diff options
| author | Doug Barton <dougb@FreeBSD.org> | 2009-05-31 00:11:36 +0000 |
|---|---|---|
| committer | Doug Barton <dougb@FreeBSD.org> | 2009-05-31 00:11:36 +0000 |
| commit | b0e69f719c1db2c19fcfba96f0dac9a5a2277350 (patch) | |
| tree | 72d567a9bc3fb8adcfcbaa9baedc122d53071209 /bin/nsupdate | |
| parent | fe9c1406ede29d1f2b9969c75785beef87a4bf87 (diff) | |
Notes
Diffstat (limited to 'bin/nsupdate')
| -rw-r--r-- | bin/nsupdate/Makefile.in | 8 | ||||
| -rw-r--r-- | bin/nsupdate/nsupdate.1 | 51 | ||||
| -rw-r--r-- | bin/nsupdate/nsupdate.c | 752 | ||||
| -rw-r--r-- | bin/nsupdate/nsupdate.docbook | 107 | ||||
| -rw-r--r-- | bin/nsupdate/nsupdate.html | 103 |
5 files changed, 843 insertions, 178 deletions
diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in index 713ec30b60f71..6d65697810e25 100644 --- a/bin/nsupdate/Makefile.in +++ b/bin/nsupdate/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2008 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.22.18.3 2008/08/29 23:46:16 tbox Exp $ +# $Id: Makefile.in,v 1.29 2008/08/29 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -24,9 +24,9 @@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISC_INCLUDES} + ${ISC_INCLUDES} @DST_GSSAPI_INC@ -CDEFINES = +CDEFINES = @USE_GSSAPI@ CWARNINGS = LWRESLIBS = ../../lib/lwres/liblwres.@A@ diff --git a/bin/nsupdate/nsupdate.1 b/bin/nsupdate/nsupdate.1 index 454f50560f203..b0688a3ac2630 100644 --- a/bin/nsupdate/nsupdate.1 +++ b/bin/nsupdate/nsupdate.1 @@ -1,4 +1,4 @@ -.\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and distribute this software for any @@ -13,7 +13,7 @@ .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" -.\" $Id: nsupdate.1,v 1.1.4.2 2008/09/01 02:29:00 tbox Exp $ +.\" $Id: nsupdate.1,v 1.3.48.2 2009/03/10 01:54:11 tbox Exp $ .\" .hy 0 .ad l @@ -33,7 +33,7 @@ nsupdate \- Dynamic DNS update utility .SH "SYNOPSIS" .HP 9 -\fBnsupdate\fR [\fB\-d\fR] [[\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-v\fR] [filename] +\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename] .SH "DESCRIPTION" .PP \fBnsupdate\fR @@ -53,7 +53,14 @@ option makes \fBnsupdate\fR operate in debug mode. This provides tracing information about the update requests that are made and the replies received from the name server. .PP -Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931. TSIG relies on a shared secret that should only be known to +The +\fB\-D\fR +option makes +\fBnsupdate\fR +report additional debugging information to +\fB\-d\fR. +.PP +Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931 or GSS\-TSIG as described in RFC3645. TSIG relies on a shared secret that should only be known to \fBnsupdate\fR and the name server. Currently, the only supported encryption algorithm for TSIG is HMAC\-MD5, which is defined in RFC 2104. Once other algorithms are defined for TSIG, applications will need to ensure they select the appropriate algorithm as well as the key when authenticating each other. For instance, suitable \fBkey\fR @@ -64,7 +71,7 @@ statements would be added to so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server. \fBnsupdate\fR does not read -\fI/etc/named.conf\fR. +\fI/etc/named.conf\fR. GSS\-TSIG uses Kerberos credentials. .PP \fBnsupdate\fR uses the @@ -96,7 +103,15 @@ The \fB\-k\fR may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key. .PP -By default +The +\fB\-g\fR +and +\fB\-o\fR +specify that GSS\-TSIG is to be used. The +\fB\-o\fR +should only be used with old Microsoft Windows 2000 servers. +.PP +By default, \fBnsupdate\fR uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. The \fB\-v\fR @@ -115,6 +130,16 @@ option sets the UDP retry interval. The default is 3 seconds. If zero, the inter The \fB\-r\fR option sets the number of UDP retries. The default is 3. If zero, only one update request will be made. +.PP +The +\fB\-R \fR\fB\fIrandomdev\fR\fR +option specifies a source of randomness. If the operating system does not provide a +\fI/dev/random\fR +or equivalent device, the default source of randomness is keyboard input. +\fIrandomdev\fR +specifies the name of a character device or file containing random data to be used instead of the default. The special value +\fIkeyboard\fR +indicates that keyboard input should be used. This option may be specified multiple times. .SH "INPUT FORMAT" .PP \fBnsupdate\fR @@ -168,6 +193,13 @@ is specified, the default class is \fIIN\fR. .RE .PP +\fBttl\fR {seconds} +.RS 4 +Specify the default time to live for records to be added. The value +\fInone\fR +will clear the default ttl. +.RE +.PP \fBkey\fR {name} {secret} .RS 4 Specifies that all updates are to be TSIG\-signed using the @@ -271,6 +303,11 @@ Sends the current message. This is equivalent to entering a blank line. Displays the answer. .RE .PP +\fBdebug\fR +.RS 4 +Turn on debugging. +.RE +.PP Lines beginning with a semicolon are comments and are ignored. .SH "EXAMPLES" .PP @@ -342,7 +379,7 @@ base\-64 encoding of HMAC\-MD5 key created by .PP The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases. .SH "COPYRIGHT" -Copyright \(co 2004\-2008 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 88749e64f9571..6cf4cf42ea3ca 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsupdate.c,v 1.130.18.22 2008/01/17 23:45:58 tbox Exp $ */ +/* $Id: nsupdate.c,v 1.163.48.3 2009/04/30 07:12:49 marka Exp $ */ /*! \file */ @@ -35,8 +35,10 @@ #include <isc/event.h> #include <isc/hash.h> #include <isc/lex.h> +#include <isc/log.h> #include <isc/mem.h> #include <isc/parseint.h> +#include <isc/random.h> #include <isc/region.h> #include <isc/sockaddr.h> #include <isc/socket.h> @@ -52,6 +54,7 @@ #include <dns/dnssec.h> #include <dns/events.h> #include <dns/fixedname.h> +#include <dns/log.h> #include <dns/masterdump.h> #include <dns/message.h> #include <dns/name.h> @@ -64,6 +67,7 @@ #include <dns/rdatatype.h> #include <dns/request.h> #include <dns/result.h> +#include <dns/tkey.h> #include <dns/tsig.h> #include <dst/dst.h> @@ -71,8 +75,12 @@ #include <lwres/lwres.h> #include <lwres/net.h> +#ifdef GSSAPI +#include <dst/gssapi.h> +#endif #include <bind9/getaddresses.h> + #ifdef HAVE_ADDRINFO #ifdef HAVE_GETADDRINFO #ifdef HAVE_GAISTRERROR @@ -107,9 +115,13 @@ static isc_boolean_t have_ipv4 = ISC_FALSE; static isc_boolean_t have_ipv6 = ISC_FALSE; static isc_boolean_t is_dst_up = ISC_FALSE; static isc_boolean_t usevc = ISC_FALSE; +static isc_boolean_t usegsstsig = ISC_FALSE; +static isc_boolean_t use_win2k_gsstsig = ISC_FALSE; +static isc_boolean_t tried_other_gsstsig = ISC_FALSE; static isc_taskmgr_t *taskmgr = NULL; static isc_task_t *global_task = NULL; static isc_event_t *global_event = NULL; +static isc_log_t *lctx = NULL; static isc_mem_t *mctx = NULL; static dns_dispatchmgr_t *dispatchmgr = NULL; static dns_requestmgr_t *requestmgr = NULL; @@ -120,6 +132,10 @@ static dns_dispatch_t *dispatchv6 = NULL; static dns_message_t *updatemsg = NULL; static dns_fixedname_t fuserzone; static dns_name_t *userzone = NULL; +static dns_name_t *zonename = NULL; +static dns_name_t tmpzonename; +static dns_name_t restart_master; +static dns_tsig_keyring_t *gssring = NULL; static dns_tsigkey_t *tsigkey = NULL; static dst_key_t *sig0key; static lwres_context_t *lwctx = NULL; @@ -129,20 +145,25 @@ static int ns_inuse = 0; static int ns_total = 0; static isc_sockaddr_t *userserver = NULL; static isc_sockaddr_t *localaddr = NULL; +static isc_sockaddr_t *serveraddr = NULL; +static isc_sockaddr_t tempaddr; static char *keystr = NULL, *keyfile = NULL; -static isc_entropy_t *entp = NULL; +static isc_entropy_t *entropy = NULL; static isc_boolean_t shuttingdown = ISC_FALSE; static FILE *input; static isc_boolean_t interactive = ISC_TRUE; static isc_boolean_t seenerror = ISC_FALSE; static const dns_master_style_t *style; static int requests = 0; +static unsigned int logdebuglevel = 0; static unsigned int timeout = 300; static unsigned int udp_timeout = 3; static unsigned int udp_retries = 3; static dns_rdataclass_t defaultclass = dns_rdataclass_in; static dns_rdataclass_t zoneclass = dns_rdataclass_none; static dns_message_t *answer = NULL; +static isc_uint32_t default_ttl = 0; +static isc_boolean_t default_ttl_set = ISC_FALSE; typedef struct nsu_requestinfo { dns_message_t *msg; @@ -161,6 +182,27 @@ debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); static void ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); +#ifdef GSSAPI +static dns_fixedname_t fkname; +static isc_sockaddr_t *kserver = NULL; +static char servicename[DNS_NAME_FORMATSIZE]; +static dns_name_t *keyname; +typedef struct nsu_gssinfo { + dns_message_t *msg; + isc_sockaddr_t *addr; + gss_ctx_id_t context; +} nsu_gssinfo_t; + +static void +start_gssrequest(dns_name_t *master); +static void +send_gssrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, + dns_message_t *msg, dns_request_t **request, + gss_ctx_id_t context); +static void +recvgss(isc_task_t *task, isc_event_t *event); +#endif /* GSSAPI */ + static void error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); @@ -169,6 +211,69 @@ error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); #define STATUS_QUIT (isc_uint16_t)2 #define STATUS_SYNTAX (isc_uint16_t)3 +typedef struct entropysource entropysource_t; + +struct entropysource { + isc_entropysource_t *source; + isc_mem_t *mctx; + ISC_LINK(entropysource_t) link; +}; + +static ISC_LIST(entropysource_t) sources; + +static void +setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) +{ + isc_result_t result; + isc_entropysource_t *source = NULL; + entropysource_t *elt; + int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; + + REQUIRE(ectx != NULL); + + if (*ectx == NULL) { + result = isc_entropy_create(mctx, ectx); + if (result != ISC_R_SUCCESS) + fatal("could not create entropy object"); + ISC_LIST_INIT(sources); + } + + if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { + usekeyboard = ISC_ENTROPY_KEYBOARDYES; + randomfile = NULL; + } + + result = isc_entropy_usebestsource(*ectx, &source, randomfile, + usekeyboard); + + if (result != ISC_R_SUCCESS) + fatal("could not initialize entropy source: %s", + isc_result_totext(result)); + + if (source != NULL) { + elt = isc_mem_get(mctx, sizeof(*elt)); + if (elt == NULL) + fatal("out of memory"); + elt->source = source; + elt->mctx = mctx; + ISC_LINK_INIT(elt, link); + ISC_LIST_APPEND(sources, elt, link); + } +} + +static void +cleanup_entropy(isc_entropy_t **ectx) { + entropysource_t *source; + while (!ISC_LIST_EMPTY(sources)) { + source = ISC_LIST_HEAD(sources); + ISC_LIST_UNLINK(sources, source, link); + isc_entropy_destroysource(&source->source); + isc_mem_put(source->mctx, source, sizeof(*source)); + } + isc_entropy_detach(ectx); +} + + static dns_rdataclass_t getzoneclass(void) { if (zoneclass == dns_rdataclass_none) @@ -295,6 +400,13 @@ reset_system(void) { check_result(result, "dns_message_create"); } updatemsg->opcode = dns_opcode_update; + if (usegsstsig) { + if (tsigkey != NULL) + dns_tsigkey_detach(&tsigkey); + if (gssring != NULL) + dns_tsigkeyring_destroy(&gssring); + tried_other_gsstsig = ISC_FALSE; + } } static isc_uint16_t @@ -518,10 +630,7 @@ doshutdown(void) { is_dst_up = ISC_FALSE; } - if (entp != NULL) { - ddebug("Detach from entropy"); - isc_entropy_detach(&entp); - } + cleanup_entropy(&entropy); lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); @@ -572,6 +681,7 @@ setup_system(void) { lwres_result_t lwresult; unsigned int attrs, attrmask; int i; + isc_logconfig_t *logconfig = NULL; ddebug("setup_system()"); @@ -588,8 +698,17 @@ setup_system(void) { if (!have_ipv4 && !have_ipv6) fatal("could not find either IPv4 or IPv6"); - result = isc_mem_create(0, 0, &mctx); - check_result(result, "isc_mem_create"); + result = isc_log_create(mctx, &lctx, &logconfig); + check_result(result, "isc_log_create"); + + isc_log_setcontext(lctx); + dns_log_init(lctx); + dns_log_setcontext(lctx); + + result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); + check_result(result, "isc_log_usechannel"); + + isc_log_setdebuglevel(lctx, logdebuglevel); lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); if (lwresult != LWRES_R_SUCCESS) @@ -626,14 +745,13 @@ setup_system(void) { } } - result = isc_entropy_create(mctx, &entp); - check_result(result, "isc_entropy_create"); + setup_entropy(mctx, NULL, &entropy); - result = isc_hash_create(mctx, entp, DNS_NAME_MAXWIRE); + result = isc_hash_create(mctx, entropy, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); isc_hash_init(); - result = dns_dispatchmgr_create(mctx, entp, &dispatchmgr); + result = dns_dispatchmgr_create(mctx, entropy, &dispatchmgr); check_result(result, "dns_dispatchmgr_create"); result = isc_socketmgr_create(mctx, &socketmgr); @@ -651,7 +769,7 @@ setup_system(void) { result = isc_task_onshutdown(global_task, shutdown_program, NULL); check_result(result, "isc_task_onshutdown"); - result = dst_lib_init(mctx, entp, 0); + result = dst_lib_init(mctx, entropy, 0); check_result(result, "dst_lib_init"); is_dst_up = ISC_TRUE; @@ -707,14 +825,47 @@ get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { INSIST(count == 1); } +#define PARSE_ARGS_FMT "dDMl:y:govk:rR::t:u:" + +static void +pre_parse_args(int argc, char **argv) { + int ch; + + while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { + switch (ch) { + case 'M': /* was -dm */ + debugging = ISC_TRUE; + ddebugging = ISC_TRUE; + memdebugging = ISC_TRUE; + isc_mem_debugging = ISC_MEM_DEBUGTRACE | + ISC_MEM_DEBUGRECORD; + break; + + case '?': + if (isc_commandline_option != '?') + fprintf(stderr, "%s: invalid argument -%c\n", + argv[0], isc_commandline_option); + fprintf(stderr, "usage: nsupdate [-d] " + "[-g | -o | -y keyname:secret | -k keyfile] " + "[-v] [filename]\n"); + exit(1); + + default: + break; + } + } + isc_commandline_reset = ISC_TRUE; + isc_commandline_index = 1; +} + static void -parse_args(int argc, char **argv) { +parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) { int ch; + isc_uint32_t i; isc_result_t result; debug("parse_args"); - while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1) - { + while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { switch (ch) { case 'd': debugging = ISC_TRUE; @@ -723,12 +874,17 @@ parse_args(int argc, char **argv) { debugging = ISC_TRUE; ddebugging = ISC_TRUE; break; - case 'M': /* was -dm */ - debugging = ISC_TRUE; - ddebugging = ISC_TRUE; - memdebugging = ISC_TRUE; - isc_mem_debugging = ISC_MEM_DEBUGTRACE | - ISC_MEM_DEBUGRECORD; + case 'M': + break; + case 'l': + result = isc_parse_uint32(&i, isc_commandline_argument, + 10); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "bad library debug value " + "'%s'\n", isc_commandline_argument); + exit(1); + } + logdebuglevel = i; break; case 'y': keystr = isc_commandline_argument; @@ -739,6 +895,14 @@ parse_args(int argc, char **argv) { case 'k': keyfile = isc_commandline_argument; break; + case 'g': + usegsstsig = ISC_TRUE; + use_win2k_gsstsig = ISC_FALSE; + break; + case 'o': + usegsstsig = ISC_TRUE; + use_win2k_gsstsig = ISC_TRUE; + break; case 't': result = isc_parse_uint32(&timeout, isc_commandline_argument, 10); @@ -767,12 +931,14 @@ parse_args(int argc, char **argv) { exit(1); } break; + + case 'R': + setup_entropy(mctx, isc_commandline_argument, ectx); + break; + default: - fprintf(stderr, "%s: invalid argument -%c\n", - argv[0], ch); - fprintf(stderr, "usage: nsupdate [-d] " - "[-y keyname:secret | -k keyfile] [-v] " - "[filename]\n"); + fprintf(stderr, "%s: unhandled option: %c\n", + argv[0], isc_commandline_option); exit(1); } } @@ -782,6 +948,21 @@ parse_args(int argc, char **argv) { exit(1); } +#ifdef GSSAPI + if (usegsstsig && (keyfile != NULL || keystr != NULL)) { + fprintf(stderr, "%s: cannot specify -g with -k or -y\n", + argv[0]); + exit(1); + } +#else + if (usegsstsig) { + fprintf(stderr, "%s: cannot specify -g or -o, " \ + "program not linked with GSS API Library\n", + argv[0]); + exit(1); + } +#endif + if (argv[isc_commandline_index] != NULL) { if (strcmp(argv[isc_commandline_index], "-") == 0) { input = stdin; @@ -853,7 +1034,7 @@ parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass, check_result(result, "isc_lex_openbuffer"); result = isc_buffer_allocate(mctx, &buf, MAXWIRE); check_result(result, "isc_buffer_allocate"); - result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, + result = dns_rdata_fromtext(NULL, rdataclass, rdatatype, lex, dns_rootname, 0, mctx, buf, &callbacks); isc_lex_destroy(&lex); @@ -947,8 +1128,7 @@ make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) { result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); - rdata->data = NULL; - rdata->length = 0; + dns_rdata_init(rdata); if (isrrset && ispositive) { retval = parse_rdata(&cmdline, rdataclass, rdatatype, @@ -1209,6 +1389,39 @@ evaluate_zone(char *cmdline) { } static isc_uint16_t +evaluate_ttl(char *cmdline) { + char *word; + isc_result_t result; + isc_uint32_t ttl; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not ttl\n"); + return (STATUS_SYNTAX); + } + + if (!strcasecmp(word, "none")) { + default_ttl = 0; + default_ttl_set = ISC_FALSE; + return (STATUS_MORE); + } + + result = isc_parse_uint32(&ttl, word, 10); + if (result != ISC_R_SUCCESS) + return (STATUS_SYNTAX); + + if (ttl > TTL_MAX) { + fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", + word, TTL_MAX); + return (STATUS_SYNTAX); + } + default_ttl = ttl; + default_ttl_set = ISC_TRUE; + + return (STATUS_MORE); +} + +static isc_uint16_t evaluate_class(char *cmdline) { char *word; isc_textregion_t r; @@ -1267,10 +1480,7 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) { result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); - rdata->rdclass = 0; - rdata->type = 0; - rdata->data = NULL; - rdata->length = 0; + dns_rdata_init(rdata); /* * If this is an add, read the TTL and verify that it's in range. @@ -1295,6 +1505,9 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) { if (isdelete) { ttl = 0; goto parseclass; + } else if (default_ttl_set) { + ttl = default_ttl; + goto parseclass; } else { fprintf(stderr, "ttl '%s': %s\n", word, isc_result_totext(result)); @@ -1328,8 +1541,9 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) { } region.base = word; region.length = strlen(word); + rdataclass = dns_rdataclass_any; result = dns_rdataclass_fromtext(&rdataclass, ®ion); - if (result == ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS && rdataclass != dns_rdataclass_any) { if (!setzoneclass(rdataclass)) { fprintf(stderr, "class mismatch: %s\n", word); goto failure; @@ -1469,7 +1683,7 @@ setzone(dns_name_t *zonename) { } static void -show_message(dns_message_t *msg) { +show_message(FILE *stream, dns_message_t *msg, const char *description) { isc_result_t result; isc_buffer_t *buf = NULL; int bufsz; @@ -1497,9 +1711,8 @@ show_message(dns_message_t *msg) { isc_buffer_free(&buf); return; } - printf("Outgoing update query:\n%.*s", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); + fprintf(stream, "%s\n%.*s", description, + (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf)); isc_buffer_free(&buf); } @@ -1544,17 +1757,68 @@ get_next_command(void) { return (evaluate_class(cmdline)); if (strcasecmp(word, "send") == 0) return (STATUS_SEND); + if (strcasecmp(word, "debug") == 0) { + if (debugging) + ddebugging = ISC_TRUE; + else + debugging = ISC_TRUE; + return (STATUS_MORE); + } + if (strcasecmp(word, "ttl") == 0) + return (evaluate_ttl(cmdline)); if (strcasecmp(word, "show") == 0) { - show_message(updatemsg); + show_message(stdout, updatemsg, "Outgoing update query:"); return (STATUS_MORE); } if (strcasecmp(word, "answer") == 0) { if (answer != NULL) - show_message(answer); + show_message(stdout, answer, "Answer:"); return (STATUS_MORE); } - if (strcasecmp(word, "key") == 0) + if (strcasecmp(word, "key") == 0) { + usegsstsig = ISC_FALSE; return (evaluate_key(cmdline)); + } + if (strcasecmp(word, "gsstsig") == 0) { +#ifdef GSSAPI + usegsstsig = ISC_TRUE; + use_win2k_gsstsig = ISC_FALSE; +#else + fprintf(stderr, "gsstsig not supported\n"); +#endif + return (STATUS_MORE); + } + if (strcasecmp(word, "oldgsstsig") == 0) { +#ifdef GSSAPI + usegsstsig = ISC_TRUE; + use_win2k_gsstsig = ISC_TRUE; +#else + fprintf(stderr, "gsstsig not supported\n"); +#endif + return (STATUS_MORE); + } + if (strcasecmp(word, "help") == 0) { + fprintf(stdout, +"local address [port] (set local resolver)\n" +"server address [port] (set master server for zone)\n" +"send (send the update request)\n" +"show (show the update request)\n" +"answer (show the answer to the last request)\n" +"quit (quit, any pending update is not sent\n" +"help (display this message_\n" +"key [hmac:]keyname secret (use TSIG to sign the request)\n" +"gsstsig (use GSS_TSIG to sign the request)\n" +"oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n" +"zone name (set the zone to be updated)\n" +"class CLASS (set the zone's DNS class, e.g. IN (default), CH)\n" +"prereq nxdomain name (does this name not exist)\n" +"prereq yxdomain name (does this name exist)\n" +"prereq nxrrset .... (does this RRset exist)\n" +"prereq yxrrset .... (does this RRset not exist)\n" +"update add .... (add the given record to the zone)\n" +"update delete .... (remove the given record(s) from the zone)\n"); + return (STATUS_MORE); + } fprintf(stderr, "incorrect section name: %s\n", word); return (STATUS_SYNTAX); } @@ -1641,12 +1905,23 @@ update_completed(isc_task_t *task, isc_event_t *event) { DNS_MESSAGEPARSE_PRESERVEORDER); switch (result) { case ISC_R_SUCCESS: + if (answer->verify_attempted) + ddebug("tsig verification successful"); break; 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 0 + if (usegsstsig && answer->rcode == dns_rcode_noerror) { + /* + * For MS DNS that violates RFC 2845, section 4.2 + */ + break; + } +#endif fprintf(stderr, "; TSIG error with server: %s\n", isc_result_totext(result)); seenerror = ISC_TRUE; @@ -1672,32 +1947,15 @@ update_completed(isc_task_t *task, isc_event_t *event) { (int)isc_buffer_usedlength(&b), buf); } } - if (debugging) { - isc_buffer_t *buf = NULL; - int bufsz; + if (debugging) + show_message(stderr, answer, "\nReply from update query:"); - bufsz = INITTEXT; - do { - if (bufsz > MAXTEXT) { - fprintf(stderr, "could not allocate large " - "enough buffer to display message\n"); - exit(1); - } - if (buf != NULL) - isc_buffer_free(&buf); - result = isc_buffer_allocate(mctx, &buf, bufsz); - check_result(result, "isc_buffer_allocate"); - result = dns_message_totext(answer, style, 0, buf); - bufsz *= 2; - } while (result == ISC_R_NOSPACE); - check_result(result, "dns_message_totext"); - fprintf(stderr, "\nReply from update query:\n%.*s\n", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); - isc_buffer_free(&buf); - } done: dns_request_destroy(&request); + if (usegsstsig) { + dns_name_free(&tmpzonename, mctx); + dns_name_free(&restart_master, mctx); + } isc_event_free(&event); done_update(); } @@ -1726,6 +1984,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master, isc_sockaddr_format(master, addrbuf, sizeof(addrbuf)); fprintf(stderr, "Sending update to %s\n", addrbuf); } + result = dns_request_createvia3(requestmgr, updatemsg, srcaddr, master, options, tsigkey, timeout, udp_timeout, udp_retries, global_task, @@ -1733,7 +1992,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master, check_result(result, "dns_request_createvia3"); if (debugging) - show_message(updatemsg); + show_message(stdout, updatemsg, "Outgoing update query:"); requests++; } @@ -1751,8 +2010,6 @@ recvsoa(isc_task_t *task, isc_event_t *event) { dns_rdata_t soarr = DNS_RDATA_INIT; int pass = 0; dns_name_t master; - isc_sockaddr_t *serveraddr, tempaddr; - dns_name_t *zonename; nsu_requestinfo_t *reqinfo; dns_message_t *soaquery = NULL; isc_sockaddr_t *addr; @@ -1788,7 +2045,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) { isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); fprintf(stderr, "; Communication with %s failed: %s\n", - addrbuf, isc_result_totext(eresult)); + addrbuf, isc_result_totext(eresult)); if (userserver != NULL) fatal("could not talk to specified name server"); else if (++ns_inuse >= lwconf->nsnext) @@ -1837,28 +2094,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) { } check_result(result, "dns_request_getresponse"); section = DNS_SECTION_ANSWER; - if (debugging) { - isc_buffer_t *buf = NULL; - int bufsz; - bufsz = INITTEXT; - do { - if (buf != NULL) - isc_buffer_free(&buf); - if (bufsz > MAXTEXT) { - fprintf(stderr, "could not allocate enough " - "space for debugging message\n"); - exit(1); - } - result = isc_buffer_allocate(mctx, &buf, bufsz); - check_result(result, "isc_buffer_allocate"); - result = dns_message_totext(rcvmsg, style, 0, buf); - } while (result == ISC_R_NOSPACE); - check_result(result, "dns_message_totext"); - fprintf(stderr, "Reply from SOA query:\n%.*s\n", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); - isc_buffer_free(&buf); - } + if (debugging) + show_message(stderr, rcvmsg, "Reply from SOA query:"); if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) @@ -1901,12 +2138,9 @@ recvsoa(isc_task_t *task, isc_event_t *event) { if (section == DNS_SECTION_ANSWER) { dns_rdataset_t *tset = NULL; if (dns_message_findtype(name, dns_rdatatype_cname, 0, - &tset) == ISC_R_SUCCESS - || + &tset) == ISC_R_SUCCESS || dns_message_findtype(name, dns_rdatatype_dname, 0, - &tset) == ISC_R_SUCCESS - ) - { + &tset) == ISC_R_SUCCESS ) { seencname = ISC_TRUE; break; } @@ -1966,8 +2200,21 @@ recvsoa(isc_task_t *task, isc_event_t *event) { } dns_rdata_freestruct(&soa); +#ifdef GSSAPI + if (usegsstsig) { + dns_name_init(&tmpzonename, NULL); + dns_name_dup(zonename, mctx, &tmpzonename); + dns_name_init(&restart_master, NULL); + dns_name_dup(&master, mctx, &restart_master); + start_gssrequest(&master); + } else { + send_update(zonename, serveraddr, localaddr); + setzoneclass(dns_rdataclass_none); + } +#else send_update(zonename, serveraddr, localaddr); setzoneclass(dns_rdataclass_none); +#endif dns_message_destroy(&soaquery); dns_request_destroy(&request); @@ -1994,8 +2241,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) { if (userserver != NULL) sendrequest(localaddr, userserver, soaquery, &request); else - sendrequest(localaddr, &servers[ns_inuse], soaquery, - &request); + sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); goto out; } @@ -2019,6 +2265,286 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, requests++; } +#ifdef GSSAPI +static void +start_gssrequest(dns_name_t *master) +{ + gss_ctx_id_t context; + isc_buffer_t buf; + isc_result_t result; + isc_uint32_t val = 0; + dns_message_t *rmsg; + dns_request_t *request = NULL; + dns_name_t *servname; + dns_fixedname_t fname; + char namestr[DNS_NAME_FORMATSIZE]; + char keystr[DNS_NAME_FORMATSIZE]; + + debug("start_gssrequest"); + usevc = ISC_TRUE; + + if (gssring != NULL) + dns_tsigkeyring_destroy(&gssring); + gssring = NULL; + result = dns_tsigkeyring_create(mctx, &gssring); + + if (result != ISC_R_SUCCESS) + fatal("dns_tsigkeyring_create failed: %s", + isc_result_totext(result)); + + dns_name_format(master, namestr, sizeof(namestr)); + if (kserver == NULL) { + kserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); + if (kserver == NULL) + fatal("out of memory"); + } + if (userserver == NULL) + get_address(namestr, DNSDEFAULTPORT, kserver); + else + (void)memcpy(kserver, userserver, sizeof(isc_sockaddr_t)); + + dns_fixedname_init(&fname); + servname = dns_fixedname_name(&fname); + + result = isc_string_printf(servicename, sizeof(servicename), + "DNS/%s", namestr); + if (result != ISC_R_SUCCESS) + fatal("isc_string_printf(servicename) failed: %s", + isc_result_totext(result)); + isc_buffer_init(&buf, servicename, strlen(servicename)); + isc_buffer_add(&buf, strlen(servicename)); + result = dns_name_fromtext(servname, &buf, dns_rootname, + ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + fatal("dns_name_fromtext(servname) failed: %s", + isc_result_totext(result)); + + dns_fixedname_init(&fkname); + keyname = dns_fixedname_name(&fkname); + + isc_random_get(&val); + result = isc_string_printf(keystr, sizeof(keystr), "%u.sig-%s", + val, namestr); + if (result != ISC_R_SUCCESS) + fatal("isc_string_printf(keystr) failed: %s", + isc_result_totext(result)); + isc_buffer_init(&buf, keystr, strlen(keystr)); + isc_buffer_add(&buf, strlen(keystr)); + + result = dns_name_fromtext(keyname, &buf, dns_rootname, + ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + fatal("dns_name_fromtext(keyname) failed: %s", + isc_result_totext(result)); + + /* Windows doesn't recognize name compression in the key name. */ + keyname->attributes |= DNS_NAMEATTR_NOCOMPRESS; + + rmsg = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &rmsg); + if (result != ISC_R_SUCCESS) + fatal("dns_message_create failed: %s", + isc_result_totext(result)); + + /* Build first request. */ + + context = GSS_C_NO_CONTEXT; + result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0, + &context, use_win2k_gsstsig); + if (result == ISC_R_FAILURE) + fatal("Check your Kerberos ticket, it may have expired."); + if (result != ISC_R_SUCCESS) + fatal("dns_tkey_buildgssquery failed: %s", + isc_result_totext(result)); + + send_gssrequest(localaddr, kserver, rmsg, &request, context); +} + +static void +send_gssrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, + dns_message_t *msg, dns_request_t **request, + gss_ctx_id_t context) +{ + isc_result_t result; + nsu_gssinfo_t *reqinfo; + unsigned int options = 0; + + debug("send_gssrequest"); + reqinfo = isc_mem_get(mctx, sizeof(nsu_gssinfo_t)); + if (reqinfo == NULL) + fatal("out of memory"); + reqinfo->msg = msg; + reqinfo->addr = destaddr; + reqinfo->context = context; + + options |= DNS_REQUESTOPT_TCP; + result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, + options, tsigkey, FIND_TIMEOUT * 20, + FIND_TIMEOUT, 3, global_task, recvgss, + reqinfo, request); + check_result(result, "dns_request_createvia3"); + if (debugging) + show_message(stdout, msg, "Outgoing update query:"); + requests++; +} + +static void +recvgss(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = NULL; + dns_request_t *request = NULL; + isc_result_t result, eresult; + dns_message_t *rcvmsg = NULL; + nsu_gssinfo_t *reqinfo; + dns_message_t *tsigquery = NULL; + isc_sockaddr_t *addr; + gss_ctx_id_t context; + isc_buffer_t buf; + dns_name_t *servname; + dns_fixedname_t fname; + + UNUSED(task); + + ddebug("recvgss()"); + + requests--; + + REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); + reqev = (dns_requestevent_t *)event; + request = reqev->request; + eresult = reqev->result; + reqinfo = reqev->ev_arg; + tsigquery = reqinfo->msg; + context = reqinfo->context; + addr = reqinfo->addr; + + if (shuttingdown) { + dns_request_destroy(&request); + dns_message_destroy(&tsigquery); + isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t)); + isc_event_free(&event); + maybeshutdown(); + return; + } + + if (eresult != ISC_R_SUCCESS) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); + fprintf(stderr, "; Communication with %s failed: %s\n", + addrbuf, isc_result_totext(eresult)); + if (userserver != NULL) + fatal("could not talk to specified name server"); + else if (++ns_inuse >= lwconf->nsnext) + fatal("could not talk to any default name server"); + ddebug("Destroying request [%p]", request); + dns_request_destroy(&request); + dns_message_renderreset(tsigquery); + sendrequest(localaddr, &servers[ns_inuse], tsigquery, + &request); + isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t)); + isc_event_free(&event); + return; + } + isc_mem_put(mctx, reqinfo, sizeof(nsu_gssinfo_t)); + + isc_event_free(&event); + reqev = NULL; + + ddebug("recvgss creating rcvmsg"); + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); + check_result(result, "dns_message_create"); + + result = dns_request_getresponse(request, rcvmsg, + DNS_MESSAGEPARSE_PRESERVEORDER); + check_result(result, "dns_request_getresponse"); + + if (debugging) + show_message(stderr, rcvmsg, + "recvmsg reply from GSS-TSIG query"); + + if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) { + ddebug("recvgss trying %s GSS-TSIG", + use_win2k_gsstsig ? "Standard" : "Win2k"); + if (use_win2k_gsstsig) + use_win2k_gsstsig = ISC_FALSE; + else + use_win2k_gsstsig = ISC_TRUE; + tried_other_gsstsig = ISC_TRUE; + start_gssrequest(&restart_master); + goto done; + } + + if (rcvmsg->rcode != dns_rcode_noerror && + rcvmsg->rcode != dns_rcode_nxdomain) + fatal("response to GSS-TSIG query was unsuccessful"); + + + dns_fixedname_init(&fname); + servname = dns_fixedname_name(&fname); + isc_buffer_init(&buf, servicename, strlen(servicename)); + isc_buffer_add(&buf, strlen(servicename)); + result = dns_name_fromtext(servname, &buf, dns_rootname, + ISC_FALSE, NULL); + check_result(result, "dns_name_fromtext"); + + tsigkey = NULL; + result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname, + &context, &tsigkey, gssring, + use_win2k_gsstsig); + switch (result) { + + case DNS_R_CONTINUE: + send_gssrequest(localaddr, kserver, tsigquery, &request, + context); + break; + + case ISC_R_SUCCESS: + /* + * XXXSRA Waaay too much fun here. There's no good + * reason why we need a TSIG here (the people who put + * it into the spec admitted at the time that it was + * not a security issue), and Windows clients don't + * seem to work if named complies with the spec and + * includes the gratuitous TSIG. So we're in the + * bizarre situation of having to choose between + * complying with a useless requirement in the spec + * and interoperating. This is nuts. If we can + * confirm this behavior, we should ask the WG to + * consider removing the requirement for the + * gratuitous TSIG here. For the moment, we ignore + * the TSIG -- this too is a spec violation, but it's + * the least insane thing to do. + */ +#if 0 + /* + * Verify the signature. + */ + rcvmsg->state = DNS_SECTION_ANY; + dns_message_setquerytsig(rcvmsg, NULL); + result = dns_message_settsigkey(rcvmsg, tsigkey); + check_result(result, "dns_message_settsigkey"); + result = dns_message_checksig(rcvmsg, NULL); + ddebug("tsig verification: %s", dns_result_totext(result)); + check_result(result, "dns_message_checksig"); +#endif /* 0 */ + + send_update(&tmpzonename, serveraddr, localaddr); + setzoneclass(dns_rdataclass_none); + break; + + default: + fatal("dns_tkey_negotiategss: %s", isc_result_totext(result)); + } + + done: + dns_request_destroy(&request); + dns_message_destroy(&tsigquery); + + dns_message_destroy(&rcvmsg); + ddebug("Out of recvgss"); +} +#endif + static void start_update(void) { isc_result_t result; @@ -2034,7 +2560,7 @@ start_update(void) { if (answer != NULL) dns_message_destroy(&answer); - if (userzone != NULL && userserver != NULL) { + if (userzone != NULL && userserver != NULL && ! usegsstsig) { send_update(userzone, userserver, localaddr); setzoneclass(dns_rdataclass_none); return; @@ -2096,6 +2622,22 @@ cleanup(void) { if (answer != NULL) dns_message_destroy(&answer); + +#ifdef GSSAPI + if (tsigkey != NULL) { + ddebug("detach tsigkey x%p", tsigkey); + dns_tsigkey_detach(&tsigkey); + } + if (gssring != NULL) { + ddebug("Destroying GSS-TSIG keyring"); + dns_tsigkeyring_destroy(&gssring); + } + if (kserver != NULL) { + isc_mem_put(mctx, kserver, sizeof(isc_sockaddr_t)); + kserver = NULL; + } +#endif + ddebug("Shutting down task manager"); isc_taskmgr_destroy(&taskmgr); @@ -2114,6 +2656,9 @@ cleanup(void) { ddebug("Destroying name state"); dns_name_destroy(); + ddebug("Removing log context"); + isc_log_destroy(&lctx); + ddebug("Destroying memory context"); if (memdebugging) isc_mem_stats(mctx, stderr); @@ -2155,7 +2700,12 @@ main(int argc, char **argv) { isc_app_start(); - parse_args(argc, argv); + pre_parse_args(argc, argv); + + result = isc_mem_create(0, 0, &mctx); + check_result(result, "isc_mem_create"); + + parse_args(argc, argv, mctx, &entropy); setup_system(); diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook index 43fe69ad48530..c42a053f1853f 100644 --- a/bin/nsupdate/nsupdate.docbook +++ b/bin/nsupdate/nsupdate.docbook @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [<!ENTITY mdash "—">]> <!-- - - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - Permission to use, copy, modify, and/or distribute this software for any @@ -18,18 +18,18 @@ - PERFORMANCE OF THIS SOFTWARE. --> -<!-- $Id: nsupdate.docbook,v 1.18.18.12 2008/08/29 23:46:16 tbox Exp $ --> -<refentry> +<!-- $Id: nsupdate.docbook,v 1.34.48.3 2009/03/09 04:21:56 marka Exp $ --> +<refentry id="man.nsupdate"> <refentryinfo> <date>Jun 30, 2000</date> </refentryinfo> <refmeta> - <refentrytitle>nsupdate</refentrytitle> + <refentrytitle><application>nsupdate</application></refentrytitle> <manvolnum>1</manvolnum> <refmiscinfo>BIND9</refmiscinfo> </refmeta> <refnamediv> - <refname>nsupdate</refname> + <refname><application>nsupdate</application></refname> <refpurpose>Dynamic DNS update utility</refpurpose> </refnamediv> @@ -40,6 +40,7 @@ <year>2006</year> <year>2007</year> <year>2008</year> + <year>2009</year> <holder>Internet Systems Consortium, Inc. ("ISC")</holder> </copyright> <copyright> @@ -55,13 +56,17 @@ <cmdsynopsis> <command>nsupdate</command> <arg><option>-d</option></arg> + <arg><option>-D</option></arg> <group> + <arg><option>-g</option></arg> + <arg><option>-o</option></arg> <arg><option>-y <replaceable class="parameter"><optional>hmac:</optional>keyname:secret</replaceable></option></arg> <arg><option>-k <replaceable class="parameter">keyfile</replaceable></option></arg> </group> <arg><option>-t <replaceable class="parameter">timeout</replaceable></option></arg> <arg><option>-u <replaceable class="parameter">udptimeout</replaceable></option></arg> <arg><option>-r <replaceable class="parameter">udpretries</replaceable></option></arg> + <arg><option>-R <replaceable class="parameter">randomdev</replaceable></option></arg> <arg><option>-v</option></arg> <arg>filename</arg> </cmdsynopsis> @@ -102,31 +107,31 @@ made and the replies received from the name server. </para> <para> - Transaction signatures can be used to authenticate the Dynamic DNS - updates. - These use the TSIG resource record type described in RFC2845 or the - SIG(0) record described in RFC3535 and RFC2931. - TSIG relies on a shared secret that should only be known to - <command>nsupdate</command> and the name server. - Currently, the only supported encryption algorithm for TSIG is - HMAC-MD5, which is defined in RFC 2104. - Once other algorithms are defined for TSIG, applications will need to - ensure they select the appropriate algorithm as well as the key when - authenticating each other. - For instance, suitable - <type>key</type> - and - <type>server</type> - statements would be added to - <filename>/etc/named.conf</filename> - so that the name server can associate the appropriate secret key - and algorithm with the IP address of the - client application that will be using TSIG authentication. - SIG(0) uses public key cryptography. To use a SIG(0) key, the public - key must be stored in a KEY record in a zone served by the name server. - <command>nsupdate</command> - does not read + The <option>-D</option> option makes <command>nsupdate</command> + report additional debugging information to <option>-d</option>. + </para> + <para> + Transaction signatures can be used to authenticate the Dynamic + DNS updates. These use the TSIG resource record type described + in RFC2845 or the SIG(0) record described in RFC3535 and + RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on + a shared secret that should only be known to + <command>nsupdate</command> and the name server. Currently, + the only supported encryption algorithm for TSIG is HMAC-MD5, + which is defined in RFC 2104. Once other algorithms are + defined for TSIG, applications will need to ensure they select + the appropriate algorithm as well as the key when authenticating + each other. For instance, suitable <type>key</type> and + <type>server</type> statements would be added to + <filename>/etc/named.conf</filename> so that the name server + can associate the appropriate secret key and algorithm with + the IP address of the client application that will be using + TSIG authentication. SIG(0) uses public key cryptography. + To use a SIG(0) key, the public key must be stored in a KEY + record in a zone served by the name server. + <command>nsupdate</command> does not read <filename>/etc/named.conf</filename>. + GSS-TSIG uses Kerberos credentials. </para> <para><command>nsupdate</command> uses the <option>-y</option> or <option>-k</option> option @@ -159,7 +164,12 @@ specified is not an HMAC-MD5 key. </para> <para> - By default + The <option>-g</option> and <option>-o</option> specify that + GSS-TSIG is to be used. The <option>-o</option> should only + be used with old Microsoft Windows 2000 servers. + </para> + <para> + By default, <command>nsupdate</command> uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. @@ -189,6 +199,18 @@ default is 3. If zero, only one update request will be made. </para> + <para> + The <option>-R <replaceable + class="parameter">randomdev</replaceable></option> option + specifies a source of randomness. If the operating system + does not provide a <filename>/dev/random</filename> or + equivalent device, the default source of randomness is keyboard + input. <filename>randomdev</filename> specifies the name of + a character device or file containing random data to be used + instead of the default. The special value + <filename>keyboard</filename> indicates that keyboard input + should be used. This option may be specified multiple times. + </para> </refsect1> <refsect1> @@ -307,6 +329,20 @@ <varlistentry> <term> + <command>ttl</command> + <arg choice="req">seconds</arg> + </term> + <listitem> + <para> + Specify the default time to live for records to be added. + The value <parameter>none</parameter> will clear the default + ttl. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> <command>key</command> <arg choice="req">name</arg> <arg choice="req">secret</arg> @@ -510,6 +546,17 @@ </listitem> </varlistentry> + <varlistentry> + <term> + <command>debug</command> + </term> + <listitem> + <para> + Turn on debugging. + </para> + </listitem> + </varlistentry> + </variablelist> </para> diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html index 1fe0f9c15806a..dab7f9029cf99 100644 --- a/bin/nsupdate/nsupdate.html +++ b/bin/nsupdate/nsupdate.html @@ -1,5 +1,5 @@ <!-- - - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - Permission to use, copy, modify, and distribute this software for any @@ -14,7 +14,7 @@ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> -<!-- $Id: nsupdate.html,v 1.14.18.23 2008/09/01 02:29:00 tbox Exp $ --> +<!-- $Id: nsupdate.html,v 1.40.48.2 2009/03/10 01:54:11 tbox Exp $ --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> @@ -22,17 +22,17 @@ <meta name="generator" content="DocBook XSL Stylesheets V1.71.1"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> -<a name="id2476275"></a><div class="titlepage"></div> +<a name="man.nsupdate"></a><div class="titlepage"></div> <div class="refnamediv"> <h2>Name</h2> -<p>nsupdate — Dynamic DNS update utility</p> +<p><span class="application">nsupdate</span> — Dynamic DNS update utility</p> </div> <div class="refsynopsisdiv"> <h2>Synopsis</h2> -<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [[<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-v</code>] [filename]</p></div> +<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div> </div> <div class="refsect1" lang="en"> -<a name="id2543420"></a><h2>DESCRIPTION</h2> +<a name="id2543449"></a><h2>DESCRIPTION</h2> <p><span><strong class="command">nsupdate</strong></span> is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. @@ -66,31 +66,31 @@ made and the replies received from the name server. </p> <p> - Transaction signatures can be used to authenticate the Dynamic DNS - updates. - These use the TSIG resource record type described in RFC2845 or the - SIG(0) record described in RFC3535 and RFC2931. - TSIG relies on a shared secret that should only be known to - <span><strong class="command">nsupdate</strong></span> and the name server. - Currently, the only supported encryption algorithm for TSIG is - HMAC-MD5, which is defined in RFC 2104. - Once other algorithms are defined for TSIG, applications will need to - ensure they select the appropriate algorithm as well as the key when - authenticating each other. - For instance, suitable - <span class="type">key</span> - and - <span class="type">server</span> - statements would be added to - <code class="filename">/etc/named.conf</code> - so that the name server can associate the appropriate secret key - and algorithm with the IP address of the - client application that will be using TSIG authentication. - SIG(0) uses public key cryptography. To use a SIG(0) key, the public - key must be stored in a KEY record in a zone served by the name server. - <span><strong class="command">nsupdate</strong></span> - does not read + The <code class="option">-D</code> option makes <span><strong class="command">nsupdate</strong></span> + report additional debugging information to <code class="option">-d</code>. + </p> +<p> + Transaction signatures can be used to authenticate the Dynamic + DNS updates. These use the TSIG resource record type described + in RFC2845 or the SIG(0) record described in RFC3535 and + RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on + a shared secret that should only be known to + <span><strong class="command">nsupdate</strong></span> and the name server. Currently, + the only supported encryption algorithm for TSIG is HMAC-MD5, + which is defined in RFC 2104. Once other algorithms are + defined for TSIG, applications will need to ensure they select + the appropriate algorithm as well as the key when authenticating + each other. For instance, suitable <span class="type">key</span> and + <span class="type">server</span> statements would be added to + <code class="filename">/etc/named.conf</code> so that the name server + can associate the appropriate secret key and algorithm with + the IP address of the client application that will be using + TSIG authentication. SIG(0) uses public key cryptography. + To use a SIG(0) key, the public key must be stored in a KEY + record in a zone served by the name server. + <span><strong class="command">nsupdate</strong></span> does not read <code class="filename">/etc/named.conf</code>. + GSS-TSIG uses Kerberos credentials. </p> <p><span><strong class="command">nsupdate</strong></span> uses the <code class="option">-y</code> or <code class="option">-k</code> option @@ -121,7 +121,12 @@ specified is not an HMAC-MD5 key. </p> <p> - By default + The <code class="option">-g</code> and <code class="option">-o</code> specify that + GSS-TSIG is to be used. The <code class="option">-o</code> should only + be used with old Microsoft Windows 2000 servers. + </p> +<p> + By default, <span><strong class="command">nsupdate</strong></span> uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. @@ -151,9 +156,20 @@ default is 3. If zero, only one update request will be made. </p> +<p> + The <code class="option">-R <em class="replaceable"><code>randomdev</code></em></code> option + specifies a source of randomness. If the operating system + does not provide a <code class="filename">/dev/random</code> or + equivalent device, the default source of randomness is keyboard + input. <code class="filename">randomdev</code> specifies the name of + a character device or file containing random data to be used + instead of the default. The special value + <code class="filename">keyboard</code> indicates that keyboard input + should be used. This option may be specified multiple times. + </p> </div> <div class="refsect1" lang="en"> -<a name="id2543649"></a><h2>INPUT FORMAT</h2> +<a name="id2543726"></a><h2>INPUT FORMAT</h2> <p><span><strong class="command">nsupdate</strong></span> reads input from <em class="parameter"><code>filename</code></em> @@ -247,6 +263,15 @@ <em class="parameter"><code>IN</code></em>. </p></dd> <dt><span class="term"> + <span><strong class="command">ttl</strong></span> + {seconds} + </span></dt> +<dd><p> + Specify the default time to live for records to be added. + The value <em class="parameter"><code>none</code></em> will clear the default + ttl. + </p></dd> +<dt><span class="term"> <span><strong class="command">key</strong></span> {name} {secret} @@ -394,6 +419,12 @@ <dd><p> Displays the answer. </p></dd> +<dt><span class="term"> + <span><strong class="command">debug</strong></span> + </span></dt> +<dd><p> + Turn on debugging. + </p></dd> </dl></div> <p> </p> @@ -402,7 +433,7 @@ </p> </div> <div class="refsect1" lang="en"> -<a name="id2544446"></a><h2>EXAMPLES</h2> +<a name="id2544567"></a><h2>EXAMPLES</h2> <p> The examples below show how <span><strong class="command">nsupdate</strong></span> @@ -456,7 +487,7 @@ </p> </div> <div class="refsect1" lang="en"> -<a name="id2544490"></a><h2>FILES</h2> +<a name="id2544611"></a><h2>FILES</h2> <div class="variablelist"><dl> <dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt> <dd><p> @@ -475,7 +506,7 @@ </dl></div> </div> <div class="refsect1" lang="en"> -<a name="id2544560"></a><h2>SEE ALSO</h2> +<a name="id2544680"></a><h2>SEE ALSO</h2> <p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>, <span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>, <span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>, @@ -488,7 +519,7 @@ </p> </div> <div class="refsect1" lang="en"> -<a name="id2542172"></a><h2>BUGS</h2> +<a name="id2542156"></a><h2>BUGS</h2> <p> The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library |
