nsupdate.c revision e02fa56849131911e9554133b17a5325b37d0828
ca41b452ede6feaa9d8739ec3cae19389a7b0d03Bob Halley * Copyright (C) 2000-2017 Internet Systems Consortium, Inc. ("ISC")
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * This Source Code Form is subject to the terms of the Mozilla Public
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * License, v. 2.0. If a copy of the MPL was not distributed with this
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * file, You can obtain one at http://mozilla.org/MPL/2.0/.
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley/* Number of addresses to request from bind9_getaddresses() */
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic isc_boolean_t debugging = ISC_FALSE, ddebugging = ISC_FALSE;
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halleystatic isc_boolean_t use_win2k_gsstsig = ISC_FALSE;
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halleystatic isc_boolean_t tried_other_gsstsig = ISC_FALSE;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int ns_inuse = 0;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int master_inuse = 0;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int ns_total = 0;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int ns_alloc = 0;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int master_total = 0;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic int master_alloc = 0;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleystatic int requests = 0;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleystatic unsigned int logdebuglevel = 0;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleystatic dns_rdataclass_t defaultclass = dns_rdataclass_in;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleystatic dns_rdataclass_t zoneclass = dns_rdataclass_none;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleytypedef struct nsu_requestinfo {
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleysendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleysend_update(dns_name_t *zonename, isc_sockaddr_t *master);
bed86971bf7eb315e9c64f75bba331917f4557cfBob HalleyISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleydebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graffddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halleytypedef struct nsu_gssinfo {
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleysend_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley#endif /* GSSAPI */
a829555ed724caa56b1ff7716d7eda2266491eafBob Halleyerror(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleysetup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley result = isc_entropy_usebestsource(*ectx, &source, randomfile,
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley isc_mem_put(source->mctx, source, sizeof(*source));
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrence if (master_servers != NULL && master_servers != servers)
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic inline void
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleycheck_result(isc_result_t result, const char *msg) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleystatic void *
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleystatic char *
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley const char *d;
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley *s++ = '\0';
&updatemsg);
if (usegsstsig) {
static isc_boolean_t
return (ISC_FALSE);
#ifndef PK11_MD5_DISABLE
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
return (len);
setup_keystr(void) {
int secretlen;
char *secretstr;
char *name;
if (n != NULL) {
#ifndef PK11_MD5_DISABLE
NULL);
goto failure;
&tsigkey);
* Get a key from a named.conf format keyfile
static isc_result_t
const char *mykeyname;
const char *secretstr;
const char *algorithm;
int len;
return (ISC_R_FILENOTFOUND);
goto cleanup;
&sessionkey);
goto cleanup;
goto cleanup;
setup_keystr();
return (result);
&dstkey);
#ifndef PK11_MD5_DISABLE
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
case DST_ALG_HMACSHA256:
case DST_ALG_HMACSHA384:
case DST_ALG_HMACSHA512:
&tsigkey);
doshutdown(void) {
if (is_dst_up) {
if (have_ipv4)
if (have_ipv6)
maybeshutdown(void) {
if (requests != 0)
doshutdown();
setup_system(void) {
ns_inuse = 0;
if (have_ipv4) {
if (have_ipv6) {
for (i = 0; i < ns_total; i++) {
if (have_ipv6) {
if (have_ipv4) {
setup_keystr();
else if (local_only) {
int count = 0;
return (count);
version(void) {
int ch;
switch (ch) {
if (dns_rdatatype_ismeta(t))
if (dns_rdatatype_ismeta(t))
version();
if (doexit)
exit(0);
int ch;
isc_uint32_t i;
switch (ch) {
logdebuglevel = i;
if (timeout == 0)
if (udp_timeout == 0)
argv[0]);
#ifdef GSSAPI
argv[0]);
if (usegsstsig) {
argv[0]);
if (!force_interactive) {
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
isc_region_t r;
return (STATUS_MORE);
cmdline++;
if (*cmdline != 0) {
&callbacks);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
char *word;
return (retval);
if (isrrset) {
goto failure;
goto failure;
goto failure;
goto failure;
goto failure;
goto failure;
if (ispositive) {
return (STATUS_MORE);
return (STATUS_SYNTAX);
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
static isc_uint16_t
long port;
if (local_only) {
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
char *endp;
if (*endp != 0) {
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
ns_inuse = 0;
if (ns_total == 0) {
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
long port;
return (STATUS_SYNTAX);
port = 0;
char *endp;
if (*endp != 0) {
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
char *namestr;
char *secretstr;
isc_buffer_t b;
int secretlen;
return (STATUS_SYNTAX);
if (n != NULL) {
&digestbits)) {
return (STATUS_SYNTAX);
#ifndef PK11_MD5_DISABLE
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
&tsigkey);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
char *word;
isc_buffer_t b;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
#ifdef GSSAPI
char *word;
return (STATUS_MORE);
return (STATUS_SYNTAX);
return (STATUS_MORE);
return (STATUS_SYNTAX);
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
default_ttl = 0;
return (STATUS_MORE);
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
switch (rdclass) {
case dns_rdataclass_none:
case dns_rdataclass_any:
case dns_rdataclass_reserved0:
return (STATUS_SYNTAX);
return (STATUS_MORE);
static isc_uint16_t
char *word;
return (retval);
if (!isdelete) {
goto failure;
ttl = 0;
goto doneparsing;
if (isdelete) {
ttl = 0;
goto parseclass;
} else if (default_ttl_set) {
goto parseclass;
goto failure;
if (isdelete)
ttl = 0;
goto failure;
if (isdelete) {
goto doneparsing;
goto failure;
goto failure;
if (isdelete) {
goto doneparsing;
goto failure;
goto failure;
goto failure;
rdata);
goto failure;
if (isdelete) {
goto failure;
ISC_TRUE))
namebuf);
goto failure;
namebuf);
goto failure;
return (STATUS_MORE);
return (STATUS_SYNTAX);
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
static isc_uint16_t
char *word;
return (STATUS_SYNTAX);
return (STATUS_SYNTAX);
return (STATUS_MORE);
int bufsz;
static isc_uint16_t
char *word;
return (STATUS_SEND);
return (STATUS_MORE);
return (STATUS_QUIT);
return (STATUS_SEND);
if (debugging)
return (STATUS_MORE);
return (STATUS_MORE);
return (STATUS_MORE);
#ifdef GSSAPI
return (STATUS_MORE);
#ifdef GSSAPI
return (STATUS_MORE);
return (STATUS_MORE);
return (STATUS_MORE);
return (STATUS_SYNTAX);
static isc_uint16_t
get_next_command(void) {
char *cmdline;
if (interactive) {
#ifdef HAVE_READLINE
#ifdef HAVE_READLINE
if (interactive)
return (result);
static isc_boolean_t
user_interaction(void) {
return (ISC_TRUE);
return (ISC_FALSE);
done_update(void) {
static isc_boolean_t
return (ISC_FALSE);
return (ISC_TRUE);
requests--;
if (shuttingdown) {
goto done;
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_CLOCKSKEW:
case DNS_R_EXPECTEDTSIG:
case DNS_R_TSIGERRORSET:
case DNS_R_TSIGVERIFYFAILURE:
case DNS_R_UNEXPECTEDTSIG:
case ISC_R_FAILURE:
if (!debugging) {
isc_buffer_t b;
if (debugging)
done:
if (usegsstsig) {
done_update();
if (usevc)
if (debugging) {
if (debugging)
requests++;
int pass = 0;
unsigned int nlabels;
requests--;
if (shuttingdown) {
&request);
requests++;
if (debugging)
namebuf);
done_update();
if (pass == 0)
goto droplabel;
pass++;
goto lookforsoa;
&soaset);
pass++;
goto lookforsoa;
if (seencname)
goto droplabel;
if (debugging) {
if (debugging) {
if (default_servers) {
if (master_total == 0) {
master_inuse = 0;
#ifdef GSSAPI
if (usegsstsig) {
out:
goto out;
requests++;
#ifdef GSSAPI
char *name;
const char * ticket_realm;
if (rc != 0)
if (rc != 0) {
if (rc != 0) {
if (rc != 0) {
done_update();
goto failure;
unsigned int options = 0;
if (debugging)
requests++;
requests--;
if (shuttingdown) {
sizeof(isc_sockaddr_t));
if (debugging)
if (use_win2k_gsstsig)
goto done;
switch (result) {
case DNS_R_CONTINUE:
case ISC_R_SUCCESS:
done:
start_update(void) {
&soaquery);
if (default_servers)
done_update();
ns_inuse = 0;
cleanup(void) {
#ifdef GSSAPI
if (memdebugging)
if (shuttingdown) {
reset_system();
if (!more) {
start_update();
setup_system();
(void)isc_app_run();
cleanup();
if (seenerror)