Bug Summary

File:src/usr.sbin/nsd/remote.c
Warning:line 429, column 5
Array access (from variable 'ip') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

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