1/*
2 * remote.c - remote control for the NSD daemon.
3 *
4 * Copyright (c) 2008, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file contains the remote control functionality for the daemon.
40 * The remote control can be performed using either the commandline
41 * nsd-control tool, or a TLS capable web browser.
42 * The channel is secured using TLSv1, and certificates.
43 * Both the server and the client(control tool) have their own keys.
44 */
45#include "config.h"
46
47#ifdef HAVE_SSL
48#ifdef HAVE_OPENSSL_SSL_H
49#include <openssl/ssl.h>
50#endif
51#ifdef HAVE_OPENSSL_ERR_H
52#include <openssl/err.h>
53#endif
54#ifdef HAVE_OPENSSL_RAND_H
55#include <openssl/rand.h>
56#endif
57#endif /* HAVE_SSL */
58#include <ctype.h>
59#include <unistd.h>
60#include <assert.h>
61#include <fcntl.h>
62#include <errno.h>
63#ifndef USE_MINI_EVENT
64#  ifdef HAVE_EVENT_H
65#    include <event.h>
66#  else
67#    include <event2/event.h>
68#    include "event2/event_struct.h"
69#    include "event2/event_compat.h"
70#  endif
71#else
72#  include "mini_event.h"
73#endif
74#include "remote.h"
75#include "util.h"
76#include "xfrd.h"
77#include "xfrd-catalog-zones.h"
78#include "xfrd-notify.h"
79#include "xfrd-tcp.h"
80#include "nsd.h"
81#include "options.h"
82#include "difffile.h"
83#include "ipc.h"
84
85#ifdef HAVE_SYS_TYPES_H
86#  include <sys/types.h>
87#endif
88#ifdef HAVE_SYS_STAT_H
89#  include <sys/stat.h>
90#endif
91#ifdef HAVE_NETDB_H
92#  include <netdb.h>
93#endif
94#ifdef HAVE_SYS_UN_H
95#  include <sys/un.h>
96#endif
97#ifndef AF_LOCAL
98#define AF_LOCAL AF_UNIX
99#endif
100
101/** number of seconds timeout on incoming remote control handshake */
102#define REMOTE_CONTROL_TCP_TIMEOUT 120
103
104/** repattern to master or slave */
105#define REPAT_SLAVE                   1
106#define REPAT_MASTER                  2
107#define REPAT_CATALOG_CONSUMER        4
108#define REPAT_CATALOG_CONSUMER_DEINIT 8
109
110/** if you want zero to be inhibited in stats output.
111 * it omits zeroes for types that have no acronym and unused-rcodes */
112const int inhibit_zero = 1;
113
114/**
115 * a busy control command connection, SSL state
116 * Defined here to keep the definition private, and keep SSL out of the .h
117 */
118struct rc_state {
119	/** the next item in list */
120	struct rc_state* next, *prev;
121	/* if the event was added to the event_base */
122	int event_added;
123	/** the commpoint */
124	struct event c;
125	/** timeout for this state */
126	struct timeval tval;
127	/** in the handshake part */
128	enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
129#ifdef HAVE_SSL
130	/** the ssl state */
131	SSL* ssl;
132#endif
133	/** file descriptor */
134	int fd;
135	/** the rc this is part of */
136	struct daemon_remote* rc;
137	/** stats list next item */
138	struct rc_state* stats_next;
139};
140
141/**
142 * list of events for accepting connections
143 */
144struct acceptlist {
145	struct acceptlist* next;
146	int event_added;
147	struct event c;
148	char* ident;
149	struct daemon_remote* rc;
150};
151
152/**
153 * The remote control state.
154 */
155struct daemon_remote {
156	/** the master process for this remote control */
157	struct xfrd_state* xfrd;
158	/** commpoints for accepting remote control connections */
159	struct acceptlist* accept_list;
160	/* if certificates are used */
161	int use_cert;
162	/** number of active commpoints that are handling remote control */
163	int active;
164	/** max active commpoints */
165	int max_active;
166	/** current commpoints busy; double linked, malloced */
167	struct rc_state* busy_list;
168	/** last time stats was reported */
169	struct timeval stats_time, boot_time;
170#ifdef HAVE_SSL
171	/** the SSL context for creating new SSL streams */
172	SSL_CTX* ctx;
173#endif
174};
175
176/**
177 * Connection to print to, either SSL or plain over fd
178 */
179struct remote_stream {
180#ifdef HAVE_SSL
181	/** SSL structure, nonNULL if using SSL */
182	SSL* ssl;
183#endif
184	/** file descriptor for plain transfer */
185	int fd;
186};
187typedef struct remote_stream RES;
188
189/**
190 * Print fixed line of text over ssl connection in blocking mode
191 * @param res: print to
192 * @param text: the text.
193 * @return false on connection failure.
194 */
195static int ssl_print_text(RES* res, const char* text);
196
197/**
198 * printf style printing to the ssl connection
199 * @param res: the RES connection to print to. Blocking.
200 * @param format: printf style format string.
201 * @return success or false on a network failure.
202 */
203static int ssl_printf(RES* res, const char* format, ...)
204        ATTR_FORMAT(printf, 2, 3);
205
206/**
207 * Read until \n is encountered
208 * If stream signals EOF, the string up to then is returned (without \n).
209 * @param res: the RES connection to read from. blocking.
210 * @param buf: buffer to read to.
211 * @param max: size of buffer.
212 * @return false on connection failure.
213 */
214static int ssl_read_line(RES* res, char* buf, size_t max);
215
216/** perform the accept of a new remote control connection */
217static void
218remote_accept_callback(int fd, short event, void* arg);
219
220/** perform remote control */
221static void
222remote_control_callback(int fd, short event, void* arg);
223
224#ifdef BIND8_STATS
225/* process the statistics and output them */
226static void process_stats(RES* ssl, xfrd_state_type* xfrd, int peek);
227#endif
228
229/** ---- end of private defines ---- **/
230
231#ifdef HAVE_SSL
232/** log ssl crypto err */
233static void
234log_crypto_err(const char* str)
235{
236	/* error:[error code]:[library name]:[function name]:[reason string] */
237	char buf[128];
238	unsigned long e;
239	ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
240	log_msg(LOG_ERR, "%s crypto %s", str, buf);
241	while( (e=ERR_get_error()) ) {
242		ERR_error_string_n(e, buf, sizeof(buf));
243		log_msg(LOG_ERR, "and additionally crypto %s", buf);
244	}
245}
246#endif /* HAVE_SSL */
247
248#ifdef BIND8_STATS
249/** subtract timers and the values do not overflow or become negative */
250static void
251timeval_subtract(struct timeval* d, const struct timeval* end,
252	const struct timeval* start)
253{
254#ifndef S_SPLINT_S
255	time_t end_usec = end->tv_usec;
256	d->tv_sec = end->tv_sec - start->tv_sec;
257	if(end_usec < start->tv_usec) {
258		end_usec += 1000000;
259		d->tv_sec--;
260	}
261	d->tv_usec = end_usec - start->tv_usec;
262#endif
263}
264#endif /* BIND8_STATS */
265
266#ifdef HAVE_SSL
267static int
268remote_setup_ctx(struct daemon_remote* rc, struct nsd_options* cfg)
269{
270	char* s_cert = cfg->server_cert_file;
271	char* s_key = cfg->server_key_file;
272	rc->ctx = server_tls_ctx_setup(s_key, s_cert, s_cert);
273	if(!rc->ctx) {
274		log_msg(LOG_ERR, "could not setup remote control TLS context");
275		return 0;
276	}
277	return 1;
278}
279#endif /* HAVE_SSL */
280
281struct daemon_remote*
282daemon_remote_create(struct nsd_options* cfg)
283{
284	struct daemon_remote* rc = (struct daemon_remote*)xalloc_zero(
285		sizeof(*rc));
286	rc->max_active = 10;
287	assert(cfg->control_enable);
288
289	if(options_remote_is_address(cfg)) {
290#ifdef HAVE_SSL
291		if(!remote_setup_ctx(rc, cfg)) {
292			daemon_remote_delete(rc);
293			return NULL;
294		}
295		rc->use_cert = 1;
296#else
297		log_msg(LOG_ERR, "Could not setup remote control: NSD was compiled without SSL.");
298#endif /* HAVE_SSL */
299	} else {
300		struct ip_address_option* o;
301#ifdef HAVE_SSL
302		rc->ctx = NULL;
303#endif
304		rc->use_cert = 0;
305		for(o = cfg->control_interface; o; o = o->next) {
306			if(o->address && o->address[0] != '/')
307				log_msg(LOG_WARNING, "control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", o->address);
308		}
309	}
310
311	/* and try to open the ports */
312	if(!daemon_remote_open_ports(rc, cfg)) {
313		log_msg(LOG_ERR, "could not open remote control port");
314		daemon_remote_delete(rc);
315		return NULL;
316	}
317
318	if(gettimeofday(&rc->boot_time, NULL) == -1)
319		log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno));
320	rc->stats_time = rc->boot_time;
321
322	return rc;
323}
324
325void daemon_remote_close(struct daemon_remote* rc)
326{
327	struct rc_state* p, *np;
328	struct acceptlist* h, *nh;
329	if(!rc) return;
330
331	/* close listen sockets */
332	h = rc->accept_list;
333	while(h) {
334		nh = h->next;
335		if(h->event_added)
336			event_del(&h->c);
337		close(h->c.ev_fd);
338		free(h->ident);
339		free(h);
340		h = nh;
341	}
342	rc->accept_list = NULL;
343
344	/* close busy connection sockets */
345	p = rc->busy_list;
346	while(p) {
347		np = p->next;
348		if(p->event_added)
349			event_del(&p->c);
350#ifdef HAVE_SSL
351		if(p->ssl)
352			SSL_free(p->ssl);
353#endif
354		close(p->c.ev_fd);
355		free(p);
356		p = np;
357	}
358	rc->busy_list = NULL;
359	rc->active = 0;
360}
361
362void daemon_remote_delete(struct daemon_remote* rc)
363{
364	if(!rc) return;
365	daemon_remote_close(rc);
366#ifdef HAVE_SSL
367	if(rc->ctx) {
368		SSL_CTX_free(rc->ctx);
369	}
370#endif
371	free(rc);
372}
373
374static int
375create_tcp_accept_sock(struct addrinfo* addr, int* noproto)
376{
377#if defined(SO_REUSEADDR) || (defined(INET6) && (defined(IPV6_V6ONLY) || defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)))
378	int on = 1;
379#endif
380	int s;
381	*noproto = 0;
382	if ((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
383#if defined(INET6)
384		if (addr->ai_family == AF_INET6 &&
385			errno == EAFNOSUPPORT) {
386			*noproto = 1;
387			log_msg(LOG_WARNING, "fallback to TCP4, no IPv6: not supported");
388			return -1;
389		}
390#endif /* INET6 */
391		log_msg(LOG_ERR, "can't create a socket: %s", strerror(errno));
392		return -1;
393	}
394#ifdef  SO_REUSEADDR
395	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
396		log_msg(LOG_ERR, "setsockopt(..., SO_REUSEADDR, ...) failed: %s", strerror(errno));
397	}
398#endif /* SO_REUSEADDR */
399#if defined(INET6) && defined(IPV6_V6ONLY)
400	if (addr->ai_family == AF_INET6 &&
401		setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
402	{
403		log_msg(LOG_ERR, "setsockopt(..., IPV6_V6ONLY, ...) failed: %s", strerror(errno));
404		close(s);
405		return -1;
406	}
407#endif
408	/* set it nonblocking */
409	/* (StevensUNP p463), if tcp listening socket is blocking, then
410	   it may block in accept, even if select() says readable. */
411	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
412		log_msg(LOG_ERR, "cannot fcntl tcp: %s", strerror(errno));
413	}
414	/* Bind it... */
415	if (bind(s, (struct sockaddr *)addr->ai_addr, addr->ai_addrlen) != 0) {
416		log_msg(LOG_ERR, "can't bind tcp socket: %s", strerror(errno));
417		close(s);
418		return -1;
419	}
420	/* Listen to it... */
421	if (listen(s, TCP_BACKLOG_REMOTE) == -1) {
422		log_msg(LOG_ERR, "can't listen: %s", strerror(errno));
423		close(s);
424		return -1;
425	}
426	return s;
427}
428
429/**
430 * Add and open a new control port
431 * @param rc: rc with result list.
432 * @param ip: ip str
433 * @param nr: port nr
434 * @param noproto_is_err: if lack of protocol support is an error.
435 * @return false on failure.
436 */
437static int
438add_open(struct daemon_remote* rc, struct nsd_options* cfg, const char* ip,
439	int nr, int noproto_is_err)
440{
441	struct addrinfo hints;
442	struct addrinfo* res;
443	struct acceptlist* hl;
444	int noproto = 0;
445	int fd, r;
446	char port[15];
447	snprintf(port, sizeof(port), "%d", nr);
448	port[sizeof(port)-1]=0;
449	memset(&hints, 0, sizeof(hints));
450	assert(ip);
451
452	if(ip[0] == '/') {
453		/* This looks like a local socket */
454		fd = create_local_accept_sock(ip, &noproto);
455		/*
456		 * Change socket ownership and permissions so users other
457		 * than root can access it provided they are in the same
458		 * group as the user we run as.
459		 */
460		if(fd != -1) {
461#ifdef HAVE_CHOWN
462			if(chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1) {
463				VERBOSITY(3, (LOG_INFO, "cannot chmod control socket %s: %s", ip, strerror(errno)));
464			}
465			if (cfg->username && cfg->username[0] &&
466				nsd.uid != (uid_t)-1) {
467				if(chown(ip, nsd.uid, nsd.gid) == -1)
468					VERBOSITY(2, (LOG_INFO, "cannot chown %u.%u %s: %s",
469					  (unsigned)nsd.uid, (unsigned)nsd.gid,
470					  ip, strerror(errno)));
471			}
472#else
473			(void)cfg;
474#endif
475		}
476	} else {
477		hints.ai_socktype = SOCK_STREAM;
478		hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
479		/* if we had no interface ip name, "default" is what we
480		 * would do getaddrinfo for. */
481		if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
482			log_msg(LOG_ERR, "control interface %s:%s getaddrinfo: %s %s",
483				ip, port, gai_strerror(r),
484#ifdef EAI_SYSTEM
485				r==EAI_SYSTEM?(char*)strerror(errno):""
486#else
487				""
488#endif
489				);
490			return 0;
491		}
492
493		/* open fd */
494		fd = create_tcp_accept_sock(res, &noproto);
495		freeaddrinfo(res);
496	}
497
498	if(fd == -1 && noproto) {
499		if(!noproto_is_err)
500			return 1; /* return success, but do nothing */
501		log_msg(LOG_ERR, "cannot open control interface %s %d : "
502			"protocol not supported", ip, nr);
503		return 0;
504	}
505	if(fd == -1) {
506		log_msg(LOG_ERR, "cannot open control interface %s %d", ip, nr);
507		return 0;
508	}
509
510	/* alloc */
511	hl = (struct acceptlist*)xalloc_zero(sizeof(*hl));
512	hl->rc = rc;
513	hl->ident = strdup(ip);
514	if(!hl->ident) {
515		log_msg(LOG_ERR, "malloc failure");
516		close(fd);
517		free(hl);
518		return 0;
519	}
520	hl->next = rc->accept_list;
521	rc->accept_list = hl;
522
523	hl->c.ev_fd = fd;
524	hl->event_added = 0;
525	return 1;
526}
527
528int
529daemon_remote_open_ports(struct daemon_remote* rc, struct nsd_options* cfg)
530{
531	assert(cfg->control_enable && cfg->control_port);
532	if(cfg->control_interface) {
533		ip_address_option_type* p;
534		for(p = cfg->control_interface; p; p = p->next) {
535			if(!add_open(rc, cfg, p->address, cfg->control_port, 1)) {
536				return 0;
537			}
538		}
539	} else {
540		/* defaults */
541		if(cfg->do_ip6 && !add_open(rc, cfg, "::1", cfg->control_port, 0)) {
542			return 0;
543		}
544		if(cfg->do_ip4 &&
545			!add_open(rc, cfg, "127.0.0.1", cfg->control_port, 1)) {
546			return 0;
547		}
548	}
549	return 1;
550}
551
552void
553daemon_remote_attach(struct daemon_remote* rc, struct xfrd_state* xfrd)
554{
555	int fd;
556	struct acceptlist* p;
557	if(!rc) return;
558	rc->xfrd = xfrd;
559	for(p = rc->accept_list; p; p = p->next) {
560		/* add event */
561		fd = p->c.ev_fd;
562		memset(&p->c, 0, sizeof(p->c));
563		event_set(&p->c, fd, EV_PERSIST|EV_READ, remote_accept_callback,
564			p);
565		if(event_base_set(xfrd->event_base, &p->c) != 0)
566			log_msg(LOG_ERR, "remote: cannot set event_base");
567		if(event_add(&p->c, NULL) != 0)
568			log_msg(LOG_ERR, "remote: cannot add event");
569		p->event_added = 1;
570	}
571}
572
573static void
574remote_accept_callback(int fd, short event, void* arg)
575{
576	struct acceptlist *hl = (struct acceptlist*)arg;
577	struct daemon_remote *rc = hl->rc;
578#ifdef INET6
579	struct sockaddr_storage addr;
580#else
581	struct sockaddr_in addr;
582#endif
583	socklen_t addrlen;
584	int newfd;
585	struct rc_state* n;
586
587	if (!(event & EV_READ)) {
588		return;
589	}
590
591	/* perform the accept */
592	addrlen = sizeof(addr);
593#ifndef HAVE_ACCEPT4
594	newfd = accept(fd, (struct sockaddr*)&addr, &addrlen);
595#else
596	newfd = accept4(fd, (struct sockaddr*)&addr, &addrlen, SOCK_NONBLOCK);
597#endif
598	if(newfd == -1) {
599		if (    errno != EINTR
600			&& errno != EWOULDBLOCK
601#ifdef ECONNABORTED
602			&& errno != ECONNABORTED
603#endif /* ECONNABORTED */
604#ifdef EPROTO
605			&& errno != EPROTO
606#endif /* EPROTO */
607			) {
608			log_msg(LOG_ERR, "accept failed: %s", strerror(errno));
609		}
610		return;
611	}
612
613	/* create new commpoint unless we are servicing already */
614	if(rc->active >= rc->max_active) {
615		log_msg(LOG_WARNING, "drop incoming remote control: "
616			"too many connections");
617	close_exit:
618		close(newfd);
619		return;
620	}
621
622#ifndef HAVE_ACCEPT4
623	if (fcntl(newfd, F_SETFL, O_NONBLOCK) == -1) {
624		log_msg(LOG_ERR, "fcntl failed: %s", strerror(errno));
625		goto close_exit;
626	}
627#endif
628
629	/* setup state to service the remote control command */
630	n = (struct rc_state*)calloc(1, sizeof(*n));
631	if(!n) {
632		log_msg(LOG_ERR, "out of memory");
633		goto close_exit;
634	}
635
636	n->tval.tv_sec = REMOTE_CONTROL_TCP_TIMEOUT;
637	n->tval.tv_usec = 0L;
638	n->fd = newfd;
639
640	memset(&n->c, 0, sizeof(n->c));
641	event_set(&n->c, newfd, EV_PERSIST|EV_TIMEOUT|EV_READ,
642		remote_control_callback, n);
643	if(event_base_set(xfrd->event_base, &n->c) != 0) {
644		log_msg(LOG_ERR, "remote_accept: cannot set event_base");
645		free(n);
646		goto close_exit;
647	}
648	if(event_add(&n->c, &n->tval) != 0) {
649		log_msg(LOG_ERR, "remote_accept: cannot add event");
650		free(n);
651		goto close_exit;
652	}
653	n->event_added = 1;
654
655	if(2 <= verbosity) {
656		if(hl->ident && hl->ident[0] == '/') {
657			VERBOSITY(2, (LOG_INFO, "new control connection from %s", hl->ident));
658		} else {
659			char s[128];
660			addr2str(&addr, s, sizeof(s));
661			VERBOSITY(2, (LOG_INFO, "new control connection from %s", s));
662		}
663	}
664
665#ifdef HAVE_SSL
666	if(rc->ctx) {
667		n->shake_state = rc_hs_read;
668		n->ssl = SSL_new(rc->ctx);
669		if(!n->ssl) {
670			log_crypto_err("could not SSL_new");
671			if(n->event_added)
672				event_del(&n->c);
673			free(n);
674			goto close_exit;
675		}
676		SSL_set_accept_state(n->ssl);
677		(void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
678		if(!SSL_set_fd(n->ssl, newfd)) {
679			log_crypto_err("could not SSL_set_fd");
680			if(n->event_added)
681				event_del(&n->c);
682			SSL_free(n->ssl);
683			free(n);
684			goto close_exit;
685		}
686	} else {
687		n->ssl = NULL;
688	}
689#endif /* HAVE_SSL */
690
691	n->rc = rc;
692	n->stats_next = NULL;
693	n->prev = NULL;
694	n->next = rc->busy_list;
695	if(n->next) n->next->prev = n;
696	rc->busy_list = n;
697	rc->active ++;
698
699	/* perform the first nonblocking read already, for windows,
700	 * so it can return wouldblock. could be faster too. */
701	remote_control_callback(newfd, EV_READ, n);
702}
703
704/** delete from list */
705static void
706state_list_remove_elem(struct rc_state** list, struct rc_state* todel)
707{
708	if(todel->prev) todel->prev->next = todel->next;
709	else	*list = todel->next;
710	if(todel->next) todel->next->prev = todel->prev;
711}
712
713/** decrease active count and remove commpoint from busy list */
714static void
715clean_point(struct daemon_remote* rc, struct rc_state* s)
716{
717	state_list_remove_elem(&rc->busy_list, s);
718	rc->active --;
719	if(s->event_added)
720		event_del(&s->c);
721#ifdef HAVE_SSL
722	if(s->ssl) {
723		SSL_shutdown(s->ssl);
724		SSL_free(s->ssl);
725	}
726#endif /* HAVE_SSL */
727	close(s->c.ev_fd);
728	free(s);
729}
730
731static int
732ssl_print_text(RES* res, const char* text)
733{
734	if(!res)
735		return 0;
736#ifdef HAVE_SSL
737	if(res->ssl) {
738		int r;
739		ERR_clear_error();
740		if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
741			if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
742				VERBOSITY(2, (LOG_WARNING, "in SSL_write, peer "
743					"closed connection"));
744				return 0;
745			}
746			log_crypto_err("could not SSL_write");
747			return 0;
748		}
749	} else {
750#endif /* HAVE_SSL */
751		if(write_socket(res->fd, text, strlen(text)) <= 0) {
752			log_msg(LOG_ERR, "could not write: %s",
753				strerror(errno));
754			return 0;
755		}
756#ifdef HAVE_SSL
757	}
758#endif /* HAVE_SSL */
759	return 1;
760}
761
762/** print text over the ssl connection */
763static int
764ssl_print_vmsg(RES* ssl, const char* format, va_list args)
765{
766	char msg[1024];
767	vsnprintf(msg, sizeof(msg), format, args);
768	return ssl_print_text(ssl, msg);
769}
770
771/** printf style printing to the ssl connection */
772static int
773ssl_printf(RES* ssl, const char* format, ...)
774{
775	va_list args;
776	int ret;
777	va_start(args, format);
778	ret = ssl_print_vmsg(ssl, format, args);
779	va_end(args);
780	return ret;
781}
782
783static int
784ssl_read_line(RES* res, char* buf, size_t max)
785{
786	size_t len = 0;
787	if(!res)
788		return 0;
789	while(len < max) {
790		buf[len] = 0; /* terminate for safety and please checkers */
791		/* this byte is written if we read a byte from the input */
792#ifdef HAVE_SSL
793		if(res->ssl) {
794			int r;
795			ERR_clear_error();
796			if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
797				if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
798					buf[len] = 0;
799					return 1;
800				}
801				log_crypto_err("could not SSL_read");
802				return 0;
803			}
804		} else {
805#endif /* HAVE_SSL */
806			while(1) {
807				ssize_t rr = read(res->fd, buf+len, 1);
808				if(rr <= 0) {
809					if(rr == 0) {
810						buf[len] = 0;
811						return 1;
812					}
813					if(errno == EINTR || errno == EAGAIN)
814						continue;
815					log_msg(LOG_ERR, "could not read: %s",
816						strerror(errno));
817					return 0;
818				}
819				break;
820			}
821#ifdef HAVE_SSL
822		}
823#endif /* HAVE_SSL */
824		if(buf[len] == '\n') {
825			/* return string without \n */
826			buf[len] = 0;
827			return 1;
828		}
829		len++;
830	}
831	buf[max-1] = 0;
832	log_msg(LOG_ERR, "control line too long (%d): %s", (int)max, buf);
833	return 0;
834}
835
836/** skip whitespace, return new pointer into string */
837static char*
838skipwhite(char* str)
839{
840	/* EOS \0 is not a space */
841	while( isspace((unsigned char)*str) )
842		str++;
843	return str;
844}
845
846/** send the OK to the control client */
847static void
848send_ok(RES* ssl)
849{
850	(void)ssl_printf(ssl, "ok\n");
851}
852
853/** get zone argument (if any) or NULL, false on error */
854static int
855get_zone_arg(RES* ssl, xfrd_state_type* xfrd, char* arg,
856	struct zone_options** zo)
857{
858	const dname_type* dname;
859	if(!arg[0]) {
860		/* no argument present, return NULL */
861		*zo = NULL;
862		return 1;
863	}
864	dname = dname_parse(xfrd->region, arg);
865	if(!dname) {
866		(void)ssl_printf(ssl, "error cannot parse zone name '%s'\n", arg);
867		*zo = NULL;
868		return 0;
869	}
870	*zo = zone_options_find(xfrd->nsd->options, dname);
871	region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
872	if(!*zo) {
873		(void)ssl_printf(ssl, "error zone %s not configured\n", arg);
874		return 0;
875	}
876	return 1;
877}
878
879/** do the stop command */
880static void
881do_stop(RES* ssl, xfrd_state_type* xfrd)
882{
883	xfrd->need_to_send_shutdown = 1;
884
885	if(!(xfrd->ipc_handler_flags&EV_WRITE)) {
886		ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
887	}
888
889	send_ok(ssl);
890}
891
892/** do the log_reopen command, it only needs reload_now */
893static void
894do_log_reopen(RES* ssl, xfrd_state_type* xfrd)
895{
896	xfrd_set_reload_now(xfrd);
897	send_ok(ssl);
898}
899
900/** do the reload command */
901static void
902do_reload(RES* ssl, xfrd_state_type* xfrd, char* arg)
903{
904	struct zone_options* zo;
905	if(!get_zone_arg(ssl, xfrd, arg, &zo))
906		return;
907	task_new_check_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
908		xfrd->last_task, zo?(const dname_type*)zo->node.key:NULL);
909	xfrd_set_reload_now(xfrd);
910	send_ok(ssl);
911}
912
913/** do the write command */
914static void
915do_write(RES* ssl, xfrd_state_type* xfrd, char* arg)
916{
917	struct zone_options* zo;
918	if(!get_zone_arg(ssl, xfrd, arg, &zo))
919		return;
920	task_new_write_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
921		xfrd->last_task, zo?(const dname_type*)zo->node.key:NULL);
922	xfrd_set_reload_now(xfrd);
923	send_ok(ssl);
924}
925
926/** do the notify command */
927static void
928do_notify(RES* ssl, xfrd_state_type* xfrd, char* arg)
929{
930	struct zone_options* zo;
931	if(!get_zone_arg(ssl, xfrd, arg, &zo))
932		return;
933	if(zo) {
934		struct notify_zone* n = (struct notify_zone*)rbtree_search(
935			xfrd->notify_zones, (const dname_type*)zo->node.key);
936		if(n) {
937			xfrd_notify_start(n, xfrd);
938			send_ok(ssl);
939		} else {
940			(void)ssl_printf(ssl, "error zone does not have notify\n");
941		}
942	} else {
943		struct notify_zone* n;
944		RBTREE_FOR(n, struct notify_zone*, xfrd->notify_zones) {
945			xfrd_notify_start(n, xfrd);
946		}
947		send_ok(ssl);
948	}
949}
950
951/** do the transfer command */
952static void
953do_transfer(RES* ssl, xfrd_state_type* xfrd, char* arg)
954{
955	struct zone_options* zo;
956	xfrd_zone_type* zone;
957	if(!get_zone_arg(ssl, xfrd, arg, &zo))
958		return;
959	if(zo) {
960		zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, (const
961			dname_type*)zo->node.key);
962		if(zone) {
963			xfrd_handle_notify_and_start_xfr(zone, NULL);
964			send_ok(ssl);
965		} else {
966			(void)ssl_printf(ssl, "error zone not secondary\n");
967		}
968	} else {
969		RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones) {
970			xfrd_handle_notify_and_start_xfr(zone, NULL);
971		}
972		(void)ssl_printf(ssl, "ok, %lu zones\n", (unsigned long)xfrd->zones->count);
973	}
974}
975
976/** force transfer a zone */
977static void
978force_transfer_zone(xfrd_zone_type* zone)
979{
980	/* if in TCP transaction, stop it immediately. */
981	if(zone->tcp_conn != -1)
982		xfrd_tcp_release(xfrd->tcp_set, zone);
983	else if(zone->zone_handler.ev_fd != -1)
984		xfrd_udp_release(zone);
985	/* pretend we not longer have it and force any
986	 * zone to be downloaded (even same serial, w AXFR) */
987	zone->soa_disk_acquired = 0;
988	zone->soa_nsd_acquired = 0;
989	xfrd_handle_notify_and_start_xfr(zone, NULL);
990}
991
992/** do the force transfer command */
993static void
994do_force_transfer(RES* ssl, xfrd_state_type* xfrd, char* arg)
995{
996	struct zone_options* zo;
997	xfrd_zone_type* zone;
998	if(!get_zone_arg(ssl, xfrd, arg, &zo))
999		return;
1000	if(zo) {
1001		zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, (const
1002			dname_type*)zo->node.key);
1003		if(zone) {
1004			force_transfer_zone(zone);
1005			send_ok(ssl);
1006		} else {
1007			(void)ssl_printf(ssl, "error zone not secondary\n");
1008		}
1009	} else {
1010		RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones) {
1011			force_transfer_zone(zone);
1012		}
1013		(void)ssl_printf(ssl, "ok, %lu zones\n", (unsigned long)xfrd->zones->count);
1014	}
1015}
1016
1017static int
1018print_soa_status(RES* ssl, const char* str, xfrd_soa_type* soa, time_t acq)
1019{
1020	if(acq) {
1021		if(!ssl_printf(ssl, "	%s: \"%u since %s\"\n", str,
1022			(unsigned)ntohl(soa->serial), xfrd_pretty_time(acq)))
1023			return 0;
1024	} else {
1025		if(!ssl_printf(ssl, "	%s: none\n", str))
1026			return 0;
1027	}
1028	return 1;
1029}
1030
1031/** print zonestatus for one domain */
1032static int
1033print_zonestatus(RES* ssl, xfrd_state_type* xfrd, struct zone_options* zo)
1034{
1035	xfrd_zone_type* xz = (xfrd_zone_type*)rbtree_search(xfrd->zones,
1036		(const dname_type*)zo->node.key);
1037	struct notify_zone* nz = (struct notify_zone*)rbtree_search(
1038		xfrd->notify_zones, (const dname_type*)zo->node.key);
1039	if(!ssl_printf(ssl, "zone:	%s\n", zo->name))
1040		return 0;
1041	if(!zo->part_of_config) {
1042		if(!ssl_printf(ssl, "	pattern: %s\n", zo->pattern->pname))
1043			return 0;
1044	}
1045	if(zone_is_catalog_consumer(zo)) {
1046		zone_type* zone = namedb_find_zone(xfrd->nsd->db,
1047				(const dname_type*)zo->node.key);
1048		struct xfrd_catalog_consumer_zone* consumer_zone =
1049			(struct xfrd_catalog_consumer_zone*)
1050			rbtree_search( xfrd->catalog_consumer_zones
1051			             , zo->node.key);
1052
1053		if(!ssl_printf(ssl, "	catalog: consumer"))
1054			return 0;
1055		if(zone && zone->soa_rrset && zone->soa_rrset->rrs
1056		&& zone->soa_rrset->rrs[0].rdata_count > 2
1057		&& rdata_atom_size(zone->soa_rrset->rrs[0].rdatas[2]) ==
1058							sizeof(uint32_t)) {
1059			if(!ssl_printf(ssl, " (serial: %u, # members: %zu)\n",
1060					read_uint32(rdata_atom_data(
1061					zone->soa_rrset->rrs[0].rdatas[2])),
1062					  consumer_zone
1063					? consumer_zone->member_ids.count : 0))
1064				return 0;
1065
1066		} else if(!ssl_printf(ssl, "\n"))
1067			return 0;
1068		if(invalid_catalog_consumer_zone(zo)) {
1069			if(!ssl_printf(ssl, "	catalog-invalid: %s\n",
1070					invalid_catalog_consumer_zone(zo)))
1071				return 0;
1072		}
1073	}
1074	if(zone_is_catalog_producer(zo)) {
1075		struct xfrd_catalog_producer_zone* producer_zone =
1076			(struct xfrd_catalog_producer_zone*)
1077			rbtree_search( xfrd->catalog_producer_zones
1078			             , zo->node.key);
1079		if(!ssl_printf(ssl, "	catalog: producer"))
1080			return 0;
1081		if(producer_zone) {
1082			if(!ssl_printf(ssl, " (serial: %u, # members: %zu)\n",
1083					(unsigned)producer_zone->serial,
1084				       	producer_zone->member_ids.count))
1085				return 0;
1086		} else if(!ssl_printf(ssl, "\n"))
1087			return 0;
1088		if (zone_is_slave(zo)) {
1089			if(!ssl_printf(ssl, "	catalog-invalid: a catalog "
1090					"producer cannot be a secondary zone"))
1091				return 0;
1092		}
1093	}
1094	if(zone_is_catalog_member(zo)) {
1095		if(!ssl_printf(ssl, "	catalog-member-id: %s\n",
1096		   as_catalog_member_zone(zo)->member_id
1097		 ? dname_to_string(as_catalog_member_zone(zo)->member_id, NULL)
1098		 : "ERROR member-id is missing!"))
1099			return 0;
1100	}
1101	if(nz) {
1102		if(nz->is_waiting) {
1103			if(!ssl_printf(ssl, "	notify: \"waiting-for-fd\"\n"))
1104				return 0;
1105		} else if(nz->notify_send_enable || nz->notify_send6_enable) {
1106			int i;
1107			if(!ssl_printf(ssl, "	notify: \"send"))
1108				return 0;
1109			for(i=0; i<NOTIFY_CONCURRENT_MAX; i++) {
1110				if(!nz->pkts[i].dest) continue;
1111				if(!ssl_printf(ssl, " %s",
1112					nz->pkts[i].dest->ip_address_spec))
1113					return 0;
1114			}
1115			if(!ssl_printf(ssl, " with serial %u\"\n",
1116				(unsigned)ntohl(nz->current_soa->serial)))
1117				return 0;
1118		}
1119	}
1120	if(!xz) {
1121		if(!ssl_printf(ssl, "	state: primary\n"))
1122			return 0;
1123		return 1;
1124	}
1125	if(!ssl_printf(ssl, "	state: %s\n",
1126		(xz->state == xfrd_zone_ok)?"ok":(
1127		(xz->state == xfrd_zone_expired)?"expired":"refreshing")))
1128		return 0;
1129	if(!print_soa_status(ssl, "served-serial", &xz->soa_nsd,
1130		xz->soa_nsd_acquired))
1131		return 0;
1132	if(!print_soa_status(ssl, "commit-serial", &xz->soa_disk,
1133		xz->soa_disk_acquired))
1134		return 0;
1135	if(xz->round_num != -1) {
1136		if(!print_soa_status(ssl, "notified-serial", &xz->soa_notified,
1137			xz->soa_notified_acquired))
1138			return 0;
1139	} else if(xz->event_added) {
1140		if(!ssl_printf(ssl, "\twait: \"%lu sec between attempts\"\n",
1141			(unsigned long)xz->timeout.tv_sec))
1142			return 0;
1143	}
1144
1145	/* UDP */
1146	if(xz->udp_waiting) {
1147		if(!ssl_printf(ssl, "	transfer: \"waiting-for-UDP-fd\"\n"))
1148			return 0;
1149	} else if(xz->zone_handler.ev_fd != -1 && xz->tcp_conn == -1) {
1150		if(!ssl_printf(ssl, "	transfer: \"sent UDP to %s\"\n",
1151			xz->master->ip_address_spec))
1152			return 0;
1153	}
1154
1155	/* TCP */
1156	if(xz->tcp_waiting) {
1157		if(!ssl_printf(ssl, "	transfer: \"waiting-for-TCP-fd\"\n"))
1158			return 0;
1159	} else if(xz->tcp_conn != -1) {
1160		if(!ssl_printf(ssl, "	transfer: \"TCP connected to %s\"\n",
1161			xz->master->ip_address_spec))
1162			return 0;
1163	}
1164
1165	return 1;
1166}
1167
1168/** do the zonestatus command */
1169static void
1170do_zonestatus(RES* ssl, xfrd_state_type* xfrd, char* arg)
1171{
1172	struct zone_options* zo;
1173	if(!get_zone_arg(ssl, xfrd, arg, &zo))
1174		return;
1175	if(zo) (void)print_zonestatus(ssl, xfrd, zo);
1176	else {
1177		RBTREE_FOR(zo, struct zone_options*,
1178			xfrd->nsd->options->zone_options) {
1179			if(!print_zonestatus(ssl, xfrd, zo))
1180				return;
1181		}
1182	}
1183}
1184
1185/** do the verbosity command */
1186static void
1187do_verbosity(RES* ssl, char* str)
1188{
1189	int val = atoi(str);
1190	if(strcmp(str, "") == 0) {
1191		(void)ssl_printf(ssl, "verbosity %d\n", verbosity);
1192		return;
1193	}
1194	if(val == 0 && strcmp(str, "0") != 0) {
1195		(void)ssl_printf(ssl, "error in verbosity number syntax: %s\n", str);
1196		return;
1197	}
1198	verbosity = val;
1199	task_new_set_verbosity(xfrd->nsd->task[xfrd->nsd->mytask],
1200		xfrd->last_task, val);
1201	xfrd_set_reload_now(xfrd);
1202	send_ok(ssl);
1203}
1204
1205/** find second argument, modifies string */
1206static int
1207find_arg2(RES* ssl, char* arg, char** arg2)
1208{
1209	char* as = strrchr(arg, ' ');
1210	if(as) {
1211		as[0]=0;
1212		*arg2 = as+1;
1213		while(isspace((unsigned char)*as) && as > arg)
1214			as--;
1215		as[0]=0;
1216		return 1;
1217	}
1218	*arg2 = NULL;
1219	(void)ssl_printf(ssl, "error could not find next argument "
1220		"after %s\n", arg);
1221	return 0;
1222}
1223
1224/** find second and third arguments, modifies string,
1225 * does not print error for missing arg3 so that if it does not find an
1226 * arg3, the caller can use two arguments. */
1227static int
1228find_arg3(RES* ssl, char* arg, char** arg2, char** arg3)
1229{
1230	if(find_arg2(ssl, arg, arg2)) {
1231		char* as;
1232		*arg3 = *arg2;
1233		as = strrchr(arg, ' ');
1234		if(as) {
1235			as[0]=0;
1236			*arg2 = as+1;
1237			while(isspace((unsigned char)*as) && as > arg)
1238				as--;
1239			as[0]=0;
1240			return 1;
1241		}
1242	}
1243	*arg3 = NULL;
1244	return 0;
1245}
1246
1247/** do the status command */
1248static void
1249do_status(RES* ssl, xfrd_state_type* xfrd)
1250{
1251	if(!ssl_printf(ssl, "version: %s\n", PACKAGE_VERSION))
1252		return;
1253	if(!ssl_printf(ssl, "verbosity: %d\n", verbosity))
1254		return;
1255#ifdef RATELIMIT
1256	if(!ssl_printf(ssl, "ratelimit: %d\n",
1257		(int)xfrd->nsd->options->rrl_ratelimit))
1258		return;
1259#else
1260	(void)xfrd;
1261#endif
1262}
1263
1264/** do the stats command */
1265static void
1266do_stats(RES* ssl, xfrd_state_type* xfrd, int peek)
1267{
1268#ifdef BIND8_STATS
1269	process_stats(ssl, xfrd, peek);
1270#else
1271	(void)xfrd; (void)peek;
1272	(void)ssl_printf(ssl, "error no stats enabled at compile time\n");
1273#endif /* BIND8_STATS */
1274}
1275
1276/** see if we have more zonestatistics entries and it has to be incremented */
1277static void
1278zonestat_inc_ifneeded(xfrd_state_type* xfrd)
1279{
1280#ifdef USE_ZONE_STATS
1281	if(xfrd->nsd->options->zonestatnames->count != xfrd->zonestat_safe)
1282		task_new_zonestat_inc(xfrd->nsd->task[xfrd->nsd->mytask],
1283			xfrd->last_task,
1284			xfrd->nsd->options->zonestatnames->count);
1285#else
1286	(void)xfrd;
1287#endif /* USE_ZONE_STATS */
1288}
1289
1290/** perform the changezone command for one zone */
1291static int
1292perform_changezone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1293{
1294	const dname_type* dname;
1295	struct zone_options* zopt;
1296	char* arg2 = NULL;
1297	if(!find_arg2(ssl, arg, &arg2))
1298		return 0;
1299
1300	/* if we add it to the xfrd now, then xfrd could download AXFR and
1301	 * store it and the NSD-reload would see it in the difffile before
1302	 * it sees the add-config task.
1303	 */
1304	/* thus: AXFRs and IXFRs must store the pattern name in the
1305	 * difffile, so that it can be added when the AXFR or IXFR is seen.
1306	 */
1307
1308	/* check that the pattern exists */
1309	if(!rbtree_search(xfrd->nsd->options->patterns, arg2)) {
1310		(void)ssl_printf(ssl, "error pattern %s does not exist\n",
1311			arg2);
1312		return 0;
1313	}
1314
1315	dname = dname_parse(xfrd->region, arg);
1316	if(!dname) {
1317		(void)ssl_printf(ssl, "error cannot parse zone name\n");
1318		return 0;
1319	}
1320
1321	/* see if zone is a duplicate */
1322	if( (zopt=zone_options_find(xfrd->nsd->options, dname)) ) {
1323		if(zopt->part_of_config) {
1324			(void)ssl_printf(ssl, "error zone defined in nsd.conf, "
1325			  "cannot delete it in this manner: remove it from "
1326			  "nsd.conf yourself and repattern\n");
1327			region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1328			dname = NULL;
1329			return 0;
1330		}
1331		if(zone_is_catalog_consumer_member(zopt)) {
1332			(void)ssl_printf(ssl, "Error: Zone is a catalog "
1333			  "consumer member zone with id %s\nRepattern in the "
1334			  "catalog with a group property.\n", dname_to_string(
1335			  as_catalog_member_zone(zopt)->member_id, NULL));
1336			region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1337			dname = NULL;
1338			return 0;
1339		}
1340		/* found the zone, now delete it */
1341		/* create deletion task */
1342		/* this deletion task is processed before the addition task,
1343		 * that is created below, in the same reload process, causing
1344		 * a seamless change from one to the other, with no downtime
1345		 * for the zone. */
1346		task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1347			xfrd->last_task, dname);
1348		xfrd_set_reload_now(xfrd);
1349		/* delete it in xfrd */
1350		if(zone_is_slave(zopt)) {
1351			xfrd_del_slave_zone(xfrd, dname);
1352		}
1353		xfrd_del_notify(xfrd, dname);
1354		/* delete it in xfrd's catalog consumers list */
1355		if(zone_is_catalog_consumer(zopt)) {
1356			xfrd_deinit_catalog_consumer_zone(xfrd, dname);
1357		}
1358		/* delete from config */
1359		zone_list_del(xfrd->nsd->options, zopt);
1360	} else {
1361		(void)ssl_printf(ssl, "zone %s did not exist, creating", arg);
1362	}
1363	region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1364	dname = NULL;
1365
1366	/* add to zonelist and adds to config in memory */
1367	zopt = zone_list_add_or_cat(xfrd->nsd->options, arg, arg2,
1368			xfrd_add_catalog_producer_member);
1369	if(!zopt) {
1370		/* also dname parse error here */
1371		(void)ssl_printf(ssl, "error could not add zonelist entry\n");
1372		return 0;
1373	}
1374	/* make addzone task and schedule reload */
1375	task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1376		xfrd->last_task, arg, arg2,
1377		getzonestatid(xfrd->nsd->options, zopt));
1378	zonestat_inc_ifneeded(xfrd);
1379	xfrd_set_reload_now(xfrd);
1380	/* add to xfrd - catalog consumer zones */
1381	if (zone_is_catalog_consumer(zopt)) {
1382		xfrd_init_catalog_consumer_zone(xfrd, zopt);
1383	}
1384	/* add to xfrd - notify (for master and slaves) */
1385	init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1386	/* add to xfrd - slave */
1387	if(zone_is_slave(zopt)) {
1388		xfrd_init_slave_zone(xfrd, zopt);
1389	}
1390	return 1;
1391}
1392
1393/** perform the addzone command for one zone */
1394static int
1395perform_addzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1396{
1397	const dname_type* dname;
1398	struct zone_options* zopt;
1399	char* arg2 = NULL;
1400	if(!find_arg2(ssl, arg, &arg2))
1401		return 0;
1402
1403	/* if we add it to the xfrd now, then xfrd could download AXFR and
1404	 * store it and the NSD-reload would see it in the difffile before
1405	 * it sees the add-config task.
1406	 */
1407	/* thus: AXFRs and IXFRs must store the pattern name in the
1408	 * difffile, so that it can be added when the AXFR or IXFR is seen.
1409	 */
1410
1411	/* check that the pattern exists */
1412	if(!rbtree_search(xfrd->nsd->options->patterns, arg2)) {
1413		(void)ssl_printf(ssl, "error pattern %s does not exist\n",
1414			arg2);
1415		return 0;
1416	}
1417
1418	dname = dname_parse(xfrd->region, arg);
1419	if(!dname) {
1420		(void)ssl_printf(ssl, "error cannot parse zone name\n");
1421		return 0;
1422	}
1423
1424	/* see if zone is a duplicate */
1425	if( zone_options_find(xfrd->nsd->options, dname) ) {
1426		region_recycle(xfrd->region, (void*)dname,
1427			dname_total_size(dname));
1428		(void)ssl_printf(ssl, "zone %s already exists\n", arg);
1429		return 1;
1430	}
1431	region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1432	dname = NULL;
1433
1434	/* add to zonelist and adds to config in memory */
1435	zopt = zone_list_add_or_cat(xfrd->nsd->options, arg, arg2,
1436			xfrd_add_catalog_producer_member);
1437	if(!zopt) {
1438		/* also dname parse error here */
1439		(void)ssl_printf(ssl, "error could not add zonelist entry\n");
1440		return 0;
1441	}
1442	/* make addzone task and schedule reload */
1443	task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1444		xfrd->last_task, arg, arg2,
1445		getzonestatid(xfrd->nsd->options, zopt));
1446	zonestat_inc_ifneeded(xfrd);
1447	xfrd_set_reload_now(xfrd);
1448	/* add to xfrd - catalog consumer zones */
1449	if (zone_is_catalog_consumer(zopt)) {
1450		xfrd_init_catalog_consumer_zone(xfrd, zopt);
1451	}
1452	/* add to xfrd - notify (for master and slaves) */
1453	init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1454	/* add to xfrd - slave */
1455	if(zone_is_slave(zopt)) {
1456		xfrd_init_slave_zone(xfrd, zopt);
1457	}
1458	return 1;
1459}
1460
1461/** perform the delzone command for one zone */
1462static int
1463perform_delzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1464{
1465	const dname_type* dname;
1466	struct zone_options* zopt;
1467	/* dont recycle dname when it becomes part of a xfrd_producer_member */
1468	int recycle_dname = 1;
1469
1470	dname = dname_parse(xfrd->region, arg);
1471	if(!dname) {
1472		(void)ssl_printf(ssl, "error cannot parse zone name\n");
1473		return 0;
1474	}
1475
1476	/* see if we have the zone in question */
1477	zopt = zone_options_find(xfrd->nsd->options, dname);
1478	if(!zopt) {
1479		region_recycle(xfrd->region, (void*)dname,
1480			dname_total_size(dname));
1481		/* nothing to do */
1482		(void)ssl_printf(ssl, "warning zone %s not present\n", arg);
1483		return 0;
1484	}
1485
1486	/* see if it can be deleted */
1487	if(zopt->part_of_config) {
1488		region_recycle(xfrd->region, (void*)dname,
1489			dname_total_size(dname));
1490		(void)ssl_printf(ssl, "error zone defined in nsd.conf, "
1491			"cannot delete it in this manner: remove it from "
1492			"nsd.conf yourself and repattern\n");
1493		return 0;
1494	}
1495	if(zone_is_catalog_consumer_member(zopt)
1496	&& as_catalog_member_zone(zopt)->member_id) {
1497		(void)ssl_printf(ssl, "Error: Zone is a catalog consumer "
1498		  "member zone with id %s\nRemove the member id from the "
1499		  "catalog to delete this zone.\n", dname_to_string(
1500		  as_catalog_member_zone(zopt)->member_id, NULL));
1501		region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1502		dname = NULL;
1503		return 0;
1504
1505	}
1506	/* create deletion task */
1507	task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1508		xfrd->last_task, dname);
1509	xfrd_set_reload_now(xfrd);
1510	/* delete it in xfrd */
1511	if(zone_is_slave(zopt)) {
1512		xfrd_del_slave_zone(xfrd, dname);
1513	}
1514	xfrd_del_notify(xfrd, dname);
1515	/* delete it in xfrd's catalog consumers list */
1516	if(zone_is_catalog_consumer(zopt)) {
1517		xfrd_deinit_catalog_consumer_zone(xfrd, dname);
1518	} else {
1519		recycle_dname = !xfrd_del_catalog_producer_member(xfrd, dname);
1520	}
1521	/* delete from config */
1522	zone_list_del(xfrd->nsd->options, zopt);
1523
1524	if(recycle_dname)
1525		region_recycle(xfrd->region,
1526				(void*)dname, dname_total_size(dname));
1527	return 1;
1528}
1529
1530/** do the addzone command */
1531static void
1532do_addzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1533{
1534	if(!perform_addzone(ssl, xfrd, arg))
1535		return;
1536	send_ok(ssl);
1537}
1538
1539/** do the delzone command */
1540static void
1541do_delzone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1542{
1543	if(!perform_delzone(ssl, xfrd, arg))
1544		return;
1545	send_ok(ssl);
1546}
1547
1548/** do the changezone command */
1549static void
1550do_changezone(RES* ssl, xfrd_state_type* xfrd, char* arg)
1551{
1552	if(!perform_changezone(ssl, xfrd, arg))
1553		return;
1554	send_ok(ssl);
1555}
1556
1557/** do the addzones command */
1558static void
1559do_addzones(RES* ssl, xfrd_state_type* xfrd)
1560{
1561	char buf[2048];
1562	int num = 0;
1563	while(ssl_read_line(ssl, buf, sizeof(buf))) {
1564		if(buf[0] == 0x04 && buf[1] == 0)
1565			break; /* end of transmission */
1566		if(!perform_addzone(ssl, xfrd, buf)) {
1567			if(!ssl_printf(ssl, "error for input line '%s'\n",
1568				buf))
1569				return;
1570		} else {
1571			if(!ssl_printf(ssl, "added: %s\n", buf))
1572				return;
1573			num++;
1574		}
1575	}
1576	(void)ssl_printf(ssl, "added %d zones\n", num);
1577}
1578
1579/** do the delzones command */
1580static void
1581do_delzones(RES* ssl, xfrd_state_type* xfrd)
1582{
1583	char buf[2048];
1584	int num = 0;
1585	while(ssl_read_line(ssl, buf, sizeof(buf))) {
1586		if(buf[0] == 0x04 && buf[1] == 0)
1587			break; /* end of transmission */
1588		if(!perform_delzone(ssl, xfrd, buf)) {
1589			if(!ssl_printf(ssl, "error for input line '%s'\n",
1590				buf))
1591				return;
1592		} else {
1593			if(!ssl_printf(ssl, "removed: %s\n", buf))
1594				return;
1595			num++;
1596		}
1597	}
1598	(void)ssl_printf(ssl, "deleted %d zones\n", num);
1599}
1600
1601
1602/** remove TSIG key from config and add task so that reload does too */
1603static void remove_key(xfrd_state_type* xfrd, const char* kname)
1604{
1605	/* add task before deletion because the name string could be deleted */
1606	task_new_del_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
1607		kname);
1608	key_options_remove(xfrd->nsd->options, kname);
1609	xfrd_set_reload_now(xfrd); /* this is executed when the current control
1610		command ends, thus the entire config changes are bunched up */
1611}
1612
1613/** add TSIG key to config and add task so that reload does too */
1614static void add_key(xfrd_state_type* xfrd, struct key_options* k)
1615{
1616	key_options_add_modify(xfrd->nsd->options, k);
1617	task_new_add_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
1618		k);
1619	xfrd_set_reload_now(xfrd);
1620}
1621
1622/** check if keys have changed */
1623static void repat_keys(xfrd_state_type* xfrd, struct nsd_options* newopt)
1624{
1625	struct nsd_options* oldopt = xfrd->nsd->options;
1626	struct key_options* k;
1627	/* find deleted keys */
1628	k = (struct key_options*)rbtree_first(oldopt->keys);
1629	while((rbnode_type*)k != RBTREE_NULL) {
1630		struct key_options* next = (struct key_options*)rbtree_next(
1631			(rbnode_type*)k);
1632		if(!key_options_find(newopt, k->name))
1633			remove_key(xfrd, k->name);
1634		k = next;
1635	}
1636	/* find added or changed keys */
1637	RBTREE_FOR(k, struct key_options*, newopt->keys) {
1638		struct key_options* origk = key_options_find(oldopt, k->name);
1639		if(!origk)
1640			add_key(xfrd, k);
1641		else if(!key_options_equal(k, origk))
1642			add_key(xfrd, k);
1643	}
1644}
1645
1646/** find zone given the implicit pattern */
1647static const dname_type*
1648parse_implicit_name(xfrd_state_type* xfrd,const char* pname)
1649{
1650	if(strncmp(pname, PATTERN_IMPLICIT_MARKER,
1651		strlen(PATTERN_IMPLICIT_MARKER)) != 0)
1652		return NULL;
1653	return dname_parse(xfrd->region, pname +
1654		strlen(PATTERN_IMPLICIT_MARKER));
1655}
1656
1657/** remove cfgzone and add task so that reload does too */
1658static void
1659remove_cfgzone(xfrd_state_type* xfrd, const char* pname)
1660{
1661	/* dname and find the zone for the implicit pattern */
1662	struct zone_options* zopt = NULL;
1663	const dname_type* dname = parse_implicit_name(xfrd, pname);
1664	if(!dname) {
1665		/* should have a parseable name, but it did not */
1666		return;
1667	}
1668
1669	/* find the zone entry for the implicit pattern */
1670	zopt = zone_options_find(xfrd->nsd->options, dname);
1671	if(!zopt) {
1672		/* this should not happen; implicit pattern has zone entry */
1673		region_recycle(xfrd->region, (void*)dname,
1674			dname_total_size(dname));
1675		return;
1676	}
1677
1678	/* create deletion task */
1679	task_new_del_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1680		xfrd->last_task, dname);
1681	xfrd_set_reload_now(xfrd);
1682	/* delete it in xfrd */
1683	if(zone_is_slave(zopt)) {
1684		xfrd_del_slave_zone(xfrd, dname);
1685	}
1686	xfrd_del_notify(xfrd, dname);
1687	/* delete it in xfrd's catalog consumers list */
1688	if(zone_is_catalog_consumer(zopt)) {
1689		xfrd_deinit_catalog_consumer_zone(xfrd, dname);
1690	}
1691
1692	/* delete from zoneoptions */
1693	zone_options_delete(xfrd->nsd->options, zopt);
1694
1695	/* recycle parsed dname */
1696	region_recycle(xfrd->region, (void*)dname, dname_total_size(dname));
1697}
1698
1699/** add cfgzone and add task so that reload does too */
1700static void
1701add_cfgzone(xfrd_state_type* xfrd, const char* pname)
1702{
1703	/* add to our zonelist */
1704	struct zone_options* zopt = zone_options_create(
1705		xfrd->nsd->options->region);
1706	if(!zopt)
1707		return;
1708	zopt->part_of_config = 1;
1709	zopt->name = region_strdup(xfrd->nsd->options->region,
1710		pname + strlen(PATTERN_IMPLICIT_MARKER));
1711	zopt->pattern = pattern_options_find(xfrd->nsd->options, pname);
1712	if(!zopt->name || !zopt->pattern)
1713		return;
1714	if(!nsd_options_insert_zone(xfrd->nsd->options, zopt)) {
1715		log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' "
1716			"pattern %s", zopt->name, pname);
1717	}
1718
1719	/* make addzone task and schedule reload */
1720	task_new_add_zone(xfrd->nsd->task[xfrd->nsd->mytask],
1721		xfrd->last_task, zopt->name, pname,
1722		getzonestatid(xfrd->nsd->options, zopt));
1723	/* zonestat_inc is done after the entire config file has been done */
1724	xfrd_set_reload_now(xfrd);
1725	/* add to xfrd - catalog consumer zones */
1726	if (zone_is_catalog_consumer(zopt)) {
1727		xfrd_init_catalog_consumer_zone(xfrd, zopt);
1728	}
1729	/* add to xfrd - notify (for master and slaves) */
1730	init_notify_send(xfrd->notify_zones, xfrd->region, zopt);
1731	/* add to xfrd - slave */
1732	if(zone_is_slave(zopt)) {
1733		xfrd_init_slave_zone(xfrd, zopt);
1734	}
1735}
1736
1737/** remove pattern and add task so that reload does too */
1738static void
1739remove_pat(xfrd_state_type* xfrd, const char* name)
1740{
1741	/* add task before deletion, because name-string could be deleted */
1742	task_new_del_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
1743		xfrd->last_task, name);
1744	pattern_options_remove(xfrd->nsd->options, name);
1745	xfrd_set_reload_now(xfrd);
1746}
1747
1748/** add pattern and add task so that reload does too */
1749static void
1750add_pat(xfrd_state_type* xfrd, struct pattern_options* p)
1751{
1752	pattern_options_add_modify(xfrd->nsd->options, p);
1753	task_new_add_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
1754		xfrd->last_task, p);
1755	xfrd_set_reload_now(xfrd);
1756}
1757
1758/** interrupt zones that are using changed or removed patterns */
1759static void
1760repat_interrupt_zones(xfrd_state_type* xfrd, struct nsd_options* newopt)
1761{
1762	/* if masterlist changed:
1763	 *   interrupt slave zone (UDP or TCP) transfers.
1764	 *   slave zones reset master to start of list.
1765	 */
1766	xfrd_zone_type* xz;
1767	struct notify_zone* nz;
1768	RBTREE_FOR(xz, xfrd_zone_type*, xfrd->zones) {
1769		struct pattern_options* oldp = xz->zone_options->pattern;
1770		struct pattern_options* newp = pattern_options_find(newopt,
1771			oldp->pname);
1772		if(!newp || !acl_list_equal(oldp->request_xfr,
1773			newp->request_xfr)) {
1774			/* interrupt transfer */
1775			if(xz->tcp_conn != -1) {
1776				xfrd_tcp_release(xfrd->tcp_set, xz);
1777				xfrd_set_refresh_now(xz);
1778			} else if(xz->zone_handler.ev_fd != -1) {
1779				xfrd_udp_release(xz);
1780				xfrd_set_refresh_now(xz);
1781			}
1782			xz->master = 0;
1783			xz->master_num = 0;
1784			xz->next_master = -1;
1785			xz->round_num = -1; /* fresh set of retries */
1786		}
1787	}
1788	/* if notify list changed:
1789	 *   interrupt notify that is busy.
1790	 *   reset notify to start of list.  (clear all other reset_notify)
1791	 */
1792	RBTREE_FOR(nz, struct notify_zone*, xfrd->notify_zones) {
1793		struct pattern_options* oldp = nz->options->pattern;
1794		struct pattern_options* newp = pattern_options_find(newopt,
1795			oldp->pname);
1796		if(!newp || !acl_list_equal(oldp->notify, newp->notify)) {
1797			/* interrupt notify */
1798			if(nz->notify_send_enable) {
1799				notify_disable(nz);
1800				/* set to restart the notify after the
1801				 * pattern has been changed. */
1802				nz->notify_restart = 2;
1803			} else {
1804				nz->notify_restart = 1;
1805			}
1806		} else {
1807			nz->notify_restart = 0;
1808		}
1809	}
1810}
1811
1812/** for notify, after the pattern changes, restart the affected notifies */
1813static void
1814repat_interrupt_notify_start(xfrd_state_type* xfrd)
1815{
1816	struct notify_zone* nz;
1817	RBTREE_FOR(nz, struct notify_zone*, xfrd->notify_zones) {
1818		if(nz->notify_restart) {
1819			if(nz->notify_current)
1820				nz->notify_current = nz->options->pattern->notify;
1821			if(nz->notify_restart == 2) {
1822				if(nz->notify_restart)
1823					xfrd_notify_start(nz, xfrd);
1824			}
1825		}
1826	}
1827}
1828
1829/** check if patterns have changed */
1830static void
1831repat_patterns(xfrd_state_type* xfrd, struct nsd_options* newopt)
1832{
1833	/* zones that use changed patterns must have:
1834	 * - their AXFR/IXFR interrupted: try again, acl may have changed.
1835	 *   if the old master/key still exists, OK, fix master-numptrs and
1836	 *   keep going.  Otherwise, stop xfer and reset TSIG.
1837	 * - send NOTIFY reset to start of NOTIFY list (and TSIG reset).
1838	 */
1839	struct nsd_options* oldopt = xfrd->nsd->options;
1840	struct pattern_options* p;
1841	int search_zones = 0;
1842
1843	repat_interrupt_zones(xfrd, newopt);
1844	/* find deleted patterns */
1845	p = (struct pattern_options*)rbtree_first(oldopt->patterns);
1846	while((rbnode_type*)p != RBTREE_NULL) {
1847		struct pattern_options* next = (struct pattern_options*)
1848			rbtree_next((rbnode_type*)p);
1849		if(!pattern_options_find(newopt, p->pname)) {
1850			if(p->implicit) {
1851				/* first remove its zone */
1852				VERBOSITY(1, (LOG_INFO, "zone removed from config: %s", p->pname + strlen(PATTERN_IMPLICIT_MARKER)));
1853				remove_cfgzone(xfrd, p->pname);
1854			}
1855			remove_pat(xfrd, p->pname);
1856		}
1857		p = next;
1858	}
1859	/* find added or changed patterns */
1860	RBTREE_FOR(p, struct pattern_options*, newopt->patterns) {
1861		struct pattern_options* origp = pattern_options_find(oldopt,
1862			p->pname);
1863		if(!origp) {
1864			/* no zones can use it, no zone_interrupt needed */
1865			add_pat(xfrd, p);
1866			if(p->implicit) {
1867				VERBOSITY(1, (LOG_INFO, "zone added to config: %s", p->pname + strlen(PATTERN_IMPLICIT_MARKER)));
1868				add_cfgzone(xfrd, p->pname);
1869			}
1870		} else if(!pattern_options_equal(p, origp)) {
1871			uint8_t newstate = 0;
1872			if (p->request_xfr && !origp->request_xfr) {
1873				newstate = REPAT_SLAVE;
1874			} else if (!p->request_xfr && origp->request_xfr) {
1875				newstate = REPAT_MASTER;
1876			}
1877			if (   p->catalog_role == CATALOG_ROLE_CONSUMER
1878			&& origp->catalog_role != CATALOG_ROLE_CONSUMER) {
1879				newstate |= REPAT_CATALOG_CONSUMER;
1880			} else if (p->catalog_role != CATALOG_ROLE_CONSUMER
1881			    && origp->catalog_role == CATALOG_ROLE_CONSUMER) {
1882				newstate |= REPAT_CATALOG_CONSUMER_DEINIT;
1883			}
1884			add_pat(xfrd, p);
1885			if (p->implicit && newstate) {
1886				const dname_type* dname =
1887					parse_implicit_name(xfrd, p->pname);
1888				if (dname) {
1889					if (newstate & REPAT_SLAVE) {
1890						struct zone_options* zopt =
1891							zone_options_find(
1892							oldopt, dname);
1893						if (zopt) {
1894							xfrd_init_slave_zone(
1895								xfrd, zopt);
1896						}
1897					} else if (newstate & REPAT_MASTER) {
1898						xfrd_del_slave_zone(xfrd,
1899							dname);
1900					}
1901					if (newstate & REPAT_CATALOG_CONSUMER) {
1902						struct zone_options* zopt =
1903							zone_options_find(
1904							oldopt, dname);
1905						if (zopt) {
1906							xfrd_init_catalog_consumer_zone(
1907								xfrd, zopt);
1908						}
1909					} else if (newstate & REPAT_CATALOG_CONSUMER_DEINIT) {
1910						xfrd_deinit_catalog_consumer_zone(
1911								xfrd, dname);
1912					}
1913					region_recycle(xfrd->region,
1914						(void*)dname,
1915						dname_total_size(dname));
1916				}
1917			} else if(!p->implicit && newstate) {
1918				/* search all zones with this pattern */
1919				search_zones = 1;
1920				origp->xfrd_flags = newstate;
1921			}
1922		}
1923	}
1924	if (search_zones) {
1925		struct zone_options* zone_opt;
1926		/* search in oldopt because 1) it contains zonelist zones,
1927		 * and 2) you need oldopt(existing) to call xfrd_init */
1928		RBTREE_FOR(zone_opt, struct zone_options*, oldopt->zone_options) {
1929			struct pattern_options* oldp = zone_opt->pattern;
1930			if (!oldp->implicit) {
1931				if (oldp->xfrd_flags & REPAT_SLAVE) {
1932					/* xfrd needs stable reference so get
1933					 * it from the oldopt(modified) tree */
1934					xfrd_init_slave_zone(xfrd, zone_opt);
1935				} else if (oldp->xfrd_flags & REPAT_MASTER) {
1936					xfrd_del_slave_zone(xfrd,
1937						(const dname_type*)
1938						zone_opt->node.key);
1939				}
1940				if (oldp->xfrd_flags & REPAT_CATALOG_CONSUMER) {
1941					xfrd_init_catalog_consumer_zone(xfrd,
1942							zone_opt);
1943				} else if (oldp->xfrd_flags & REPAT_CATALOG_CONSUMER_DEINIT) {
1944					xfrd_deinit_catalog_consumer_zone(xfrd,
1945						(const dname_type*)
1946						zone_opt->node.key);
1947				}
1948				oldp->xfrd_flags = 0;
1949			}
1950		}
1951	}
1952	repat_interrupt_notify_start(xfrd);
1953}
1954
1955/** true if options are different that can be set via repat. */
1956static int
1957repat_options_changed(xfrd_state_type* xfrd, struct nsd_options* newopt)
1958{
1959#ifdef RATELIMIT
1960	if(xfrd->nsd->options->rrl_ratelimit != newopt->rrl_ratelimit)
1961		return 1;
1962	if(xfrd->nsd->options->rrl_whitelist_ratelimit != newopt->rrl_whitelist_ratelimit)
1963		return 1;
1964	if(xfrd->nsd->options->rrl_slip != newopt->rrl_slip)
1965		return 1;
1966#else
1967	(void)xfrd; (void)newopt;
1968#endif
1969	return 0;
1970}
1971
1972/** check if global options have changed */
1973static void
1974repat_options(xfrd_state_type* xfrd, struct nsd_options* newopt)
1975{
1976	if(repat_options_changed(xfrd, newopt)) {
1977		/* update our options */
1978#ifdef RATELIMIT
1979		xfrd->nsd->options->rrl_ratelimit = newopt->rrl_ratelimit;
1980		xfrd->nsd->options->rrl_whitelist_ratelimit = newopt->rrl_whitelist_ratelimit;
1981		xfrd->nsd->options->rrl_slip = newopt->rrl_slip;
1982#endif
1983		task_new_opt_change(xfrd->nsd->task[xfrd->nsd->mytask],
1984			xfrd->last_task, newopt);
1985		xfrd_set_reload_now(xfrd);
1986	}
1987}
1988
1989/** print errors over ssl, gets pointer-to-pointer to ssl, so it can set
1990 * the pointer to NULL on failure and stop printing */
1991static void
1992print_ssl_cfg_err(void* arg, const char* str)
1993{
1994	RES** ssl = (RES**)arg;
1995	if(!*ssl) return;
1996	if(!ssl_printf(*ssl, "%s", str))
1997		*ssl = NULL; /* failed, stop printing */
1998}
1999
2000/** do the repattern command: reread config file and apply keys, patterns */
2001static void
2002do_repattern(RES* ssl, xfrd_state_type* xfrd)
2003{
2004	region_type* region = region_create(xalloc, free);
2005	struct nsd_options* opt;
2006	const char* cfgfile = xfrd->nsd->options->configfile;
2007
2008	/* check chroot and configfile, if possible to reread */
2009	if(xfrd->nsd->chrootdir) {
2010		size_t l = strlen(xfrd->nsd->chrootdir);
2011		while(l>0 && xfrd->nsd->chrootdir[l-1] == '/')
2012			--l;
2013		if(strncmp(xfrd->nsd->chrootdir, cfgfile, l) != 0) {
2014			(void)ssl_printf(ssl, "error %s is not relative to %s: "
2015				"chroot prevents reread of config\n",
2016				cfgfile, xfrd->nsd->chrootdir);
2017			region_destroy(region);
2018			return;
2019		}
2020		cfgfile += l;
2021	}
2022
2023	(void)ssl_printf(ssl, "reconfig start, read %s\n", cfgfile);
2024	opt = nsd_options_create(region);
2025	if(!parse_options_file(opt, cfgfile, &print_ssl_cfg_err, &ssl,
2026				xfrd->nsd->options)) {
2027		/* error already printed */
2028		region_destroy(region);
2029		return;
2030	}
2031	/* check for differences in TSIG keys and patterns, and apply,
2032	 * first the keys, so that pattern->keyptr can be set right. */
2033	repat_keys(xfrd, opt);
2034	repat_patterns(xfrd, opt);
2035	repat_options(xfrd, opt);
2036	zonestat_inc_ifneeded(xfrd);
2037	send_ok(ssl);
2038	region_destroy(region);
2039}
2040
2041/** do the serverpid command: printout pid of server process */
2042static void
2043do_serverpid(RES* ssl, xfrd_state_type* xfrd)
2044{
2045	(void)ssl_printf(ssl, "%u\n", (unsigned)xfrd->reload_pid);
2046}
2047
2048/** do the print_tsig command: printout tsig info */
2049static void
2050do_print_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
2051{
2052	if(*arg == '\0') {
2053		struct key_options* key;
2054		RBTREE_FOR(key, struct key_options*, xfrd->nsd->options->keys) {
2055			if(!ssl_printf(ssl, "key: name: \"%s\" secret: \"%s\" algorithm: %s\n", key->name, key->secret, key->algorithm))
2056				return;
2057		}
2058		return;
2059	} else {
2060		struct key_options* key_opts = key_options_find(xfrd->nsd->options, arg);
2061		if(!key_opts) {
2062			(void)ssl_printf(ssl, "error: no such key with name: %s\n", arg);
2063			return;
2064		} else {
2065			(void)ssl_printf(ssl, "key: name: \"%s\" secret: \"%s\" algorithm: %s\n", arg, key_opts->secret, key_opts->algorithm);
2066		}
2067	}
2068}
2069
2070/** do the update_tsig command: change existing tsig to new secret */
2071static void
2072do_update_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
2073{
2074	struct region* region = xfrd->nsd->options->region;
2075	char* arg2 = NULL;
2076	uint8_t data[65536]; /* 64K */
2077	struct key_options* key_opt;
2078
2079	if(*arg == '\0') {
2080		(void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2081		return;
2082	}
2083	if(!find_arg2(ssl, arg, &arg2)) {
2084		(void)ssl_printf(ssl, "error: missing argument (secret)\n");
2085		return;
2086	}
2087	key_opt = key_options_find(xfrd->nsd->options, arg);
2088	if(!key_opt) {
2089		(void)ssl_printf(ssl, "error: no such key with name: %s\n", arg);
2090		memset(arg2, 0xdd, strlen(arg2));
2091		return;
2092	}
2093	if(__b64_pton(arg2, data, sizeof(data)) == -1) {
2094		(void)ssl_printf(ssl, "error: the secret: %s is not in b64 format\n", arg2);
2095		memset(data, 0xdd, sizeof(data)); /* wipe secret */
2096		memset(arg2, 0xdd, strlen(arg2));
2097		return;
2098	}
2099	log_msg(LOG_INFO, "changing secret provided with the key: %s with old secret %s and algo: %s\n", arg, key_opt->secret, key_opt->algorithm);
2100	if(key_opt->secret) {
2101		/* wipe old secret */
2102		memset(key_opt->secret, 0xdd, strlen(key_opt->secret));
2103		region_recycle(region, key_opt->secret,
2104			strlen(key_opt->secret)+1);
2105	}
2106	key_opt->secret = region_strdup(region, arg2);
2107	log_msg(LOG_INFO, "the key: %s has new secret %s and algorithm: %s\n", arg, key_opt->secret, key_opt->algorithm);
2108	/* wipe secret from temp parse buffer */
2109	memset(arg2, 0xdd, strlen(arg2));
2110	memset(data, 0xdd, sizeof(data));
2111
2112	key_options_desetup(region, key_opt);
2113	key_options_setup(region, key_opt);
2114	task_new_add_key(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
2115		key_opt);
2116	xfrd_set_reload_now(xfrd);
2117
2118	send_ok(ssl);
2119}
2120
2121/** do the add tsig command, add new key with name, secret and algo given */
2122static void
2123do_add_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
2124{
2125	char* arg2 = NULL;
2126	char* arg3 = NULL;
2127	uint8_t data[65536]; /* 64KB */
2128	uint8_t dname[MAXDOMAINLEN+1];
2129	char algo[256];
2130	region_type* region = xfrd->nsd->options->region;
2131	struct key_options* new_key_opt;
2132
2133	if(*arg == '\0') {
2134		(void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2135		return;
2136	}
2137	if(!find_arg3(ssl, arg, &arg2, &arg3)) {
2138		strlcpy(algo, "hmac-sha256", sizeof(algo));
2139	} else {
2140		strlcpy(algo, arg3, sizeof(algo));
2141	}
2142	if(!arg2) {
2143		(void)ssl_printf(ssl, "error: missing argument (secret)\n");
2144		return;
2145	}
2146	if(key_options_find(xfrd->nsd->options, arg)) {
2147		(void)ssl_printf(ssl, "error: key %s already exists\n", arg);
2148		memset(arg2, 0xdd, strlen(arg2));
2149		return;
2150	}
2151	if(__b64_pton(arg2, data, sizeof(data)) == -1) {
2152		(void)ssl_printf(ssl, "error: the secret: %s is not in b64 format\n", arg2);
2153		memset(data, 0xdd, sizeof(data)); /* wipe secret */
2154		memset(arg2, 0xdd, strlen(arg2));
2155		return;
2156	}
2157	memset(data, 0xdd, sizeof(data)); /* wipe secret from temp buffer */
2158	if(!dname_parse_wire(dname, arg)) {
2159		(void)ssl_printf(ssl, "error: could not parse key name: %s\n", arg);
2160		memset(arg2, 0xdd, strlen(arg2));
2161		return;
2162	}
2163	if(tsig_get_algorithm_by_name(algo) == NULL) {
2164		(void)ssl_printf(ssl, "error: unknown algorithm: %s\n", algo);
2165		memset(arg2, 0xdd, strlen(arg2));
2166		return;
2167	}
2168	log_msg(LOG_INFO, "adding key with name: %s and secret: %s with algo: %s\n", arg, arg2, algo);
2169	new_key_opt = key_options_create(region);
2170	new_key_opt->name = region_strdup(region, arg);
2171	new_key_opt->secret = region_strdup(region, arg2);
2172	new_key_opt->algorithm = region_strdup(region, algo);
2173	add_key(xfrd, new_key_opt);
2174
2175	/* wipe secret from temp buffer */
2176	memset(arg2, 0xdd, strlen(arg2));
2177	send_ok(ssl);
2178}
2179
2180/** set acl entries to use the given TSIG key */
2181static void
2182zopt_set_acl_to_tsig(struct acl_options* acl, struct region* region,
2183	const char* key_name, struct key_options* key_opt)
2184{
2185	while(acl) {
2186		if(acl->blocked) {
2187			acl = acl->next;
2188			continue;
2189		}
2190		acl->nokey = 0;
2191		if(acl->key_name)
2192			region_recycle(region, (void*)acl->key_name,
2193				strlen(acl->key_name)+1);
2194		acl->key_name = region_strdup(region, key_name);
2195		acl->key_options = key_opt;
2196		acl = acl->next;
2197	}
2198}
2199
2200/** do the assoc_tsig command: associate the zone to use the tsig name */
2201static void
2202do_assoc_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg)
2203{
2204	region_type* region = xfrd->nsd->options->region;
2205	char* arg2 = NULL;
2206	struct zone_options* zone;
2207	struct key_options* key_opt;
2208
2209	if(*arg == '\0') {
2210		(void)ssl_printf(ssl, "error: missing argument (zonename)\n");
2211		return;
2212	}
2213	if(!find_arg2(ssl, arg, &arg2)) {
2214		(void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2215		return;
2216	}
2217
2218	if(!get_zone_arg(ssl, xfrd, arg, &zone))
2219		return;
2220	if(!zone) {
2221		(void)ssl_printf(ssl, "error: missing argument (zone)\n");
2222		return;
2223	}
2224	key_opt = key_options_find(xfrd->nsd->options, arg2);
2225	if(!key_opt) {
2226		(void)ssl_printf(ssl, "error: key: %s does not exist\n", arg2);
2227		return;
2228	}
2229
2230	zopt_set_acl_to_tsig(zone->pattern->allow_notify, region, arg2,
2231		key_opt);
2232	zopt_set_acl_to_tsig(zone->pattern->notify, region, arg2, key_opt);
2233	zopt_set_acl_to_tsig(zone->pattern->request_xfr, region, arg2,
2234		key_opt);
2235	zopt_set_acl_to_tsig(zone->pattern->provide_xfr, region, arg2,
2236		key_opt);
2237	zopt_set_acl_to_tsig(zone->pattern->allow_query, region, arg2,
2238		key_opt);
2239
2240	task_new_add_pattern(xfrd->nsd->task[xfrd->nsd->mytask],
2241		xfrd->last_task, zone->pattern);
2242	xfrd_set_reload_now(xfrd);
2243
2244	send_ok(ssl);
2245}
2246
2247/** see if TSIG key is used in the acl */
2248static int
2249acl_contains_tsig_key(struct acl_options* acl, const char* name)
2250{
2251	while(acl) {
2252		if(acl->key_name && strcmp(acl->key_name, name) == 0)
2253			return 1;
2254		acl = acl->next;
2255	}
2256	return 0;
2257}
2258
2259/** do the del_tsig command, remove an (unused) tsig */
2260static void
2261do_del_tsig(RES* ssl, xfrd_state_type* xfrd, char* arg) {
2262	int used_key = 0;
2263	struct zone_options* zone;
2264	struct key_options* key_opt;
2265
2266	if(*arg == '\0') {
2267		(void)ssl_printf(ssl, "error: missing argument (keyname)\n");
2268		return;
2269	}
2270	key_opt = key_options_find(xfrd->nsd->options, arg);
2271	if(!key_opt) {
2272		(void)ssl_printf(ssl, "key %s does not exist, nothing to be deleted\n", arg);
2273		return;
2274	}
2275	RBTREE_FOR(zone, struct zone_options*, xfrd->nsd->options->zone_options)
2276	{
2277		if(acl_contains_tsig_key(zone->pattern->allow_notify, arg) ||
2278		   acl_contains_tsig_key(zone->pattern->notify, arg) ||
2279		   acl_contains_tsig_key(zone->pattern->request_xfr, arg) ||
2280		   acl_contains_tsig_key(zone->pattern->provide_xfr, arg) ||
2281		   acl_contains_tsig_key(zone->pattern->allow_query, arg)) {
2282			if(!ssl_printf(ssl, "zone %s uses key %s\n",
2283				zone->name, arg))
2284				return;
2285			used_key = 1;
2286			break;
2287		}
2288	}
2289
2290	if(used_key) {
2291		(void)ssl_printf(ssl, "error: key: %s is in use and cannot be deleted\n", arg);
2292		return;
2293	} else {
2294		remove_key(xfrd, arg);
2295		log_msg(LOG_INFO, "key: %s is successfully deleted\n", arg);
2296	}
2297
2298	send_ok(ssl);
2299}
2300
2301/* returns `0` on failure */
2302static int
2303cookie_secret_file_dump(RES* ssl, nsd_type const* nsd) {
2304	char const* secret_file = nsd->options->cookie_secret_file;
2305	char secret_hex[NSD_COOKIE_SECRET_SIZE * 2 + 1];
2306	FILE* f;
2307	size_t i;
2308	assert( secret_file != NULL );
2309
2310	/* open write only and truncate */
2311	if((f = fopen(secret_file, "w")) == NULL ) {
2312		(void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
2313		                 secret_file, strerror(errno));
2314		return 0;
2315	}
2316	for(i = 0; i < nsd->cookie_count; i++) {
2317		struct cookie_secret const* cs = &nsd->cookie_secrets[i];
2318		ssize_t const len = hex_ntop(cs->cookie_secret, NSD_COOKIE_SECRET_SIZE,
2319			secret_hex, sizeof(secret_hex));
2320		(void)len; /* silence unused variable warning with -DNDEBUG */
2321		assert( len == NSD_COOKIE_SECRET_SIZE * 2 );
2322		secret_hex[NSD_COOKIE_SECRET_SIZE * 2] = '\0';
2323		fprintf(f, "%s\n", secret_hex);
2324	}
2325	explicit_bzero(secret_hex, sizeof(secret_hex));
2326	fclose(f);
2327	return 1;
2328}
2329
2330static void
2331do_activate_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2332	nsd_type* nsd = xrfd->nsd;
2333	(void)arg;
2334
2335	if(nsd->cookie_count <= 1 ) {
2336		(void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
2337		return;
2338	}
2339	if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2340		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2341		return;
2342	}
2343	if(!cookie_secret_file_dump(ssl, nsd)) {
2344		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2345				nsd->options->cookie_secret_file);
2346		return;
2347	}
2348	activate_cookie_secret(nsd);
2349	(void)cookie_secret_file_dump(ssl, nsd);
2350	task_new_activate_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2351	    xfrd->last_task);
2352	xfrd_set_reload_now(xfrd);
2353	send_ok(ssl);
2354}
2355
2356static void
2357do_drop_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2358	nsd_type* nsd = xrfd->nsd;
2359	(void)arg;
2360
2361	if(nsd->cookie_count <= 1 ) {
2362		(void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
2363		return;
2364	}
2365	if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2366		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2367		return;
2368	}
2369	if(!cookie_secret_file_dump(ssl, nsd)) {
2370		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2371				nsd->options->cookie_secret_file);
2372		return;
2373	}
2374	drop_cookie_secret(nsd);
2375	(void)cookie_secret_file_dump(ssl, nsd);
2376	task_new_drop_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2377	    xfrd->last_task);
2378	xfrd_set_reload_now(xfrd);
2379	send_ok(ssl);
2380}
2381
2382static void
2383do_add_cookie_secret(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2384	nsd_type* nsd = xrfd->nsd;
2385	uint8_t secret[NSD_COOKIE_SECRET_SIZE];
2386
2387	if(*arg == '\0') {
2388		(void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
2389		return;
2390	}
2391	if(strlen(arg) != 32) {
2392		explicit_bzero(arg, strlen(arg));
2393		(void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
2394		(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
2395		return;
2396	}
2397	if(hex_pton(arg, secret, NSD_COOKIE_SECRET_SIZE) != NSD_COOKIE_SECRET_SIZE ) {
2398		explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE);
2399		explicit_bzero(arg, strlen(arg));
2400		(void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
2401		(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
2402		return;
2403	}
2404	if(!nsd->options->cookie_secret_file || !nsd->options->cookie_secret_file[0]) {
2405		explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE);
2406		explicit_bzero(arg, strlen(arg));
2407		(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
2408		return;
2409	}
2410	if(!cookie_secret_file_dump(ssl, nsd)) {
2411		explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE);
2412		explicit_bzero(arg, strlen(arg));
2413		(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
2414				nsd->options->cookie_secret_file);
2415		return;
2416	}
2417	add_cookie_secret(nsd, secret);
2418	explicit_bzero(secret, NSD_COOKIE_SECRET_SIZE);
2419	(void)cookie_secret_file_dump(ssl, nsd);
2420	task_new_add_cookie_secret(xfrd->nsd->task[xfrd->nsd->mytask],
2421	    xfrd->last_task, arg);
2422	explicit_bzero(arg, strlen(arg));
2423	xfrd_set_reload_now(xfrd);
2424	send_ok(ssl);
2425}
2426
2427static void
2428do_print_cookie_secrets(RES* ssl, xfrd_state_type* xrfd, char* arg) {
2429	nsd_type* nsd = xrfd->nsd;
2430	char secret_hex[NSD_COOKIE_SECRET_SIZE * 2 + 1];
2431	int i;
2432	(void)arg;
2433
2434	/* (void)ssl_printf(ssl, "cookie_secret_count=%zu\n", nsd->cookie_count); */
2435	for(i = 0; (size_t)i < nsd->cookie_count; i++) {
2436		struct cookie_secret const* cs = &nsd->cookie_secrets[i];
2437		ssize_t const len = hex_ntop(cs->cookie_secret, NSD_COOKIE_SECRET_SIZE,
2438		                             secret_hex, sizeof(secret_hex));
2439		(void)len; /* silence unused variable warning with -DNDEBUG */
2440		assert( len == NSD_COOKIE_SECRET_SIZE * 2 );
2441		secret_hex[NSD_COOKIE_SECRET_SIZE * 2] = '\0';
2442		if (i == 0)
2443			(void)ssl_printf(ssl, "active : %s\n",  secret_hex);
2444		else if (nsd->cookie_count == 2)
2445			(void)ssl_printf(ssl, "staging: %s\n",  secret_hex);
2446		else
2447			(void)ssl_printf(ssl, "staging[%d]: %s\n", i, secret_hex);
2448	}
2449	explicit_bzero(secret_hex, sizeof(secret_hex));
2450}
2451
2452/** check for name with end-of-string, space or tab after it */
2453static int
2454cmdcmp(char* p, const char* cmd, size_t len)
2455{
2456	return strncmp(p,cmd,len)==0 && (p[len]==0||p[len]==' '||p[len]=='\t');
2457}
2458
2459/** execute a remote control command */
2460static void
2461execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
2462{
2463	char* p = skipwhite(cmd);
2464	/* compare command */
2465	if(cmdcmp(p, "stop", 4)) {
2466		do_stop(ssl, rc->xfrd);
2467	} else if(cmdcmp(p, "reload", 6)) {
2468		do_reload(ssl, rc->xfrd, skipwhite(p+6));
2469	} else if(cmdcmp(p, "write", 5)) {
2470		do_write(ssl, rc->xfrd, skipwhite(p+5));
2471	} else if(cmdcmp(p, "status", 6)) {
2472		do_status(ssl, rc->xfrd);
2473	} else if(cmdcmp(p, "stats_noreset", 13)) {
2474		do_stats(ssl, rc->xfrd, 1);
2475	} else if(cmdcmp(p, "stats", 5)) {
2476		do_stats(ssl, rc->xfrd, 0);
2477	} else if(cmdcmp(p, "log_reopen", 10)) {
2478		do_log_reopen(ssl, rc->xfrd);
2479	} else if(cmdcmp(p, "addzone", 7)) {
2480		do_addzone(ssl, rc->xfrd, skipwhite(p+7));
2481	} else if(cmdcmp(p, "delzone", 7)) {
2482		do_delzone(ssl, rc->xfrd, skipwhite(p+7));
2483	} else if(cmdcmp(p, "changezone", 10)) {
2484		do_changezone(ssl, rc->xfrd, skipwhite(p+10));
2485	} else if(cmdcmp(p, "addzones", 8)) {
2486		do_addzones(ssl, rc->xfrd);
2487	} else if(cmdcmp(p, "delzones", 8)) {
2488		do_delzones(ssl, rc->xfrd);
2489	} else if(cmdcmp(p, "notify", 6)) {
2490		do_notify(ssl, rc->xfrd, skipwhite(p+6));
2491	} else if(cmdcmp(p, "transfer", 8)) {
2492		do_transfer(ssl, rc->xfrd, skipwhite(p+8));
2493	} else if(cmdcmp(p, "force_transfer", 14)) {
2494		do_force_transfer(ssl, rc->xfrd, skipwhite(p+14));
2495	} else if(cmdcmp(p, "zonestatus", 10)) {
2496		do_zonestatus(ssl, rc->xfrd, skipwhite(p+10));
2497	} else if(cmdcmp(p, "verbosity", 9)) {
2498		do_verbosity(ssl, skipwhite(p+9));
2499	} else if(cmdcmp(p, "repattern", 9)) {
2500		do_repattern(ssl, rc->xfrd);
2501	} else if(cmdcmp(p, "reconfig", 8)) {
2502		do_repattern(ssl, rc->xfrd);
2503	} else if(cmdcmp(p, "serverpid", 9)) {
2504		do_serverpid(ssl, rc->xfrd);
2505	} else if(cmdcmp(p, "print_tsig", 10)) {
2506		do_print_tsig(ssl, rc->xfrd, skipwhite(p+10));
2507	} else if(cmdcmp(p, "update_tsig", 11)) {
2508		do_update_tsig(ssl, rc->xfrd, skipwhite(p+11));
2509	} else if(cmdcmp(p, "add_tsig", 8)) {
2510		do_add_tsig(ssl, rc->xfrd, skipwhite(p+8));
2511	} else if(cmdcmp(p, "assoc_tsig", 10)) {
2512		do_assoc_tsig(ssl, rc->xfrd, skipwhite(p+10));
2513	} else if(cmdcmp(p, "del_tsig", 8)) {
2514		do_del_tsig(ssl, rc->xfrd, skipwhite(p+8));
2515	} else if(cmdcmp(p, "add_cookie_secret", 17)) {
2516		do_add_cookie_secret(ssl, rc->xfrd, skipwhite(p+17));
2517	} else if(cmdcmp(p, "drop_cookie_secret", 18)) {
2518		do_drop_cookie_secret(ssl, rc->xfrd, skipwhite(p+18));
2519	} else if(cmdcmp(p, "print_cookie_secrets", 20)) {
2520		do_print_cookie_secrets(ssl, rc->xfrd, skipwhite(p+20));
2521	} else if(cmdcmp(p, "activate_cookie_secret", 22)) {
2522		do_activate_cookie_secret(ssl, rc->xfrd, skipwhite(p+22));
2523	} else {
2524		(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
2525	}
2526}
2527
2528/** handle remote control request */
2529static void
2530handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
2531{
2532	int r;
2533	char pre[10];
2534	char magic[8];
2535	char buf[1024];
2536	if (fcntl(s->c.ev_fd, F_SETFL, 0) == -1) { /* set blocking */
2537		log_msg(LOG_ERR, "cannot fcntl rc: %s", strerror(errno));
2538	}
2539
2540	/* try to read magic UBCT[version]_space_ string */
2541#ifdef HAVE_SSL
2542	if(res->ssl) {
2543		ERR_clear_error();
2544		if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
2545			if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN)
2546				return;
2547			log_crypto_err("could not SSL_read");
2548			return;
2549		}
2550	} else {
2551#endif /* HAVE_SSL */
2552		while(1) {
2553			ssize_t rr = read(res->fd, magic, sizeof(magic)-1);
2554			if(rr <= 0) {
2555				if(rr == 0) return;
2556				if(errno == EINTR || errno == EAGAIN)
2557					continue;
2558				log_msg(LOG_ERR, "could not read: %s", strerror(errno));
2559				return;
2560			}
2561			r = (int)rr;
2562			break;
2563		}
2564#ifdef HAVE_SSL
2565	}
2566#endif /* HAVE_SSL */
2567	magic[7] = 0;
2568	if( r != 7 || strncmp(magic, "NSDCT", 5) != 0) {
2569		VERBOSITY(2, (LOG_INFO, "control connection has bad header"));
2570		/* probably wrong tool connected, ignore it completely */
2571		return;
2572	}
2573
2574	/* read the command line */
2575	if(!ssl_read_line(res, buf, sizeof(buf))) {
2576		return;
2577	}
2578	snprintf(pre, sizeof(pre), "NSDCT%d ", NSD_CONTROL_VERSION);
2579	if(strcmp(magic, pre) != 0) {
2580		VERBOSITY(2, (LOG_INFO, "control connection had bad "
2581			"version %s, cmd: %s", magic, buf));
2582		(void)ssl_printf(res, "error version mismatch\n");
2583		return;
2584	}
2585	/* always log control commands */
2586	VERBOSITY(0, (LOG_INFO, "control cmd: %s", buf));
2587
2588	/* figure out what to do */
2589	execute_cmd(rc, res, buf);
2590}
2591
2592#ifdef HAVE_SSL
2593/** handle SSL_do_handshake changes to the file descriptor to wait for later */
2594static void
2595remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, int fd,
2596	int r, int r2)
2597{
2598	if(r2 == SSL_ERROR_WANT_READ) {
2599		if(s->shake_state == rc_hs_read) {
2600			/* try again later */
2601			return;
2602		}
2603		s->shake_state = rc_hs_read;
2604		if(s->event_added)
2605			event_del(&s->c);
2606		memset(&s->c, 0, sizeof(s->c));
2607		event_set(&s->c, fd, EV_PERSIST|EV_TIMEOUT|EV_READ,
2608			remote_control_callback, s);
2609		if(event_base_set(xfrd->event_base, &s->c) != 0)
2610			log_msg(LOG_ERR, "remote_accept: cannot set event_base");
2611		if(event_add(&s->c, &s->tval) != 0)
2612			log_msg(LOG_ERR, "remote_accept: cannot add event");
2613		s->event_added = 1;
2614		return;
2615	} else if(r2 == SSL_ERROR_WANT_WRITE) {
2616		if(s->shake_state == rc_hs_write) {
2617			/* try again later */
2618			return;
2619		}
2620		s->shake_state = rc_hs_write;
2621		if(s->event_added)
2622			event_del(&s->c);
2623		memset(&s->c, 0, sizeof(s->c));
2624		event_set(&s->c, fd, EV_PERSIST|EV_TIMEOUT|EV_WRITE,
2625			remote_control_callback, s);
2626		if(event_base_set(xfrd->event_base, &s->c) != 0)
2627			log_msg(LOG_ERR, "remote_accept: cannot set event_base");
2628		if(event_add(&s->c, &s->tval) != 0)
2629			log_msg(LOG_ERR, "remote_accept: cannot add event");
2630		s->event_added = 1;
2631		return;
2632	} else {
2633		if(r == 0)
2634			log_msg(LOG_ERR, "remote control connection closed prematurely");
2635		log_crypto_err("remote control failed ssl");
2636		clean_point(rc, s);
2637	}
2638}
2639#endif /* HAVE_SSL */
2640
2641static void
2642remote_control_callback(int fd, short event, void* arg)
2643{
2644	RES res;
2645	struct rc_state* s = (struct rc_state*)arg;
2646	struct daemon_remote* rc = s->rc;
2647	if( (event&EV_TIMEOUT) ) {
2648		log_msg(LOG_ERR, "remote control timed out");
2649		clean_point(rc, s);
2650		return;
2651	}
2652#ifdef HAVE_SSL
2653	if(s->ssl) {
2654		/* (continue to) setup the SSL connection */
2655		int r;
2656		ERR_clear_error();
2657		r = SSL_do_handshake(s->ssl);
2658		if(r != 1) {
2659			int r2 = SSL_get_error(s->ssl, r);
2660			remote_handshake_later(rc, s, fd, r, r2);
2661			return;
2662		}
2663		s->shake_state = rc_none;
2664	}
2665#endif /* HAVE_SSL */
2666
2667	/* once handshake has completed, check authentication */
2668	if (!rc->use_cert) {
2669		VERBOSITY(3, (LOG_INFO, "unauthenticated remote control connection"));
2670#ifdef HAVE_SSL
2671	} else if(SSL_get_verify_result(s->ssl) == X509_V_OK) {
2672		X509* x = SSL_get_peer_certificate(s->ssl);
2673		if(!x) {
2674			VERBOSITY(2, (LOG_INFO, "remote control connection "
2675				"provided no client certificate"));
2676			clean_point(rc, s);
2677			return;
2678		}
2679		VERBOSITY(3, (LOG_INFO, "remote control connection authenticated"));
2680		X509_free(x);
2681#endif /* HAVE_SSL */
2682	} else {
2683		VERBOSITY(2, (LOG_INFO, "remote control connection failed to "
2684			"authenticate with client certificate"));
2685		clean_point(rc, s);
2686		return;
2687	}
2688
2689	/* if OK start to actually handle the request */
2690#ifdef HAVE_SSL
2691	res.ssl = s->ssl;
2692#endif /* HAVE_SSL */
2693	res.fd = fd;
2694	handle_req(rc, s, &res);
2695
2696	VERBOSITY(3, (LOG_INFO, "remote control operation completed"));
2697	clean_point(rc, s);
2698}
2699
2700#ifdef BIND8_STATS
2701static const char*
2702opcode2str(int o)
2703{
2704	switch(o) {
2705		case OPCODE_QUERY: return "QUERY";
2706		case OPCODE_IQUERY: return "IQUERY";
2707		case OPCODE_STATUS: return "STATUS";
2708		case OPCODE_NOTIFY: return "NOTIFY";
2709		case OPCODE_UPDATE: return "UPDATE";
2710		default: return "OTHER";
2711	}
2712}
2713
2714/** print long number */
2715static int
2716print_longnum(RES* ssl, char* desc, uint64_t x)
2717{
2718	if(x > (uint64_t)1024*1024*1024) {
2719		/* more than a Gb */
2720		size_t front = (size_t)(x / (uint64_t)1000000);
2721		size_t back = (size_t)(x % (uint64_t)1000000);
2722		return ssl_printf(ssl, "%s%lu%6.6lu\n", desc,
2723			(unsigned long)front, (unsigned long)back);
2724	} else {
2725		return ssl_printf(ssl, "%s%lu\n", desc, (unsigned long)x);
2726	}
2727}
2728
2729/* print one block of statistics.  n is name and d is delimiter */
2730static void
2731print_stat_block(RES* ssl, char* n, char* d, struct nsdst* st)
2732{
2733	const char* rcstr[] = {"NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN",
2734	    "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", "NXRRSET", "NOTAUTH",
2735	    "NOTZONE", "RCODE11", "RCODE12", "RCODE13", "RCODE14", "RCODE15",
2736	    "BADVERS"
2737	};
2738	size_t i;
2739	for(i=0; i<= 255; i++) {
2740		if(inhibit_zero && st->qtype[i] == 0 &&
2741			strncmp(rrtype_to_string(i), "TYPE", 4) == 0)
2742			continue;
2743		if(!ssl_printf(ssl, "%s%snum.type.%s=%lu\n", n, d,
2744			rrtype_to_string(i), (unsigned long)st->qtype[i]))
2745			return;
2746	}
2747
2748	/* opcode */
2749	for(i=0; i<6; i++) {
2750		if(inhibit_zero && st->opcode[i] == 0 && i != OPCODE_QUERY)
2751			continue;
2752		if(!ssl_printf(ssl, "%s%snum.opcode.%s=%lu\n", n, d,
2753			opcode2str(i), (unsigned long)st->opcode[i]))
2754			return;
2755	}
2756
2757	/* qclass */
2758	for(i=0; i<4; i++) {
2759		if(inhibit_zero && st->qclass[i] == 0 && i != CLASS_IN)
2760			continue;
2761		if(!ssl_printf(ssl, "%s%snum.class.%s=%lu\n", n, d,
2762			rrclass_to_string(i), (unsigned long)st->qclass[i]))
2763			return;
2764	}
2765
2766	/* rcode */
2767	for(i=0; i<17; i++) {
2768		if(inhibit_zero && st->rcode[i] == 0 &&
2769			i > RCODE_YXDOMAIN) /* NSD does not use larger */
2770			continue;
2771		if(!ssl_printf(ssl, "%s%snum.rcode.%s=%lu\n", n, d, rcstr[i],
2772			(unsigned long)st->rcode[i]))
2773			return;
2774	}
2775
2776	/* edns */
2777	if(!ssl_printf(ssl, "%s%snum.edns=%lu\n", n, d, (unsigned long)st->edns))
2778		return;
2779
2780	/* ednserr */
2781	if(!ssl_printf(ssl, "%s%snum.ednserr=%lu\n", n, d,
2782		(unsigned long)st->ednserr))
2783		return;
2784
2785	/* qudp */
2786	if(!ssl_printf(ssl, "%s%snum.udp=%lu\n", n, d, (unsigned long)st->qudp))
2787		return;
2788	/* qudp6 */
2789	if(!ssl_printf(ssl, "%s%snum.udp6=%lu\n", n, d, (unsigned long)st->qudp6))
2790		return;
2791	/* ctcp */
2792	if(!ssl_printf(ssl, "%s%snum.tcp=%lu\n", n, d, (unsigned long)st->ctcp))
2793		return;
2794	/* ctcp6 */
2795	if(!ssl_printf(ssl, "%s%snum.tcp6=%lu\n", n, d, (unsigned long)st->ctcp6))
2796		return;
2797	/* ctls */
2798	if(!ssl_printf(ssl, "%s%snum.tls=%lu\n", n, d, (unsigned long)st->ctls))
2799		return;
2800	/* ctls6 */
2801	if(!ssl_printf(ssl, "%s%snum.tls6=%lu\n", n, d, (unsigned long)st->ctls6))
2802		return;
2803
2804	/* nona */
2805	if(!ssl_printf(ssl, "%s%snum.answer_wo_aa=%lu\n", n, d,
2806		(unsigned long)st->nona))
2807		return;
2808
2809	/* rxerr */
2810	if(!ssl_printf(ssl, "%s%snum.rxerr=%lu\n", n, d, (unsigned long)st->rxerr))
2811		return;
2812
2813	/* txerr */
2814	if(!ssl_printf(ssl, "%s%snum.txerr=%lu\n", n, d, (unsigned long)st->txerr))
2815		return;
2816
2817	/* number of requested-axfr, number of times axfr served to clients */
2818	if(!ssl_printf(ssl, "%s%snum.raxfr=%lu\n", n, d, (unsigned long)st->raxfr))
2819		return;
2820
2821	/* number of requested-ixfr, number of times ixfr served to clients */
2822	if(!ssl_printf(ssl, "%s%snum.rixfr=%lu\n", n, d, (unsigned long)st->rixfr))
2823		return;
2824
2825	/* truncated */
2826	if(!ssl_printf(ssl, "%s%snum.truncated=%lu\n", n, d,
2827		(unsigned long)st->truncated))
2828		return;
2829
2830	/* dropped */
2831	if(!ssl_printf(ssl, "%s%snum.dropped=%lu\n", n, d,
2832		(unsigned long)st->dropped))
2833		return;
2834}
2835
2836#ifdef USE_ZONE_STATS
2837static void
2838resize_zonestat(xfrd_state_type* xfrd, size_t num)
2839{
2840	struct nsdst** a = xalloc_array_zero(num, sizeof(struct nsdst*));
2841	if(xfrd->zonestat_clear_num != 0)
2842		memcpy(a, xfrd->zonestat_clear, xfrd->zonestat_clear_num
2843			* sizeof(struct nsdst*));
2844	free(xfrd->zonestat_clear);
2845	xfrd->zonestat_clear = a;
2846	xfrd->zonestat_clear_num = num;
2847}
2848
2849static void
2850zonestat_print(RES* ssl, xfrd_state_type* xfrd, int clear,
2851	struct nsdst** zonestats)
2852{
2853	struct zonestatname* n;
2854	struct nsdst stat0, stat1;
2855	RBTREE_FOR(n, struct zonestatname*, xfrd->nsd->options->zonestatnames){
2856		char* name = (char*)n->node.key;
2857		if(n->id >= xfrd->zonestat_safe)
2858			continue; /* newly allocated and reload has not yet
2859				done and replied with new size */
2860		if(name == NULL || name[0]==0)
2861			continue; /* empty name, do not output */
2862		/* the statistics are stored in two blocks, during reload
2863		 * the newly forked processes get the other block to use,
2864		 * these blocks are mmapped and are currently in use to
2865		 * add statistics to */
2866		memcpy(&stat0, &zonestats[0][n->id], sizeof(stat0));
2867		memcpy(&stat1, &zonestats[1][n->id], sizeof(stat1));
2868		stats_add(&stat0, &stat1);
2869
2870		/* save a copy of current (cumulative) stats in stat1 */
2871		memcpy(&stat1, &stat0, sizeof(stat1));
2872		/* subtract last total of stats that was 'cleared' */
2873		if(n->id < xfrd->zonestat_clear_num &&
2874			xfrd->zonestat_clear[n->id])
2875			stats_subtract(&stat0, xfrd->zonestat_clear[n->id]);
2876		if(clear) {
2877			/* extend storage array if needed */
2878			if(n->id >= xfrd->zonestat_clear_num) {
2879				if(n->id+1 < xfrd->nsd->options->zonestatnames->count)
2880					resize_zonestat(xfrd, xfrd->nsd->options->zonestatnames->count);
2881				else
2882					resize_zonestat(xfrd, n->id+1);
2883			}
2884			if(!xfrd->zonestat_clear[n->id])
2885				xfrd->zonestat_clear[n->id] = xalloc(
2886					sizeof(struct nsdst));
2887			/* store last total of stats */
2888			memcpy(xfrd->zonestat_clear[n->id], &stat1,
2889				sizeof(struct nsdst));
2890		}
2891
2892		/* stat0 contains the details that we want to print */
2893		if(!ssl_printf(ssl, "%s%snum.queries=%lu\n", name, ".",
2894			(unsigned long)(stat0.qudp + stat0.qudp6 + stat0.ctcp +
2895				stat0.ctcp6 + stat0.ctls + stat0.ctls6)))
2896			return;
2897		print_stat_block(ssl, name, ".", &stat0);
2898	}
2899}
2900#endif /* USE_ZONE_STATS */
2901
2902static void
2903print_stats(RES* ssl, xfrd_state_type* xfrd, struct timeval* now, int clear,
2904	struct nsdst* st, struct nsdst** zonestats)
2905{
2906	size_t i;
2907	stc_type total = 0;
2908	struct timeval elapsed, uptime;
2909
2910	/* per CPU and total */
2911	for(i=0; i<xfrd->nsd->child_count; i++) {
2912		if(!ssl_printf(ssl, "server%d.queries=%lu\n", (int)i,
2913			(unsigned long)xfrd->nsd->children[i].query_count))
2914			return;
2915		total += xfrd->nsd->children[i].query_count;
2916	}
2917	if(!ssl_printf(ssl, "num.queries=%lu\n", (unsigned long)total))
2918		return;
2919
2920	/* time elapsed and uptime (in seconds) */
2921	timeval_subtract(&uptime, now, &xfrd->nsd->rc->boot_time);
2922	timeval_subtract(&elapsed, now, &xfrd->nsd->rc->stats_time);
2923	if(!ssl_printf(ssl, "time.boot=%lu.%6.6lu\n",
2924		(unsigned long)uptime.tv_sec, (unsigned long)uptime.tv_usec))
2925		return;
2926	if(!ssl_printf(ssl, "time.elapsed=%lu.%6.6lu\n",
2927		(unsigned long)elapsed.tv_sec, (unsigned long)elapsed.tv_usec))
2928		return;
2929
2930	/* mem info, database on disksize */
2931	if(!print_longnum(ssl, "size.db.disk=", st->db_disk))
2932		return;
2933	if(!print_longnum(ssl, "size.db.mem=", st->db_mem))
2934		return;
2935	if(!print_longnum(ssl, "size.xfrd.mem=", region_get_mem(xfrd->region)))
2936		return;
2937	if(!print_longnum(ssl, "size.config.disk=",
2938		xfrd->nsd->options->zonelist_off))
2939		return;
2940	if(!print_longnum(ssl, "size.config.mem=", region_get_mem(
2941		xfrd->nsd->options->region)))
2942		return;
2943	print_stat_block(ssl, "", "", st);
2944
2945	/* zone statistics */
2946	if(!ssl_printf(ssl, "zone.primary=%lu\n",
2947		(unsigned long)(xfrd->notify_zones->count - xfrd->zones->count)))
2948		return;
2949	if(!ssl_printf(ssl, "zone.secondary=%lu\n", (unsigned long)xfrd->zones->count))
2950		return;
2951	if(!ssl_printf(ssl, "zone.master=%lu\n",
2952		(unsigned long)(xfrd->notify_zones->count - xfrd->zones->count)))
2953		return;
2954	if(!ssl_printf(ssl, "zone.slave=%lu\n", (unsigned long)xfrd->zones->count))
2955		return;
2956#ifdef USE_ZONE_STATS
2957	zonestat_print(ssl, xfrd, clear, zonestats); /* per-zone statistics */
2958#else
2959	(void)clear; (void)zonestats;
2960#endif
2961}
2962
2963/* allocate stats temp arrays, for taking a coherent snapshot of the
2964 * statistics values at that time. */
2965static void
2966process_stats_alloc(xfrd_state_type* xfrd, struct nsdst** stats,
2967	struct nsdst** zonestats)
2968{
2969	*stats = xmallocarray(xfrd->nsd->child_count*2, sizeof(struct nsdst));
2970#ifdef USE_ZONE_STATS
2971	zonestats[0] = xmallocarray(xfrd->zonestat_safe, sizeof(struct nsdst));
2972	zonestats[1] = xmallocarray(xfrd->zonestat_safe, sizeof(struct nsdst));
2973#else
2974	(void)zonestats;
2975#endif
2976}
2977
2978/* grab a copy of the statistics, at this particular time. */
2979static void
2980process_stats_grab(xfrd_state_type* xfrd, struct timeval* stattime,
2981	struct nsdst* stats, struct nsdst** zonestats)
2982{
2983	if(gettimeofday(stattime, NULL) == -1)
2984		log_msg(LOG_ERR, "gettimeofday: %s", strerror(errno));
2985	memcpy(stats, xfrd->nsd->stat_map,
2986		xfrd->nsd->child_count*2*sizeof(struct nsdst));
2987#ifdef USE_ZONE_STATS
2988	memcpy(zonestats[0], xfrd->nsd->zonestat[0],
2989		xfrd->zonestat_safe*sizeof(struct nsdst));
2990	memcpy(zonestats[1], xfrd->nsd->zonestat[1],
2991		xfrd->zonestat_safe*sizeof(struct nsdst));
2992#else
2993	(void)zonestats;
2994#endif
2995}
2996
2997/* add the old and new processes stat values into the first part of the
2998 * array of stats */
2999static void
3000process_stats_add_old_new(xfrd_state_type* xfrd, struct nsdst* stats)
3001{
3002	size_t i;
3003	uint64_t dbd = stats[0].db_disk;
3004	uint64_t dbm = stats[0].db_mem;
3005	/* The old and new server processes have separate stat blocks,
3006	 * and these are added up together. This results in the statistics
3007	 * values per server-child. The reload task briefly forks both
3008	 * old and new server processes. */
3009	for(i=0; i<xfrd->nsd->child_count; i++) {
3010		stats_add(&stats[i], &stats[xfrd->nsd->child_count+i]);
3011	}
3012	stats[0].db_disk = dbd;
3013	stats[0].db_mem = dbm;
3014}
3015
3016/* manage clearing of stats, a cumulative count of cleared statistics */
3017static void
3018process_stats_manage_clear(xfrd_state_type* xfrd, struct nsdst* stats,
3019	int peek)
3020{
3021	struct nsdst st;
3022	size_t i;
3023	if(peek) {
3024		/* Subtract the earlier resetted values from the numbers,
3025		 * but do not reset the values that are retrieved now. */
3026		if(!xfrd->stat_clear)
3027			return; /* nothing to subtract */
3028		for(i=0; i<xfrd->nsd->child_count; i++) {
3029			/* subtract cumulative count that has been reset */
3030			stats_subtract(&stats[i], &xfrd->stat_clear[i]);
3031		}
3032		return;
3033	}
3034	if(!xfrd->stat_clear)
3035		xfrd->stat_clear = region_alloc_zero(xfrd->region,
3036			sizeof(struct nsdst)*xfrd->nsd->child_count);
3037	for(i=0; i<xfrd->nsd->child_count; i++) {
3038		/* store cumulative count copy */
3039		memcpy(&st, &stats[i], sizeof(st));
3040		/* subtract cumulative count that has been reset */
3041		stats_subtract(&stats[i], &xfrd->stat_clear[i]);
3042		/* store cumulative count in the cleared value array */
3043		memcpy(&xfrd->stat_clear[i], &st, sizeof(st));
3044	}
3045}
3046
3047/* add up the statistics to get the total over the server children. */
3048static void
3049process_stats_add_total(xfrd_state_type* xfrd, struct nsdst* total,
3050	struct nsdst* stats)
3051{
3052	size_t i;
3053	/* copy over the first one, with also the nonadded values. */
3054	memcpy(total, &stats[0], sizeof(*total));
3055	xfrd->nsd->children[0].query_count = stats[0].qudp + stats[0].qudp6
3056		+ stats[0].ctcp + stats[0].ctcp6 + stats[0].ctls
3057		+ stats[0].ctls6;
3058	for(i=1; i<xfrd->nsd->child_count; i++) {
3059		stats_add(total, &stats[i]);
3060		xfrd->nsd->children[i].query_count = stats[i].qudp
3061			+ stats[i].qudp6 + stats[i].ctcp + stats[i].ctcp6
3062			+ stats[i].ctls + stats[i].ctls6;
3063	}
3064}
3065
3066/* process the statistics and output them */
3067static void
3068process_stats(RES* ssl, xfrd_state_type* xfrd, int peek)
3069{
3070	struct timeval stattime;
3071	struct nsdst* stats, *zonestats[2], total;
3072
3073	process_stats_alloc(xfrd, &stats, zonestats);
3074	process_stats_grab(xfrd, &stattime, stats, zonestats);
3075	process_stats_add_old_new(xfrd, stats);
3076	process_stats_manage_clear(xfrd, stats, peek);
3077	process_stats_add_total(xfrd, &total, stats);
3078	print_stats(ssl, xfrd, &stattime, !peek, &total, zonestats);
3079	if(!peek) {
3080		xfrd->nsd->rc->stats_time = stattime;
3081	}
3082
3083	free(stats);
3084#ifdef USE_ZONE_STATS
3085	free(zonestats[0]);
3086	free(zonestats[1]);
3087#endif
3088
3089	VERBOSITY(3, (LOG_INFO, "remote control stats printed"));
3090}
3091#endif /* BIND8_STATS */
3092
3093int
3094create_local_accept_sock(const char *path, int* noproto)
3095{
3096#ifdef HAVE_SYS_UN_H
3097	int s;
3098	struct sockaddr_un usock;
3099
3100	VERBOSITY(3, (LOG_INFO, "creating unix socket %s", path));
3101#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
3102	/* this member exists on BSDs, not Linux */
3103	usock.sun_len = (unsigned)sizeof(usock);
3104#endif
3105	usock.sun_family = AF_LOCAL;
3106	/* length is 92-108, 104 on FreeBSD */
3107	(void)strlcpy(usock.sun_path, path, sizeof(usock.sun_path));
3108
3109	if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
3110		log_msg(LOG_ERR, "Cannot create local socket %s (%s)",
3111			path, strerror(errno));
3112		return -1;
3113	}
3114
3115	if (unlink(path) && errno != ENOENT) {
3116		/* The socket already exists and cannot be removed */
3117		log_msg(LOG_ERR, "Cannot remove old local socket %s (%s)",
3118			path, strerror(errno));
3119		goto err;
3120	}
3121
3122	if (bind(s, (struct sockaddr *)&usock,
3123		(socklen_t)sizeof(struct sockaddr_un)) == -1) {
3124		log_msg(LOG_ERR, "Cannot bind local socket %s (%s)",
3125			path, strerror(errno));
3126		goto err;
3127	}
3128
3129	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
3130		log_msg(LOG_ERR, "Cannot set non-blocking mode");
3131		goto err;
3132	}
3133
3134	if (listen(s, TCP_BACKLOG) == -1) {
3135		log_msg(LOG_ERR, "can't listen: %s", strerror(errno));
3136		goto err;
3137	}
3138
3139	(void)noproto; /*unused*/
3140	return s;
3141
3142err:
3143	close(s);
3144	return -1;
3145
3146#else
3147	(void)path;
3148	log_msg(LOG_ERR, "Local sockets are not supported");
3149	*noproto = 1;
3150	return -1;
3151#endif
3152}
3153