rndc.c revision 784a904bd06c7492361ed09a882d10c636b1291b
/*
* Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc.c,v 1.133 2011/02/03 12:18:10 tbox Exp $ */
/*! \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 unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
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] [-V] command\n\
\n\
command is one of the following:\n\
\n\
reload Reload configuration file and zones.\n\
reload zone [class [view]]\n\
Reload a single zone.\n\
refresh zone [class [view]]\n\
Schedule immediate maintenance for a zone.\n\
retransfer zone [class [view]]\n\
Retransfer a single zone without checking serial number.\n\
freeze Suspend updates to all dynamic zones.\n\
freeze zone [class [view]]\n\
Suspend updates to a dynamic zone.\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\
notify zone [class [view]]\n\
Resend NOTIFY messages for the zone.\n\
reconfig Reload configuration file and new zones only.\n\
sign zone [class [view]]\n\
Update zone keys, and sign as needed.\n\
loadkeys zone [class [view]]\n\
Update keys without signing immediately.\n\
stats Write server statistics to the statistics file.\n\
querylog Toggle query logging.\n\
dumpdb [-all|-cache|-zones] [view ...]\n\
Dump cache(s) to the dump file (named_dump.db).\n\
secroots [view ...]\n\
Write security roots to the secroots file.\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\
halt Stop the server without saving pending updates.\n\
halt -p Stop the server without saving pending updates reporting\n\
process id.\n\
trace Increment debugging level by one.\n\
trace level Change the debugging level.\n\
notrace Set debugging level to 0.\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\
status Display status of the server.\n\
recursing Dump the queries that are currently recursing (named.recursing)\n\
validation newstate [view]\n\
Enable / disable DNSSEC validation.\n\
*restart Restart the server.\n\
addzone [\"file\"] zone [class [view]] { zone-options }\n\
Add zone to given view. Requires new-zone-file option.\n\
delzone [\"file\"] zone [class [view]]\n\
Removes zone from given view. Requires new-zone-file option.\n\
\n\
* == not yet implemented\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.");
fatal("no 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)
}
}
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, or\n"
"* the key is invalid.");
fatal("_ctrl section missing");
nonce = 0;
nonce = 0;
fatal("_data section missing");
fatal("out of memory");
if (nonce != 0) {
fatal("_ctrl section missing");
fatal("out of memory");
}
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");
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 *algorithm;
static char secretarray[1024];
const cfg_listelt_t *element;
if (! isc_file_exists(conffile)) {
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");
/*
* 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 's':
break;
case 'V':
break;
case 'y':
break;
case '?':
if (isc_commandline_option != '?') {
usage(1);
}
case 'h':
usage(0);
break;
default:
exit(1);
}
}
if (argc < 1)
usage(1);
DO("creating log channel",
/*
* 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);
}