rndc.c revision 523230336909d30111cb060b7eb6fc39d23ad174
/*
* Copyright (C) 2000-2018 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*! \file */
/*
* Principal Author: DCL
*/
#include <config.h>
#include <stdlib.h>
#include <isc/commandline.h>
#include <isccfg/namedconf.h>
#include <bind9/getaddresses.h>
#include "util.h"
#define SERVERADDRS 10
const char *progname;
static const char *admin_conffile;
static const char *admin_keyfile;
static const char *servername = NULL;
static int nserveraddrs;
static int currentaddr = 0;
static unsigned int remoteport = 0;
static isc_buffer_t *databuf;
static isccc_ccmsg_t ccmsg;
static isc_uint32_t algorithm;
static isccc_region_t secret;
static char *command;
static char *args;
static char program[256];
static isc_uint32_t serial;
ISC_PLATFORM_NORETURN_PRE static void
static void
Usage: %s [-b address] [-c config] [-s server] [-p port]\n\
[-k key-file ] [-y key] [-r] [-V] command\n\
\n\
command is one of the following:\n\
\n\
addzone zone [class [view]] { zone-options }\n\
Add zone to given view. Requires allow-new-zones option.\n\
delzone [-clean] zone [class [view]]\n\
Removes zone from given view.\n\
dnstap -reopen\n\
Close, truncate and re-open the DNSTAP output file.\n\
dnstap -roll count\n\
Close, rename and re-open the DNSTAP output file(s).\n\
dumpdb [-all|-cache|-zones|-adb|-bad|-fail] [view ...]\n\
Dump cache(s) to the dump file (named_dump.db).\n\
flush Flushes all of the server's caches.\n\
flush [view] Flushes the server's cache for a view.\n\
flushname name [view]\n\
Flush the given name from the server's cache(s)\n\
flushtree name [view]\n\
Flush all names under the given name from the server's cache(s)\n\
freeze Suspend updates to all dynamic zones.\n\
freeze zone [class [view]]\n\
Suspend updates to a dynamic zone.\n\
halt Stop the server without saving pending updates.\n\
halt -p Stop the server without saving pending updates reporting\n\
process id.\n\
loadkeys zone [class [view]]\n\
Update keys without signing immediately.\n\
managed-keys refresh [class [view]]\n\
Check trust anchor for RFC 5011 key changes\n\
managed-keys status [class [view]]\n\
Display RFC 5011 managed keys information\n\
managed-keys sync [class [view]]\n\
Write RFC 5011 managed keys to disk\n\
modzone zone [class [view]] { zone-options }\n\
Modify a zone's configuration.\n\
Requires allow-new-zones option.\n\
notify zone [class [view]]\n\
Resend NOTIFY messages for the zone.\n\
notrace Set debugging level to 0.\n\
nta -dump\n\
List all negative trust anchors.\n\
nta [-lifetime duration] [-force] domain [view]\n\
Set a negative trust anchor, disabling DNSSEC validation\n\
for the given domain.\n\
Using -lifetime specifies the duration of the NTA, up\n\
to one week.\n\
Using -force prevents the NTA from expiring before its\n\
full lifetime, even if the domain can validate sooner.\n\
nta -remove domain [view]\n\
Remove a negative trust anchor, re-enabling validation\n\
for the given domain.\n\
querylog [ on | off ]\n\
Enable / disable query logging.\n\
reconfig Reload configuration file and new zones only.\n\
recursing Dump the queries that are currently recursing (named.recursing)\n\
refresh zone [class [view]]\n\
Schedule immediate maintenance for a zone.\n\
reload Reload configuration file and zones.\n\
reload zone [class [view]]\n\
Reload a single zone.\n\
retransfer zone [class [view]]\n\
Retransfer a single zone without checking serial number.\n\
scan Scan available network interfaces for changes.\n\
secroots [view ...]\n\
Write security roots to the secroots file.\n\
showzone zone [class [view]]\n\
Print a zone's configuration.\n\
sign zone [class [view]]\n\
Update zone keys, and sign as needed.\n\
signing -clear all zone [class [view]]\n\
Remove the private records for all keys that have\n\
finished signing the given zone.\n\
signing -clear <keyid>/<algorithm> zone [class [view]]\n\
Remove the private record that indicating the given key\n\
has finished signing the given zone.\n\
signing -list zone [class [view]]\n\
List the private records showing the state of DNSSEC\n\
signing in the given zone.\n\
signing -nsec3param hash flags iterations salt zone [class [view]]\n\
Add NSEC3 chain to zone if already signed.\n\
Prime zone with NSEC3 chain if not yet signed.\n\
signing -nsec3param none zone [class [view]]\n\
Remove NSEC3 chains from zone.\n\
signing -serial <value> zone [class [view]]\n\
Set the zones's serial to <value>.\n\
stats Write server statistics to the statistics file.\n\
status Display status of the server.\n\
stop Save pending updates to master files and stop the server.\n\
stop -p Save pending updates to master files and stop the server\n\
reporting process id.\n\
sync [-clean] Dump changes to all dynamic zones to disk, and optionally\n\
remove their journal files.\n\
sync [-clean] zone [class [view]]\n\
Dump a single zone's changes to disk, and optionally\n\
remove its journal file.\n\
thaw Enable updates to all dynamic zones and reload them.\n\
thaw zone [class [view]]\n\
Enable updates to a frozen dynamic zone and reload it.\n\
trace Increment debugging level by one.\n\
trace level Change the debugging level.\n\
tsig-delete keyname [view]\n\
Delete a TKEY-negotiated TSIG key.\n\
tsig-list List all currently active TSIG keys, including both statically\n\
configured and TKEY-negotiated keys.\n\
validation [ yes | no | status ] [view]\n\
Enable / disable DNSSEC validation.\n\
zonestatus zone [class [view]]\n\
Display the current status of a zone.\n\
\n\
Version: %s\n",
}
static void
if (*host == '/') {
host);
if (result == ISC_R_SUCCESS)
nserveraddrs++;
} else {
nserveraddrs += found;
}
if (result != ISC_R_SUCCESS)
fatal("couldn't get address for '%s': %s",
INSIST(nserveraddrs > 0);
}
static void
sends--;
}
}
static void
recvs--;
fatal("connection to remote host closed\n"
"This may indicate that\n"
"* the remote server is using an older version of"
" the command protocol,\n"
"* this host is not authorized to connect,\n"
"* the clocks are not synchronized, or\n"
"* the key is invalid.");
DO("parse message",
if (!isccc_alist_alistp(data))
fatal("bad or missing data section in response");
if (result == ISC_R_SUCCESS) {
}
else if (result != ISC_R_NOTFOUND)
if (result == ISC_R_SUCCESS) {
} else if (result != ISC_R_NOTFOUND)
if (showresult) {
if (result == ISC_R_SUCCESS)
else
printf("NONE -1\n");
}
}
}
static void
isc_region_t r;
isc_buffer_t b;
recvs--;
fatal("connection to remote host closed\n"
"This may indicate that\n"
"* the remote server is using an older version of"
" the command protocol,\n"
"* this host is not authorized to connect,\n"
"* the clocks are not synchronized,\n"
"* the key signing algorithm is incorrect, or\n"
"* the key is invalid.");
DO("parse message",
if (!isccc_alist_alistp(_ctrl))
fatal("bad or missing ctrl section in response");
nonce = 0;
nonce = 0;
fatal("_data section missing");
fatal("out of memory");
if (nonce != 0) {
fatal("_ctrl section missing");
fatal("out of memory");
}
/* Skip the length field (4 bytes) */
DO("render message",
rndc_recvdone, NULL));
recvs++;
NULL));
sends++;
return;
}
static void
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_region_t r;
isc_buffer_t b;
connects--;
sizeof(socktext));
++currentaddr < nserveraddrs)
{
return;
} else
}
fatal("_data section missing");
fatal("out of memory");
/* Skip the length field (4 bytes) */
DO("render message",
rndc_recvnonce, NULL));
recvs++;
NULL));
sends++;
}
static void
int pf;
char socktext[ISC_SOCKADDR_FORMATSIZE];
else
switch (isc_sockaddr_pf(addr)) {
case AF_INET:
break;
case AF_INET6:
break;
default:
break;
}
NULL));
connects++;
}
static void
currentaddr = 0;
}
static void
{
const char *conffile = admin_conffile;
const cfg_listelt_t *elt;
const char *secretstr;
const char *algorithmstr;
static char secretarray[1024];
const cfg_listelt_t *element;
if (! isc_file_exists(conffile)) {
if (c_flag)
if (! isc_file_exists(conffile))
fatal("neither %s nor %s was found",
"default configuration file (%s)\n",
}
/*
* The parser will output its own errors, so DO() is not used.
*/
if (result != ISC_R_SUCCESS)
fatal("could not load rndc configuration");
if (!key_only)
servername = "127.0.0.1";
if (defserverobj != NULL)
}
if (servername == NULL)
fatal("no server specified and no default");
if (!key_only) {
{
const char *name;
break;
}
}
}
/*
* Look for the name of the key to use.
*/
; /* Was set on command line, do nothing. */
&defkey));
} else if (!key_only)
fatal("no key for server and no default");
/*
* Get the key's definition.
*/
if (key_only)
else {
{
keyname) == 0)
break;
}
}
fatal("key must have algorithm and secret");
#ifndef PK11_MD5_DISABLE
else
#endif
else
/*
* Find the port to connect to.
*/
if (remoteport != 0)
; /* Was set on command line, do nothing. */
else {
}
} else if (remoteport == 0)
else
if (result == ISC_R_SUCCESS) {
{
if (!cfg_obj_issockaddr(address)) {
unsigned int myport;
const char *name;
if (cfg_obj_isuint32(obj)) {
if (myport > ISC_UINT16_MAX ||
myport == 0)
fatal("port %u out of range",
myport);
} else
myport = remoteport;
if (nserveraddrs < SERVERADDRS)
else
"%s: dropped\n", name);
continue;
}
if (isc_sockaddr_getport(&sa) == 0)
if (nserveraddrs < SERVERADDRS)
else {
char socktext[ISC_SOCKADDR_FORMATSIZE];
sizeof(socktext));
"too many address: %s: dropped\n",
socktext);
}
}
}
}
}
}
}
}
}
}
}
}
int
char *p;
int ch;
int i;
if (result != ISC_R_SUCCESS)
result = isc_app_start();
if (result != ISC_R_SUCCESS)
!= -1) {
switch (ch) {
case 'b':
&in) == 1) {
&in6) == 1) {
}
break;
case 'c':
break;
case 'k':
break;
case 'M':
break;
case 'm':
break;
case 'p':
fatal("port '%s' out of range",
break;
case 'q':
break;
case 'r':
break;
case 's':
break;
case 'V':
break;
case 'y':
break;
case '?':
if (isc_commandline_option != '?') {
usage(1);
}
/* FALLTHROUGH */
case 'h':
usage(0);
break;
default:
exit(1);
}
}
if (argc < 1)
usage(1);
DO("creating log channel",
DO("allocate data buffer",
/*
* similar to what the user might enter in interactive mode
* (if that were implemented).
*/
argslen = 0;
for (i = 0; i < argc; i++)
p = args;
for (i = 0; i < argc; i++) {
p += len;
*p++ = ' ';
}
p--;
*p++ = '\0';
if (nserveraddrs == 0)
result = isc_app_run();
if (result != ISC_R_SUCCESS)
if (show_final_mem)
if (failed)
return (1);
return (0);
}