2 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
29 #include <isc/base64.h>
30 #include <isc/buffer.h>
31 #include <isc/commandline.h>
32 #include <isc/entropy.h>
33 #include <isc/event.h>
39 #include <isc/parseint.h>
40 #include <isc/print.h>
41 #include <isc/random.h>
42 #include <isc/region.h>
43 #include <isc/sockaddr.h>
44 #include <isc/socket.h>
45 #include <isc/stdio.h>
46 #include <isc/string.h>
48 #include <isc/timer.h>
49 #include <isc/types.h>
52 #include <isccfg/namedconf.h>
54 #include <dns/callbacks.h>
55 #include <dns/dispatch.h>
56 #include <dns/dnssec.h>
57 #include <dns/events.h>
58 #include <dns/fixedname.h>
60 #include <dns/masterdump.h>
61 #include <dns/message.h>
63 #include <dns/rcode.h>
64 #include <dns/rdata.h>
65 #include <dns/rdataclass.h>
66 #include <dns/rdatalist.h>
67 #include <dns/rdataset.h>
68 #include <dns/rdatastruct.h>
69 #include <dns/rdatatype.h>
70 #include <dns/request.h>
71 #include <dns/result.h>
77 #include <lwres/lwres.h>
78 #include <lwres/net.h>
81 #include <dst/gssapi.h>
83 #include <krb5/krb5.h>
85 #include ISC_PLATFORM_KRB5HEADER
88 #include <bind9/getaddresses.h>
90 #if defined(HAVE_READLINE)
91 #include <readline/readline.h>
92 #include <readline/history.h>
96 #ifdef HAVE_GETADDRINFO
97 #ifdef HAVE_GAISTRERROR
98 #define USE_GETADDRINFO
103 #ifndef USE_GETADDRINFO
104 #ifndef ISC_PLATFORM_NONSTDHERRNO
109 #define MAXCMD (128 * 1024)
110 #define MAXWIRE (64 * 1024)
111 #define PACKETSIZE ((64 * 1024) - 1)
112 #define INITTEXT (2 * 1024)
113 #define MAXTEXT (128 * 1024)
114 #define FIND_TIMEOUT 5
115 #define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
117 #define DNSDEFAULTPORT 53
119 /* Number of addresses to request from bind9_getaddresses() */
120 #define MAX_SERVERADDRS 4
122 static isc_uint16_t dnsport = DNSDEFAULTPORT;
125 #define RESOLV_CONF "/etc/resolv.conf"
128 static isc_boolean_t debugging = ISC_FALSE, ddebugging = ISC_FALSE;
129 static isc_boolean_t memdebugging = ISC_FALSE;
130 static isc_boolean_t have_ipv4 = ISC_FALSE;
131 static isc_boolean_t have_ipv6 = ISC_FALSE;
132 static isc_boolean_t is_dst_up = ISC_FALSE;
133 static isc_boolean_t usevc = ISC_FALSE;
134 static isc_boolean_t usegsstsig = ISC_FALSE;
135 static isc_boolean_t use_win2k_gsstsig = ISC_FALSE;
136 static isc_boolean_t tried_other_gsstsig = ISC_FALSE;
137 static isc_boolean_t local_only = ISC_FALSE;
138 static isc_taskmgr_t *taskmgr = NULL;
139 static isc_task_t *global_task = NULL;
140 static isc_event_t *global_event = NULL;
141 static isc_log_t *glctx = NULL;
142 static isc_mem_t *gmctx = NULL;
143 static dns_dispatchmgr_t *dispatchmgr = NULL;
144 static dns_requestmgr_t *requestmgr = NULL;
145 static isc_socketmgr_t *socketmgr = NULL;
146 static isc_timermgr_t *timermgr = NULL;
147 static dns_dispatch_t *dispatchv4 = NULL;
148 static dns_dispatch_t *dispatchv6 = NULL;
149 static dns_message_t *updatemsg = NULL;
150 static dns_fixedname_t fuserzone;
151 static dns_name_t *userzone = NULL;
152 static dns_name_t *zname = NULL;
153 static dns_name_t tmpzonename;
154 static dns_name_t restart_master;
155 static dns_tsig_keyring_t *gssring = NULL;
156 static dns_tsigkey_t *tsigkey = NULL;
157 static dst_key_t *sig0key = NULL;
158 static lwres_context_t *lwctx = NULL;
159 static lwres_conf_t *lwconf;
160 static isc_sockaddr_t *servers = NULL;
161 static isc_sockaddr_t *master_servers = NULL;
162 static isc_boolean_t default_servers = ISC_TRUE;
163 static int ns_inuse = 0;
164 static int master_inuse = 0;
165 static int ns_total = 0;
166 static int master_total = 0;
167 static isc_sockaddr_t *localaddr4 = NULL;
168 static isc_sockaddr_t *localaddr6 = NULL;
169 static const char *keyfile = NULL;
170 static char *keystr = NULL;
171 static isc_entropy_t *entropy = NULL;
172 static isc_boolean_t shuttingdown = ISC_FALSE;
174 static isc_boolean_t interactive = ISC_TRUE;
175 static isc_boolean_t seenerror = ISC_FALSE;
176 static const dns_master_style_t *style;
177 static int requests = 0;
178 static unsigned int logdebuglevel = 0;
179 static unsigned int timeout = 300;
180 static unsigned int udp_timeout = 3;
181 static unsigned int udp_retries = 3;
182 static dns_rdataclass_t defaultclass = dns_rdataclass_in;
183 static dns_rdataclass_t zoneclass = dns_rdataclass_none;
184 static dns_message_t *answer = NULL;
185 static isc_uint32_t default_ttl = 0;
186 static isc_boolean_t default_ttl_set = ISC_FALSE;
188 typedef struct nsu_requestinfo {
190 isc_sockaddr_t *addr;
194 sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
195 dns_request_t **request);
197 send_update(dns_name_t *zonename, isc_sockaddr_t *master);
199 ISC_PLATFORM_NORETURN_PRE static void
200 fatal(const char *format, ...)
201 ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
204 debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
207 ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
210 static dns_fixedname_t fkname;
211 static isc_sockaddr_t *kserver = NULL;
212 static char *realm = NULL;
213 static char servicename[DNS_NAME_FORMATSIZE];
214 static dns_name_t *keyname;
215 typedef struct nsu_gssinfo {
217 isc_sockaddr_t *addr;
218 gss_ctx_id_t context;
224 start_gssrequest(dns_name_t *master);
226 send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
227 dns_request_t **request, gss_ctx_id_t context);
229 recvgss(isc_task_t *task, isc_event_t *event);
233 error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
235 #define STATUS_MORE (isc_uint16_t)0
236 #define STATUS_SEND (isc_uint16_t)1
237 #define STATUS_QUIT (isc_uint16_t)2
238 #define STATUS_SYNTAX (isc_uint16_t)3
240 typedef struct entropysource entropysource_t;
242 struct entropysource {
243 isc_entropysource_t *source;
245 ISC_LINK(entropysource_t) link;
248 static ISC_LIST(entropysource_t) sources;
251 setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
253 isc_entropysource_t *source = NULL;
254 entropysource_t *elt;
255 int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE;
257 REQUIRE(ectx != NULL);
260 result = isc_entropy_create(mctx, ectx);
261 if (result != ISC_R_SUCCESS)
262 fatal("could not create entropy object");
263 ISC_LIST_INIT(sources);
266 if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
267 usekeyboard = ISC_ENTROPY_KEYBOARDYES;
271 result = isc_entropy_usebestsource(*ectx, &source, randomfile,
274 if (result != ISC_R_SUCCESS)
275 fatal("could not initialize entropy source: %s",
276 isc_result_totext(result));
278 if (source != NULL) {
279 elt = isc_mem_get(mctx, sizeof(*elt));
281 fatal("out of memory");
282 elt->source = source;
284 ISC_LINK_INIT(elt, link);
285 ISC_LIST_APPEND(sources, elt, link);
290 cleanup_entropy(isc_entropy_t **ectx) {
291 entropysource_t *source;
292 while (!ISC_LIST_EMPTY(sources)) {
293 source = ISC_LIST_HEAD(sources);
294 ISC_LIST_UNLINK(sources, source, link);
295 isc_entropy_destroysource(&source->source);
296 isc_mem_put(source->mctx, source, sizeof(*source));
298 isc_entropy_detach(ectx);
302 master_from_servers(void) {
304 if (master_servers != NULL && master_servers != servers)
305 isc_mem_put(gmctx, master_servers,
306 master_total * sizeof(isc_sockaddr_t));
307 master_servers = servers;
308 master_total = ns_total;
309 master_inuse = ns_inuse;
312 static dns_rdataclass_t
314 if (zoneclass == dns_rdataclass_none)
315 zoneclass = defaultclass;
320 setzoneclass(dns_rdataclass_t rdclass) {
321 if (zoneclass == dns_rdataclass_none ||
322 rdclass == dns_rdataclass_none)
324 if (zoneclass != rdclass)
330 fatal(const char *format, ...) {
333 va_start(args, format);
334 vfprintf(stderr, format, args);
336 fprintf(stderr, "\n");
341 error(const char *format, ...) {
344 va_start(args, format);
345 vfprintf(stderr, format, args);
347 fprintf(stderr, "\n");
351 debug(const char *format, ...) {
355 va_start(args, format);
356 vfprintf(stderr, format, args);
358 fprintf(stderr, "\n");
363 ddebug(const char *format, ...) {
367 va_start(args, format);
368 vfprintf(stderr, format, args);
370 fprintf(stderr, "\n");
375 check_result(isc_result_t result, const char *msg) {
376 if (result != ISC_R_SUCCESS)
377 fatal("%s: %s", msg, isc_result_totext(result));
381 mem_alloc(void *arg, size_t size) {
382 return (isc_mem_get(arg, size));
386 mem_free(void *arg, void *mem, size_t size) {
387 isc_mem_put(arg, mem, size);
391 nsu_strsep(char **stringp, const char *delim) {
392 char *string = *stringp;
400 for (; *string != '\0'; string++) {
402 for (d = delim; (dc = *d) != '\0'; d++) {
410 for (s = string; *s != '\0'; s++) {
412 for (d = delim; (dc = *d) != '\0'; d++) {
428 ddebug("reset_system()");
429 /* If the update message is still around, destroy it */
430 if (updatemsg != NULL)
431 dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER);
433 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER,
435 check_result(result, "dns_message_create");
437 updatemsg->opcode = dns_opcode_update;
440 dns_tsigkey_detach(&tsigkey);
442 dns_tsigkeyring_detach(&gssring);
443 tried_other_gsstsig = ISC_FALSE;
448 parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) {
449 isc_uint16_t digestbits = 0;
453 REQUIRE(hmac != NULL && *hmac == NULL);
454 REQUIRE(hmacstr != NULL);
456 if (len >= sizeof(buf))
457 fatal("unknown key type '%.*s'", (int)(len), hmacstr);
459 strncpy(buf, hmacstr, len);
462 if (strcasecmp(buf, "hmac-md5") == 0) {
463 *hmac = DNS_TSIG_HMACMD5_NAME;
464 } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) {
465 *hmac = DNS_TSIG_HMACMD5_NAME;
466 result = isc_parse_uint16(&digestbits, &buf[9], 10);
467 if (result != ISC_R_SUCCESS || digestbits > 128)
468 fatal("digest-bits out of range [0..128]");
469 digestbits = (digestbits +7) & ~0x7U;
470 } else if (strcasecmp(buf, "hmac-sha1") == 0) {
471 *hmac = DNS_TSIG_HMACSHA1_NAME;
472 } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) {
473 *hmac = DNS_TSIG_HMACSHA1_NAME;
474 result = isc_parse_uint16(&digestbits, &buf[10], 10);
475 if (result != ISC_R_SUCCESS || digestbits > 160)
476 fatal("digest-bits out of range [0..160]");
477 digestbits = (digestbits +7) & ~0x7U;
478 } else if (strcasecmp(buf, "hmac-sha224") == 0) {
479 *hmac = DNS_TSIG_HMACSHA224_NAME;
480 } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) {
481 *hmac = DNS_TSIG_HMACSHA224_NAME;
482 result = isc_parse_uint16(&digestbits, &buf[12], 10);
483 if (result != ISC_R_SUCCESS || digestbits > 224)
484 fatal("digest-bits out of range [0..224]");
485 digestbits = (digestbits +7) & ~0x7U;
486 } else if (strcasecmp(buf, "hmac-sha256") == 0) {
487 *hmac = DNS_TSIG_HMACSHA256_NAME;
488 } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) {
489 *hmac = DNS_TSIG_HMACSHA256_NAME;
490 result = isc_parse_uint16(&digestbits, &buf[12], 10);
491 if (result != ISC_R_SUCCESS || digestbits > 256)
492 fatal("digest-bits out of range [0..256]");
493 digestbits = (digestbits +7) & ~0x7U;
494 } else if (strcasecmp(buf, "hmac-sha384") == 0) {
495 *hmac = DNS_TSIG_HMACSHA384_NAME;
496 } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) {
497 *hmac = DNS_TSIG_HMACSHA384_NAME;
498 result = isc_parse_uint16(&digestbits, &buf[12], 10);
499 if (result != ISC_R_SUCCESS || digestbits > 384)
500 fatal("digest-bits out of range [0..384]");
501 digestbits = (digestbits +7) & ~0x7U;
502 } else if (strcasecmp(buf, "hmac-sha512") == 0) {
503 *hmac = DNS_TSIG_HMACSHA512_NAME;
504 } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) {
505 *hmac = DNS_TSIG_HMACSHA512_NAME;
506 result = isc_parse_uint16(&digestbits, &buf[12], 10);
507 if (result != ISC_R_SUCCESS || digestbits > 512)
508 fatal("digest-bits out of range [0..512]");
509 digestbits = (digestbits +7) & ~0x7U;
511 fatal("unknown key type '%s'", buf);
516 basenamelen(const char *file) {
517 int len = strlen(file);
519 if (len > 1 && file[len - 1] == '.')
521 else if (len > 8 && strcmp(file + len - 8, ".private") == 0)
523 else if (len > 4 && strcmp(file + len - 4, ".key") == 0)
530 unsigned char *secret = NULL;
532 isc_buffer_t secretbuf;
534 isc_buffer_t keynamesrc;
537 dns_fixedname_t fkeyname;
538 dns_name_t *mykeyname;
540 dns_name_t *hmacname = NULL;
541 isc_uint16_t digestbits = 0;
543 dns_fixedname_init(&fkeyname);
544 mykeyname = dns_fixedname_name(&fkeyname);
546 debug("Creating key...");
548 s = strchr(keystr, ':');
549 if (s == NULL || s == keystr || s[1] == 0)
550 fatal("key option must specify [hmac:]keyname:secret");
552 n = strchr(secretstr, ':');
554 if (n == secretstr || n[1] == 0)
555 fatal("key option must specify [hmac:]keyname:secret");
558 digestbits = parse_hmac(&hmacname, keystr, s - keystr);
560 hmacname = DNS_TSIG_HMACMD5_NAME;
565 isc_buffer_init(&keynamesrc, name, (unsigned int)(n - name));
566 isc_buffer_add(&keynamesrc, (unsigned int)(n - name));
568 debug("namefromtext");
569 result = dns_name_fromtext(mykeyname, &keynamesrc, dns_rootname, 0,
571 check_result(result, "dns_name_fromtext");
573 secretlen = strlen(secretstr) * 3 / 4;
574 secret = isc_mem_allocate(gmctx, secretlen);
576 fatal("out of memory");
578 isc_buffer_init(&secretbuf, secret, secretlen);
579 result = isc_base64_decodestring(secretstr, &secretbuf);
580 if (result != ISC_R_SUCCESS) {
581 fprintf(stderr, "could not create key from %s: %s\n",
582 keystr, isc_result_totext(result));
586 secretlen = isc_buffer_usedlength(&secretbuf);
589 result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen,
590 ISC_FALSE, NULL, 0, 0, gmctx, NULL,
592 if (result != ISC_R_SUCCESS)
593 fprintf(stderr, "could not create key from %s: %s\n",
594 keystr, dns_result_totext(result));
596 dst_key_setbits(tsigkey->key, digestbits);
599 isc_mem_free(gmctx, secret);
603 * Get a key from a named.conf format keyfile
606 read_sessionkey(isc_mem_t *mctx, isc_log_t *lctx) {
607 cfg_parser_t *pctx = NULL;
608 cfg_obj_t *sessionkey = NULL;
609 const cfg_obj_t *key = NULL;
610 const cfg_obj_t *secretobj = NULL;
611 const cfg_obj_t *algorithmobj = NULL;
612 const char *mykeyname;
613 const char *secretstr;
614 const char *algorithm;
618 if (! isc_file_exists(keyfile))
619 return (ISC_R_FILENOTFOUND);
621 result = cfg_parser_create(mctx, lctx, &pctx);
622 if (result != ISC_R_SUCCESS)
625 result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
627 if (result != ISC_R_SUCCESS)
630 result = cfg_map_get(sessionkey, "key", &key);
631 if (result != ISC_R_SUCCESS)
634 (void) cfg_map_get(key, "secret", &secretobj);
635 (void) cfg_map_get(key, "algorithm", &algorithmobj);
636 if (secretobj == NULL || algorithmobj == NULL)
637 fatal("key must have algorithm and secret");
639 mykeyname = cfg_obj_asstring(cfg_map_getname(key));
640 secretstr = cfg_obj_asstring(secretobj);
641 algorithm = cfg_obj_asstring(algorithmobj);
643 len = strlen(algorithm) + strlen(mykeyname) + strlen(secretstr) + 3;
644 keystr = isc_mem_allocate(mctx, len);
646 fatal("out of memory");
647 snprintf(keystr, len, "%s:%s:%s", algorithm, mykeyname, secretstr);
652 if (sessionkey != NULL)
653 cfg_obj_destroy(pctx, &sessionkey);
654 cfg_parser_destroy(&pctx);
658 isc_mem_free(mctx, keystr);
664 setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) {
665 dst_key_t *dstkey = NULL;
667 dns_name_t *hmacname = NULL;
669 debug("Creating key...");
672 dst_key_free(&sig0key);
674 /* Try reading the key from a K* pair */
675 result = dst_key_fromnamedfile(keyfile, NULL,
676 DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
679 /* If that didn't work, try reading it as a session.key keyfile */
680 if (result != ISC_R_SUCCESS) {
681 result = read_sessionkey(mctx, lctx);
682 if (result == ISC_R_SUCCESS)
686 if (result != ISC_R_SUCCESS) {
687 fprintf(stderr, "could not read key from %.*s.{private,key}: "
688 "%s\n", basenamelen(keyfile), keyfile,
689 isc_result_totext(result));
693 switch (dst_key_alg(dstkey)) {
694 case DST_ALG_HMACMD5:
695 hmacname = DNS_TSIG_HMACMD5_NAME;
697 case DST_ALG_HMACSHA1:
698 hmacname = DNS_TSIG_HMACSHA1_NAME;
700 case DST_ALG_HMACSHA224:
701 hmacname = DNS_TSIG_HMACSHA224_NAME;
703 case DST_ALG_HMACSHA256:
704 hmacname = DNS_TSIG_HMACSHA256_NAME;
706 case DST_ALG_HMACSHA384:
707 hmacname = DNS_TSIG_HMACSHA384_NAME;
709 case DST_ALG_HMACSHA512:
710 hmacname = DNS_TSIG_HMACSHA512_NAME;
713 if (hmacname != NULL) {
714 result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
715 hmacname, dstkey, ISC_FALSE,
716 NULL, 0, 0, mctx, NULL,
718 dst_key_free(&dstkey);
719 if (result != ISC_R_SUCCESS) {
720 fprintf(stderr, "could not create key from %s: %s\n",
721 keyfile, isc_result_totext(result));
725 dst_key_attach(dstkey, &sig0key);
726 dst_key_free(&dstkey);
732 isc_task_detach(&global_task);
735 * The isc_mem_put of master_servers must be before the
736 * isc_mem_put of servers as it sets the servers pointer
739 if (master_servers != NULL && master_servers != servers)
740 isc_mem_put(gmctx, master_servers,
741 master_total * sizeof(isc_sockaddr_t));
744 isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
746 if (localaddr4 != NULL)
747 isc_mem_put(gmctx, localaddr4, sizeof(isc_sockaddr_t));
749 if (localaddr6 != NULL)
750 isc_mem_put(gmctx, localaddr6, sizeof(isc_sockaddr_t));
752 if (tsigkey != NULL) {
753 ddebug("Freeing TSIG key");
754 dns_tsigkey_detach(&tsigkey);
757 if (sig0key != NULL) {
758 ddebug("Freeing SIG(0) key");
759 dst_key_free(&sig0key);
762 if (updatemsg != NULL)
763 dns_message_destroy(&updatemsg);
766 ddebug("Destroy DST lib");
768 is_dst_up = ISC_FALSE;
771 cleanup_entropy(&entropy);
773 lwres_conf_clear(lwctx);
774 lwres_context_destroy(&lwctx);
776 ddebug("Destroying request manager");
777 dns_requestmgr_detach(&requestmgr);
779 ddebug("Freeing the dispatchers");
781 dns_dispatch_detach(&dispatchv4);
783 dns_dispatch_detach(&dispatchv6);
785 ddebug("Shutting down dispatch manager");
786 dns_dispatchmgr_destroy(&dispatchmgr);
791 maybeshutdown(void) {
792 ddebug("Shutting down request manager");
793 dns_requestmgr_shutdown(requestmgr);
802 shutdown_program(isc_task_t *task, isc_event_t *event) {
803 REQUIRE(task == global_task);
806 ddebug("shutdown_program()");
807 isc_event_free(&event);
809 shuttingdown = ISC_TRUE;
816 isc_sockaddr_t bind_any, bind_any6;
817 lwres_result_t lwresult;
818 unsigned int attrs, attrmask;
820 isc_logconfig_t *logconfig = NULL;
822 ddebug("setup_system()");
824 dns_result_register();
826 result = isc_net_probeipv4();
827 if (result == ISC_R_SUCCESS)
828 have_ipv4 = ISC_TRUE;
830 result = isc_net_probeipv6();
831 if (result == ISC_R_SUCCESS)
832 have_ipv6 = ISC_TRUE;
834 if (!have_ipv4 && !have_ipv6)
835 fatal("could not find either IPv4 or IPv6");
837 result = isc_log_create(gmctx, &glctx, &logconfig);
838 check_result(result, "isc_log_create");
840 isc_log_setcontext(glctx);
842 dns_log_setcontext(glctx);
844 result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
845 check_result(result, "isc_log_usechannel");
847 isc_log_setdebuglevel(glctx, logdebuglevel);
849 lwresult = lwres_context_create(&lwctx, gmctx, mem_alloc, mem_free, 1);
850 if (lwresult != LWRES_R_SUCCESS)
851 fatal("lwres_context_create failed");
853 (void)lwres_conf_parse(lwctx, RESOLV_CONF);
854 lwconf = lwres_conf_get(lwctx);
856 if (servers != NULL) {
857 if (master_servers == servers)
858 master_servers = NULL;
859 isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
863 if (local_only || lwconf->nsnext <= 0) {
867 if (local_only && keyfile == NULL)
868 keyfile = SESSION_KEYFILE;
870 default_servers = !local_only;
872 ns_total = (have_ipv4 ? 1 : 0) + (have_ipv6 ? 1 : 0);
873 servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
875 fatal("out of memory");
878 in.s_addr = htonl(INADDR_LOOPBACK);
879 isc_sockaddr_fromin(&servers[0], &in, dnsport);
882 memset(&in6, 0, sizeof(in6));
884 isc_sockaddr_fromin6(&servers[(have_ipv4 ? 1 : 0)],
888 ns_total = lwconf->nsnext;
889 servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
891 fatal("out of memory");
892 for (i = 0; i < ns_total; i++) {
893 if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4)
897 lwconf->nameservers[i].address, 4);
898 isc_sockaddr_fromin(&servers[i],
903 lwconf->nameservers[i].address, 16);
904 isc_sockaddr_fromin6(&servers[i],
910 setup_entropy(gmctx, NULL, &entropy);
912 result = isc_hash_create(gmctx, entropy, DNS_NAME_MAXWIRE);
913 check_result(result, "isc_hash_create");
916 result = dns_dispatchmgr_create(gmctx, entropy, &dispatchmgr);
917 check_result(result, "dns_dispatchmgr_create");
919 result = isc_socketmgr_create(gmctx, &socketmgr);
920 check_result(result, "dns_socketmgr_create");
922 result = isc_timermgr_create(gmctx, &timermgr);
923 check_result(result, "dns_timermgr_create");
925 result = isc_taskmgr_create(gmctx, 1, 0, &taskmgr);
926 check_result(result, "isc_taskmgr_create");
928 result = isc_task_create(taskmgr, 0, &global_task);
929 check_result(result, "isc_task_create");
931 result = isc_task_onshutdown(global_task, shutdown_program, NULL);
932 check_result(result, "isc_task_onshutdown");
934 result = dst_lib_init(gmctx, entropy, 0);
935 check_result(result, "dst_lib_init");
936 is_dst_up = ISC_TRUE;
938 attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
939 attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
942 attrs = DNS_DISPATCHATTR_UDP;
943 attrs |= DNS_DISPATCHATTR_MAKEQUERY;
944 attrs |= DNS_DISPATCHATTR_IPV6;
945 isc_sockaddr_any6(&bind_any6);
946 result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
947 &bind_any6, PACKETSIZE,
949 attrs, attrmask, &dispatchv6);
950 check_result(result, "dns_dispatch_getudp (v6)");
954 attrs = DNS_DISPATCHATTR_UDP;
955 attrs |= DNS_DISPATCHATTR_MAKEQUERY;
956 attrs |= DNS_DISPATCHATTR_IPV4;
957 isc_sockaddr_any(&bind_any);
958 result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
959 &bind_any, PACKETSIZE,
961 attrs, attrmask, &dispatchv4);
962 check_result(result, "dns_dispatch_getudp (v4)");
965 result = dns_requestmgr_create(gmctx, timermgr,
966 socketmgr, taskmgr, dispatchmgr,
967 dispatchv4, dispatchv6, &requestmgr);
968 check_result(result, "dns_requestmgr_create");
972 else if (local_only) {
973 result = read_sessionkey(gmctx, glctx);
974 if (result != ISC_R_SUCCESS)
975 fatal("can't read key from %s: %s\n",
976 keyfile, isc_result_totext(result));
977 } else if (keyfile != NULL)
978 setup_keyfile(gmctx, glctx);
982 get_addresses(char *host, in_port_t port,
983 isc_sockaddr_t *sockaddr, int naddrs)
989 result = bind9_getaddresses(host, port, sockaddr, naddrs, &count);
991 if (result != ISC_R_SUCCESS)
992 fatal("couldn't get address for '%s': %s",
993 host, isc_result_totext(result));
998 fputs("nsupdate " VERSION "\n", stderr);
1001 #define PARSE_ARGS_FMT "dDML:y:ghlovk:p:r:R::t:u:V"
1004 pre_parse_args(int argc, char **argv) {
1007 while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) {
1009 case 'M': /* was -dm */
1010 debugging = ISC_TRUE;
1011 ddebugging = ISC_TRUE;
1012 memdebugging = ISC_TRUE;
1013 isc_mem_debugging = ISC_MEM_DEBUGTRACE |
1014 ISC_MEM_DEBUGRECORD;
1019 if (isc_commandline_option != '?')
1020 fprintf(stderr, "%s: invalid argument -%c\n",
1021 argv[0], isc_commandline_option);
1022 fprintf(stderr, "usage: nsupdate [-dD] [-L level] [-l]"
1023 "[-g | -o | -y keyname:secret | -k keyfile] "
1024 "[-v] [-V] [filename]\n");
1035 isc_commandline_reset = ISC_TRUE;
1036 isc_commandline_index = 1;
1040 parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
1043 isc_result_t result;
1045 debug("parse_args");
1046 while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) {
1049 debugging = ISC_TRUE;
1051 case 'D': /* was -dd */
1052 debugging = ISC_TRUE;
1053 ddebugging = ISC_TRUE;
1058 local_only = ISC_TRUE;
1061 result = isc_parse_uint32(&i, isc_commandline_argument,
1063 if (result != ISC_R_SUCCESS) {
1064 fprintf(stderr, "bad library debug value "
1065 "'%s'\n", isc_commandline_argument);
1071 keystr = isc_commandline_argument;
1077 keyfile = isc_commandline_argument;
1080 usegsstsig = ISC_TRUE;
1081 use_win2k_gsstsig = ISC_FALSE;
1084 usegsstsig = ISC_TRUE;
1085 use_win2k_gsstsig = ISC_TRUE;
1088 result = isc_parse_uint16(&dnsport,
1089 isc_commandline_argument, 10);
1090 if (result != ISC_R_SUCCESS) {
1091 fprintf(stderr, "bad port number "
1092 "'%s'\n", isc_commandline_argument);
1097 result = isc_parse_uint32(&timeout,
1098 isc_commandline_argument, 10);
1099 if (result != ISC_R_SUCCESS) {
1100 fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument);
1107 result = isc_parse_uint32(&udp_timeout,
1108 isc_commandline_argument, 10);
1109 if (result != ISC_R_SUCCESS) {
1110 fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument);
1113 if (udp_timeout == 0)
1114 udp_timeout = UINT_MAX;
1117 result = isc_parse_uint32(&udp_retries,
1118 isc_commandline_argument, 10);
1119 if (result != ISC_R_SUCCESS) {
1120 fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument);
1126 setup_entropy(mctx, isc_commandline_argument, ectx);
1130 fprintf(stderr, "%s: unhandled option: %c\n",
1131 argv[0], isc_commandline_option);
1135 if (keyfile != NULL && keystr != NULL) {
1136 fprintf(stderr, "%s: cannot specify both -k and -y\n",
1142 if (usegsstsig && (keyfile != NULL || keystr != NULL)) {
1143 fprintf(stderr, "%s: cannot specify -g with -k or -y\n",
1149 fprintf(stderr, "%s: cannot specify -g or -o, " \
1150 "program not linked with GSS API Library\n",
1156 if (argv[isc_commandline_index] != NULL) {
1157 if (strcmp(argv[isc_commandline_index], "-") == 0) {
1160 result = isc_stdio_open(argv[isc_commandline_index],
1162 if (result != ISC_R_SUCCESS) {
1163 fprintf(stderr, "could not open '%s': %s\n",
1164 argv[isc_commandline_index],
1165 isc_result_totext(result));
1169 interactive = ISC_FALSE;
1174 parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
1175 isc_result_t result;
1177 isc_buffer_t *namebuf = NULL;
1178 isc_buffer_t source;
1180 word = nsu_strsep(cmdlinep, " \t\r\n");
1181 if (word == NULL || *word == 0) {
1182 fprintf(stderr, "could not read owner name\n");
1183 return (STATUS_SYNTAX);
1186 result = dns_message_gettempname(msg, namep);
1187 check_result(result, "dns_message_gettempname");
1188 result = isc_buffer_allocate(gmctx, &namebuf, DNS_NAME_MAXWIRE);
1189 check_result(result, "isc_buffer_allocate");
1190 dns_name_init(*namep, NULL);
1191 dns_name_setbuffer(*namep, namebuf);
1192 dns_message_takebuffer(msg, &namebuf);
1193 isc_buffer_init(&source, word, strlen(word));
1194 isc_buffer_add(&source, strlen(word));
1195 result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL);
1196 check_result(result, "dns_name_fromtext");
1197 isc_buffer_invalidate(&source);
1198 return (STATUS_MORE);
1202 parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass,
1203 dns_rdatatype_t rdatatype, dns_message_t *msg,
1206 char *cmdline = *cmdlinep;
1207 isc_buffer_t source, *buf = NULL, *newbuf = NULL;
1209 isc_lex_t *lex = NULL;
1210 dns_rdatacallbacks_t callbacks;
1211 isc_result_t result;
1213 if (cmdline == NULL) {
1214 rdata->flags = DNS_RDATA_UPDATE;
1215 return (STATUS_MORE);
1218 while (*cmdline != 0 && isspace((unsigned char)*cmdline))
1221 if (*cmdline != 0) {
1222 dns_rdatacallbacks_init(&callbacks);
1223 result = isc_lex_create(gmctx, strlen(cmdline), &lex);
1224 check_result(result, "isc_lex_create");
1225 isc_buffer_init(&source, cmdline, strlen(cmdline));
1226 isc_buffer_add(&source, strlen(cmdline));
1227 result = isc_lex_openbuffer(lex, &source);
1228 check_result(result, "isc_lex_openbuffer");
1229 result = isc_buffer_allocate(gmctx, &buf, MAXWIRE);
1230 check_result(result, "isc_buffer_allocate");
1231 result = dns_rdata_fromtext(NULL, rdataclass, rdatatype, lex,
1232 dns_rootname, 0, gmctx, buf,
1234 isc_lex_destroy(&lex);
1235 if (result == ISC_R_SUCCESS) {
1236 isc_buffer_usedregion(buf, &r);
1237 result = isc_buffer_allocate(gmctx, &newbuf, r.length);
1238 check_result(result, "isc_buffer_allocate");
1239 isc_buffer_putmem(newbuf, r.base, r.length);
1240 isc_buffer_usedregion(newbuf, &r);
1241 dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r);
1242 isc_buffer_free(&buf);
1243 dns_message_takebuffer(msg, &newbuf);
1245 fprintf(stderr, "invalid rdata format: %s\n",
1246 isc_result_totext(result));
1247 isc_buffer_free(&buf);
1248 return (STATUS_SYNTAX);
1251 rdata->flags = DNS_RDATA_UPDATE;
1253 *cmdlinep = cmdline;
1254 return (STATUS_MORE);
1258 make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) {
1259 isc_result_t result;
1261 dns_name_t *name = NULL;
1262 isc_textregion_t region;
1263 dns_rdataset_t *rdataset = NULL;
1264 dns_rdatalist_t *rdatalist = NULL;
1265 dns_rdataclass_t rdataclass;
1266 dns_rdatatype_t rdatatype;
1267 dns_rdata_t *rdata = NULL;
1268 isc_uint16_t retval;
1270 ddebug("make_prereq()");
1273 * Read the owner name
1275 retval = parse_name(&cmdline, updatemsg, &name);
1276 if (retval != STATUS_MORE)
1280 * If this is an rrset prereq, read the class or type.
1283 word = nsu_strsep(&cmdline, " \t\r\n");
1284 if (word == NULL || *word == 0) {
1285 fprintf(stderr, "could not read class or type\n");
1289 region.length = strlen(word);
1290 result = dns_rdataclass_fromtext(&rdataclass, ®ion);
1291 if (result == ISC_R_SUCCESS) {
1292 if (!setzoneclass(rdataclass)) {
1293 fprintf(stderr, "class mismatch: %s\n", word);
1297 * Now read the type.
1299 word = nsu_strsep(&cmdline, " \t\r\n");
1300 if (word == NULL || *word == 0) {
1301 fprintf(stderr, "could not read type\n");
1305 region.length = strlen(word);
1306 result = dns_rdatatype_fromtext(&rdatatype, ®ion);
1307 if (result != ISC_R_SUCCESS) {
1308 fprintf(stderr, "invalid type: %s\n", word);
1312 rdataclass = getzoneclass();
1313 result = dns_rdatatype_fromtext(&rdatatype, ®ion);
1314 if (result != ISC_R_SUCCESS) {
1315 fprintf(stderr, "invalid type: %s\n", word);
1320 rdatatype = dns_rdatatype_any;
1322 result = dns_message_gettemprdata(updatemsg, &rdata);
1323 check_result(result, "dns_message_gettemprdata");
1325 dns_rdata_init(rdata);
1327 if (isrrset && ispositive) {
1328 retval = parse_rdata(&cmdline, rdataclass, rdatatype,
1330 if (retval != STATUS_MORE)
1333 rdata->flags = DNS_RDATA_UPDATE;
1335 result = dns_message_gettemprdatalist(updatemsg, &rdatalist);
1336 check_result(result, "dns_message_gettemprdatalist");
1337 result = dns_message_gettemprdataset(updatemsg, &rdataset);
1338 check_result(result, "dns_message_gettemprdataset");
1339 rdatalist->type = rdatatype;
1341 if (isrrset && rdata->data != NULL)
1342 rdatalist->rdclass = rdataclass;
1344 rdatalist->rdclass = dns_rdataclass_any;
1346 rdatalist->rdclass = dns_rdataclass_none;
1347 rdata->rdclass = rdatalist->rdclass;
1348 rdata->type = rdatatype;
1349 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1350 dns_rdataset_init(rdataset);
1351 dns_rdatalist_tordataset(rdatalist, rdataset);
1352 ISC_LIST_INIT(name->list);
1353 ISC_LIST_APPEND(name->list, rdataset, link);
1354 dns_message_addname(updatemsg, name, DNS_SECTION_PREREQUISITE);
1355 return (STATUS_MORE);
1359 dns_message_puttempname(updatemsg, &name);
1360 return (STATUS_SYNTAX);
1364 evaluate_prereq(char *cmdline) {
1366 isc_boolean_t ispositive, isrrset;
1368 ddebug("evaluate_prereq()");
1369 word = nsu_strsep(&cmdline, " \t\r\n");
1370 if (word == NULL || *word == 0) {
1371 fprintf(stderr, "could not read operation code\n");
1372 return (STATUS_SYNTAX);
1374 if (strcasecmp(word, "nxdomain") == 0) {
1375 ispositive = ISC_FALSE;
1376 isrrset = ISC_FALSE;
1377 } else if (strcasecmp(word, "yxdomain") == 0) {
1378 ispositive = ISC_TRUE;
1379 isrrset = ISC_FALSE;
1380 } else if (strcasecmp(word, "nxrrset") == 0) {
1381 ispositive = ISC_FALSE;
1383 } else if (strcasecmp(word, "yxrrset") == 0) {
1384 ispositive = ISC_TRUE;
1387 fprintf(stderr, "incorrect operation code: %s\n", word);
1388 return (STATUS_SYNTAX);
1390 return (make_prereq(cmdline, ispositive, isrrset));
1394 evaluate_server(char *cmdline) {
1395 char *word, *server;
1399 fprintf(stderr, "cannot reset server in localhost-only mode\n");
1400 return (STATUS_SYNTAX);
1403 word = nsu_strsep(&cmdline, " \t\r\n");
1404 if (word == NULL || *word == 0) {
1405 fprintf(stderr, "could not read server name\n");
1406 return (STATUS_SYNTAX);
1410 word = nsu_strsep(&cmdline, " \t\r\n");
1411 if (word == NULL || *word == 0)
1415 port = strtol(word, &endp, 10);
1417 fprintf(stderr, "port '%s' is not numeric\n", word);
1418 return (STATUS_SYNTAX);
1419 } else if (port < 1 || port > 65535) {
1420 fprintf(stderr, "port '%s' is out of range "
1421 "(1 to 65535)\n", word);
1422 return (STATUS_SYNTAX);
1426 if (servers != NULL) {
1427 if (master_servers == servers)
1428 master_servers = NULL;
1429 isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
1432 default_servers = ISC_FALSE;
1434 ns_total = MAX_SERVERADDRS;
1436 servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
1437 if (servers == NULL)
1438 fatal("out of memory");
1440 memset(servers, 0, ns_total * sizeof(isc_sockaddr_t));
1441 get_addresses(server, (in_port_t)port, servers, ns_total);
1443 return (STATUS_MORE);
1447 evaluate_local(char *cmdline) {
1451 struct in6_addr in6;
1453 word = nsu_strsep(&cmdline, " \t\r\n");
1454 if (word == NULL || *word == 0) {
1455 fprintf(stderr, "could not read server name\n");
1456 return (STATUS_SYNTAX);
1460 word = nsu_strsep(&cmdline, " \t\r\n");
1461 if (word == NULL || *word == 0)
1465 port = strtol(word, &endp, 10);
1467 fprintf(stderr, "port '%s' is not numeric\n", word);
1468 return (STATUS_SYNTAX);
1469 } else if (port < 1 || port > 65535) {
1470 fprintf(stderr, "port '%s' is out of range "
1471 "(1 to 65535)\n", word);
1472 return (STATUS_SYNTAX);
1476 if (have_ipv6 && inet_pton(AF_INET6, local, &in6) == 1) {
1477 if (localaddr6 == NULL)
1478 localaddr6 = isc_mem_get(gmctx, sizeof(isc_sockaddr_t));
1479 if (localaddr6 == NULL)
1480 fatal("out of memory");
1481 isc_sockaddr_fromin6(localaddr6, &in6, (in_port_t)port);
1482 } else if (have_ipv4 && inet_pton(AF_INET, local, &in4) == 1) {
1483 if (localaddr4 == NULL)
1484 localaddr4 = isc_mem_get(gmctx, sizeof(isc_sockaddr_t));
1485 if (localaddr4 == NULL)
1486 fatal("out of memory");
1487 isc_sockaddr_fromin(localaddr4, &in4, (in_port_t)port);
1489 fprintf(stderr, "invalid address %s", local);
1490 return (STATUS_SYNTAX);
1493 return (STATUS_MORE);
1497 evaluate_key(char *cmdline) {
1501 isc_result_t result;
1502 dns_fixedname_t fkeyname;
1503 dns_name_t *mykeyname;
1505 unsigned char *secret = NULL;
1506 isc_buffer_t secretbuf;
1507 dns_name_t *hmacname = NULL;
1508 isc_uint16_t digestbits = 0;
1511 namestr = nsu_strsep(&cmdline, " \t\r\n");
1512 if (namestr == NULL || *namestr == 0) {
1513 fprintf(stderr, "could not read key name\n");
1514 return (STATUS_SYNTAX);
1517 dns_fixedname_init(&fkeyname);
1518 mykeyname = dns_fixedname_name(&fkeyname);
1520 n = strchr(namestr, ':');
1522 digestbits = parse_hmac(&hmacname, namestr, n - namestr);
1525 hmacname = DNS_TSIG_HMACMD5_NAME;
1527 isc_buffer_init(&b, namestr, strlen(namestr));
1528 isc_buffer_add(&b, strlen(namestr));
1529 result = dns_name_fromtext(mykeyname, &b, dns_rootname, 0, NULL);
1530 if (result != ISC_R_SUCCESS) {
1531 fprintf(stderr, "could not parse key name\n");
1532 return (STATUS_SYNTAX);
1535 secretstr = nsu_strsep(&cmdline, "\r\n");
1536 if (secretstr == NULL || *secretstr == 0) {
1537 fprintf(stderr, "could not read key secret\n");
1538 return (STATUS_SYNTAX);
1540 secretlen = strlen(secretstr) * 3 / 4;
1541 secret = isc_mem_allocate(gmctx, secretlen);
1543 fatal("out of memory");
1545 isc_buffer_init(&secretbuf, secret, secretlen);
1546 result = isc_base64_decodestring(secretstr, &secretbuf);
1547 if (result != ISC_R_SUCCESS) {
1548 fprintf(stderr, "could not create key from %s: %s\n",
1549 secretstr, isc_result_totext(result));
1550 isc_mem_free(gmctx, secret);
1551 return (STATUS_SYNTAX);
1553 secretlen = isc_buffer_usedlength(&secretbuf);
1555 if (tsigkey != NULL)
1556 dns_tsigkey_detach(&tsigkey);
1557 result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen,
1558 ISC_FALSE, NULL, 0, 0, gmctx, NULL,
1560 isc_mem_free(gmctx, secret);
1561 if (result != ISC_R_SUCCESS) {
1562 fprintf(stderr, "could not create key from %s %s: %s\n",
1563 namestr, secretstr, dns_result_totext(result));
1564 return (STATUS_SYNTAX);
1566 dst_key_setbits(tsigkey->key, digestbits);
1567 return (STATUS_MORE);
1571 evaluate_zone(char *cmdline) {
1574 isc_result_t result;
1576 word = nsu_strsep(&cmdline, " \t\r\n");
1577 if (word == NULL || *word == 0) {
1578 fprintf(stderr, "could not read zone name\n");
1579 return (STATUS_SYNTAX);
1582 dns_fixedname_init(&fuserzone);
1583 userzone = dns_fixedname_name(&fuserzone);
1584 isc_buffer_init(&b, word, strlen(word));
1585 isc_buffer_add(&b, strlen(word));
1586 result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL);
1587 if (result != ISC_R_SUCCESS) {
1588 userzone = NULL; /* Lest it point to an invalid name */
1589 fprintf(stderr, "could not parse zone name\n");
1590 return (STATUS_SYNTAX);
1593 return (STATUS_MORE);
1597 evaluate_realm(char *cmdline) {
1603 if (realm != NULL) {
1604 isc_mem_free(gmctx, realm);
1608 word = nsu_strsep(&cmdline, " \t\r\n");
1609 if (word == NULL || *word == 0)
1610 return (STATUS_MORE);
1612 n = snprintf(buf, sizeof(buf), "@%s", word);
1613 if (n < 0 || (size_t)n >= sizeof(buf))
1614 fatal("realm is too long");
1615 realm = isc_mem_strdup(gmctx, buf);
1617 fatal("out of memory");
1618 return (STATUS_MORE);
1621 return (STATUS_SYNTAX);
1626 evaluate_ttl(char *cmdline) {
1628 isc_result_t result;
1631 word = nsu_strsep(&cmdline, " \t\r\n");
1632 if (word == NULL || *word == 0) {
1633 fprintf(stderr, "could not ttl\n");
1634 return (STATUS_SYNTAX);
1637 if (!strcasecmp(word, "none")) {
1639 default_ttl_set = ISC_FALSE;
1640 return (STATUS_MORE);
1643 result = isc_parse_uint32(&ttl, word, 10);
1644 if (result != ISC_R_SUCCESS)
1645 return (STATUS_SYNTAX);
1647 if (ttl > TTL_MAX) {
1648 fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
1650 return (STATUS_SYNTAX);
1653 default_ttl_set = ISC_TRUE;
1655 return (STATUS_MORE);
1659 evaluate_class(char *cmdline) {
1662 isc_result_t result;
1663 dns_rdataclass_t rdclass;
1665 word = nsu_strsep(&cmdline, " \t\r\n");
1666 if (word == NULL || *word == 0) {
1667 fprintf(stderr, "could not read class name\n");
1668 return (STATUS_SYNTAX);
1672 r.length = strlen(word);
1673 result = dns_rdataclass_fromtext(&rdclass, &r);
1674 if (result != ISC_R_SUCCESS) {
1675 fprintf(stderr, "could not parse class name: %s\n", word);
1676 return (STATUS_SYNTAX);
1679 case dns_rdataclass_none:
1680 case dns_rdataclass_any:
1681 case dns_rdataclass_reserved0:
1682 fprintf(stderr, "bad default class: %s\n", word);
1683 return (STATUS_SYNTAX);
1685 defaultclass = rdclass;
1688 return (STATUS_MORE);
1692 update_addordelete(char *cmdline, isc_boolean_t isdelete) {
1693 isc_result_t result;
1694 dns_name_t *name = NULL;
1697 dns_rdataclass_t rdataclass;
1698 dns_rdatatype_t rdatatype;
1699 dns_rdata_t *rdata = NULL;
1700 dns_rdatalist_t *rdatalist = NULL;
1701 dns_rdataset_t *rdataset = NULL;
1702 isc_textregion_t region;
1703 isc_uint16_t retval;
1705 ddebug("update_addordelete()");
1708 * Read the owner name.
1710 retval = parse_name(&cmdline, updatemsg, &name);
1711 if (retval != STATUS_MORE)
1714 result = dns_message_gettemprdata(updatemsg, &rdata);
1715 check_result(result, "dns_message_gettemprdata");
1717 dns_rdata_init(rdata);
1720 * If this is an add, read the TTL and verify that it's in range.
1721 * If it's a delete, ignore a TTL if present (for compatibility).
1723 word = nsu_strsep(&cmdline, " \t\r\n");
1724 if (word == NULL || *word == 0) {
1726 fprintf(stderr, "could not read owner ttl\n");
1731 rdataclass = dns_rdataclass_any;
1732 rdatatype = dns_rdatatype_any;
1733 rdata->flags = DNS_RDATA_UPDATE;
1737 result = isc_parse_uint32(&ttl, word, 10);
1738 if (result != ISC_R_SUCCESS) {
1742 } else if (default_ttl_set) {
1746 fprintf(stderr, "ttl '%s': %s\n", word,
1747 isc_result_totext(result));
1754 else if (ttl > TTL_MAX) {
1755 fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
1761 * Read the class or type.
1763 word = nsu_strsep(&cmdline, " \t\r\n");
1765 if (word == NULL || *word == 0) {
1767 rdataclass = dns_rdataclass_any;
1768 rdatatype = dns_rdatatype_any;
1769 rdata->flags = DNS_RDATA_UPDATE;
1772 fprintf(stderr, "could not read class or type\n");
1777 region.length = strlen(word);
1778 rdataclass = dns_rdataclass_any;
1779 result = dns_rdataclass_fromtext(&rdataclass, ®ion);
1780 if (result == ISC_R_SUCCESS && rdataclass != dns_rdataclass_any) {
1781 if (!setzoneclass(rdataclass)) {
1782 fprintf(stderr, "class mismatch: %s\n", word);
1786 * Now read the type.
1788 word = nsu_strsep(&cmdline, " \t\r\n");
1789 if (word == NULL || *word == 0) {
1791 rdataclass = dns_rdataclass_any;
1792 rdatatype = dns_rdatatype_any;
1793 rdata->flags = DNS_RDATA_UPDATE;
1796 fprintf(stderr, "could not read type\n");
1801 region.length = strlen(word);
1802 result = dns_rdatatype_fromtext(&rdatatype, ®ion);
1803 if (result != ISC_R_SUCCESS) {
1804 fprintf(stderr, "'%s' is not a valid type: %s\n",
1805 word, isc_result_totext(result));
1809 rdataclass = getzoneclass();
1810 result = dns_rdatatype_fromtext(&rdatatype, ®ion);
1811 if (result != ISC_R_SUCCESS) {
1812 fprintf(stderr, "'%s' is not a valid class or type: "
1813 "%s\n", word, isc_result_totext(result));
1818 retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg,
1820 if (retval != STATUS_MORE)
1824 if ((rdata->flags & DNS_RDATA_UPDATE) != 0)
1825 rdataclass = dns_rdataclass_any;
1827 rdataclass = dns_rdataclass_none;
1829 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
1830 fprintf(stderr, "could not read rdata\n");
1837 result = dns_message_gettemprdatalist(updatemsg, &rdatalist);
1838 check_result(result, "dns_message_gettemprdatalist");
1839 result = dns_message_gettemprdataset(updatemsg, &rdataset);
1840 check_result(result, "dns_message_gettemprdataset");
1841 rdatalist->type = rdatatype;
1842 rdatalist->rdclass = rdataclass;
1843 rdatalist->covers = rdatatype;
1844 rdatalist->ttl = (dns_ttl_t)ttl;
1845 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1846 dns_rdataset_init(rdataset);
1847 dns_rdatalist_tordataset(rdatalist, rdataset);
1848 ISC_LIST_INIT(name->list);
1849 ISC_LIST_APPEND(name->list, rdataset, link);
1850 dns_message_addname(updatemsg, name, DNS_SECTION_UPDATE);
1851 return (STATUS_MORE);
1855 dns_message_puttempname(updatemsg, &name);
1856 dns_message_puttemprdata(updatemsg, &rdata);
1857 return (STATUS_SYNTAX);
1861 evaluate_update(char *cmdline) {
1863 isc_boolean_t isdelete;
1865 ddebug("evaluate_update()");
1866 word = nsu_strsep(&cmdline, " \t\r\n");
1867 if (word == NULL || *word == 0) {
1868 fprintf(stderr, "could not read operation code\n");
1869 return (STATUS_SYNTAX);
1871 if (strcasecmp(word, "delete") == 0)
1872 isdelete = ISC_TRUE;
1873 else if (strcasecmp(word, "del") == 0)
1874 isdelete = ISC_TRUE;
1875 else if (strcasecmp(word, "add") == 0)
1876 isdelete = ISC_FALSE;
1878 fprintf(stderr, "incorrect operation code: %s\n", word);
1879 return (STATUS_SYNTAX);
1881 return (update_addordelete(cmdline, isdelete));
1885 setzone(dns_name_t *zonename) {
1886 isc_result_t result;
1887 dns_name_t *name = NULL;
1888 dns_rdataset_t *rdataset = NULL;
1890 result = dns_message_firstname(updatemsg, DNS_SECTION_ZONE);
1891 if (result == ISC_R_SUCCESS) {
1892 dns_message_currentname(updatemsg, DNS_SECTION_ZONE, &name);
1893 dns_message_removename(updatemsg, name, DNS_SECTION_ZONE);
1894 for (rdataset = ISC_LIST_HEAD(name->list);
1896 rdataset = ISC_LIST_HEAD(name->list)) {
1897 ISC_LIST_UNLINK(name->list, rdataset, link);
1898 dns_rdataset_disassociate(rdataset);
1899 dns_message_puttemprdataset(updatemsg, &rdataset);
1901 dns_message_puttempname(updatemsg, &name);
1904 if (zonename != NULL) {
1905 result = dns_message_gettempname(updatemsg, &name);
1906 check_result(result, "dns_message_gettempname");
1907 dns_name_init(name, NULL);
1908 dns_name_clone(zonename, name);
1909 result = dns_message_gettemprdataset(updatemsg, &rdataset);
1910 check_result(result, "dns_message_gettemprdataset");
1911 dns_rdataset_makequestion(rdataset, getzoneclass(),
1913 ISC_LIST_INIT(name->list);
1914 ISC_LIST_APPEND(name->list, rdataset, link);
1915 dns_message_addname(updatemsg, name, DNS_SECTION_ZONE);
1920 show_message(FILE *stream, dns_message_t *msg, const char *description) {
1921 isc_result_t result;
1922 isc_buffer_t *buf = NULL;
1925 ddebug("show_message()");
1931 if (bufsz > MAXTEXT) {
1932 fprintf(stderr, "could not allocate large enough "
1933 "buffer to display message\n");
1937 isc_buffer_free(&buf);
1938 result = isc_buffer_allocate(gmctx, &buf, bufsz);
1939 check_result(result, "isc_buffer_allocate");
1940 result = dns_message_totext(msg, style, 0, buf);
1942 } while (result == ISC_R_NOSPACE);
1943 if (result != ISC_R_SUCCESS) {
1944 fprintf(stderr, "could not convert message to text format.\n");
1945 isc_buffer_free(&buf);
1948 fprintf(stream, "%s\n%.*s", description,
1949 (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf));
1950 isc_buffer_free(&buf);
1954 do_next_command(char *cmdline) {
1957 ddebug("do_next_command()");
1958 word = nsu_strsep(&cmdline, " \t\r\n");
1960 if (word == NULL || *word == 0)
1961 return (STATUS_SEND);
1963 return (STATUS_MORE);
1964 if (strcasecmp(word, "quit") == 0)
1965 return (STATUS_QUIT);
1966 if (strcasecmp(word, "prereq") == 0)
1967 return (evaluate_prereq(cmdline));
1968 if (strcasecmp(word, "nxdomain") == 0)
1969 return (make_prereq(cmdline, ISC_FALSE, ISC_FALSE));
1970 if (strcasecmp(word, "yxdomain") == 0)
1971 return (make_prereq(cmdline, ISC_TRUE, ISC_FALSE));
1972 if (strcasecmp(word, "nxrrset") == 0)
1973 return (make_prereq(cmdline, ISC_FALSE, ISC_TRUE));
1974 if (strcasecmp(word, "yxrrset") == 0)
1975 return (make_prereq(cmdline, ISC_TRUE, ISC_TRUE));
1976 if (strcasecmp(word, "update") == 0)
1977 return (evaluate_update(cmdline));
1978 if (strcasecmp(word, "delete") == 0)
1979 return (update_addordelete(cmdline, ISC_TRUE));
1980 if (strcasecmp(word, "del") == 0)
1981 return (update_addordelete(cmdline, ISC_TRUE));
1982 if (strcasecmp(word, "add") == 0)
1983 return (update_addordelete(cmdline, ISC_FALSE));
1984 if (strcasecmp(word, "server") == 0)
1985 return (evaluate_server(cmdline));
1986 if (strcasecmp(word, "local") == 0)
1987 return (evaluate_local(cmdline));
1988 if (strcasecmp(word, "zone") == 0)
1989 return (evaluate_zone(cmdline));
1990 if (strcasecmp(word, "class") == 0)
1991 return (evaluate_class(cmdline));
1992 if (strcasecmp(word, "send") == 0)
1993 return (STATUS_SEND);
1994 if (strcasecmp(word, "debug") == 0) {
1996 ddebugging = ISC_TRUE;
1998 debugging = ISC_TRUE;
1999 return (STATUS_MORE);
2001 if (strcasecmp(word, "ttl") == 0)
2002 return (evaluate_ttl(cmdline));
2003 if (strcasecmp(word, "show") == 0) {
2004 show_message(stdout, updatemsg, "Outgoing update query:");
2005 return (STATUS_MORE);
2007 if (strcasecmp(word, "answer") == 0) {
2009 show_message(stdout, answer, "Answer:");
2010 return (STATUS_MORE);
2012 if (strcasecmp(word, "key") == 0) {
2013 usegsstsig = ISC_FALSE;
2014 return (evaluate_key(cmdline));
2016 if (strcasecmp(word, "realm") == 0)
2017 return (evaluate_realm(cmdline));
2018 if (strcasecmp(word, "gsstsig") == 0) {
2020 usegsstsig = ISC_TRUE;
2021 use_win2k_gsstsig = ISC_FALSE;
2023 fprintf(stderr, "gsstsig not supported\n");
2025 return (STATUS_MORE);
2027 if (strcasecmp(word, "oldgsstsig") == 0) {
2029 usegsstsig = ISC_TRUE;
2030 use_win2k_gsstsig = ISC_TRUE;
2032 fprintf(stderr, "gsstsig not supported\n");
2034 return (STATUS_MORE);
2036 if (strcasecmp(word, "help") == 0) {
2038 "nsupdate " VERSION ":\n"
2039 "local address [port] (set local resolver)\n"
2040 "server address [port] (set master server for zone)\n"
2041 "send (send the update request)\n"
2042 "show (show the update request)\n"
2043 "answer (show the answer to the last request)\n"
2044 "quit (quit, any pending update is not sent\n"
2045 "help (display this message_\n"
2046 "key [hmac:]keyname secret (use TSIG to sign the request)\n"
2047 "gsstsig (use GSS_TSIG to sign the request)\n"
2048 "oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n"
2049 "zone name (set the zone to be updated)\n"
2050 "class CLASS (set the zone's DNS class, e.g. IN (default), CH)\n"
2051 "[prereq] nxdomain name (does this name not exist)\n"
2052 "[prereq] yxdomain name (does this name exist)\n"
2053 "[prereq] nxrrset .... (does this RRset exist)\n"
2054 "[prereq] yxrrset .... (does this RRset not exist)\n"
2055 "[update] add .... (add the given record to the zone)\n"
2056 "[update] del[ete] .... (remove the given record(s) from the zone)\n");
2057 return (STATUS_MORE);
2059 if (strcasecmp(word, "version") == 0) {
2060 fprintf(stdout, "nsupdate " VERSION "\n");
2061 return (STATUS_MORE);
2063 fprintf(stderr, "incorrect section name: %s\n", word);
2064 return (STATUS_SYNTAX);
2068 get_next_command(void) {
2069 isc_uint16_t result = STATUS_QUIT;
2070 char cmdlinebuf[MAXCMD];
2075 #ifdef HAVE_READLINE
2076 cmdline = readline("> ");
2077 if (cmdline != NULL)
2078 add_history(cmdline);
2080 fprintf(stdout, "> ");
2082 cmdline = fgets(cmdlinebuf, MAXCMD, input);
2085 cmdline = fgets(cmdlinebuf, MAXCMD, input);
2088 if (cmdline != NULL) {
2089 char *tmp = cmdline;
2092 * Normalize input by removing any eol as readline()
2093 * removes eol but fgets doesn't.
2095 (void)nsu_strsep(&tmp, "\r\n");
2096 result = do_next_command(cmdline);
2098 #ifdef HAVE_READLINE
2105 static isc_boolean_t
2106 user_interaction(void) {
2107 isc_uint16_t result = STATUS_MORE;
2109 ddebug("user_interaction()");
2110 while ((result == STATUS_MORE) || (result == STATUS_SYNTAX)) {
2111 result = get_next_command();
2112 if (!interactive && result == STATUS_SYNTAX)
2113 fatal("syntax error");
2115 if (result == STATUS_SEND)
2123 isc_event_t *event = global_event;
2124 ddebug("done_update()");
2125 isc_task_send(global_task, &event);
2129 check_tsig_error(dns_rdataset_t *rdataset, isc_buffer_t *b) {
2130 isc_result_t result;
2131 dns_rdata_t rdata = DNS_RDATA_INIT;
2132 dns_rdata_any_tsig_t tsig;
2134 result = dns_rdataset_first(rdataset);
2135 check_result(result, "dns_rdataset_first");
2136 dns_rdataset_current(rdataset, &rdata);
2137 result = dns_rdata_tostruct(&rdata, &tsig, NULL);
2138 check_result(result, "dns_rdata_tostruct");
2139 if (tsig.error != 0) {
2140 if (isc_buffer_remaininglength(b) < 1)
2141 check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength");
2142 isc_buffer_putstr(b, "(" /*)*/);
2143 result = dns_tsigrcode_totext(tsig.error, b);
2144 check_result(result, "dns_tsigrcode_totext");
2145 if (isc_buffer_remaininglength(b) < 1)
2146 check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength");
2147 isc_buffer_putstr(b, /*(*/ ")");
2151 static isc_boolean_t
2152 next_master(const char *caller, isc_sockaddr_t *addr, isc_result_t eresult) {
2153 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2155 isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf));
2156 fprintf(stderr, "; Communication with %s failed: %s\n",
2157 addrbuf, isc_result_totext(eresult));
2158 if (++master_inuse >= master_total)
2160 ddebug("%s: trying next server", caller);
2165 update_completed(isc_task_t *task, isc_event_t *event) {
2166 dns_requestevent_t *reqev = NULL;
2167 isc_result_t result;
2168 dns_request_t *request;
2172 ddebug("update_completed()");
2176 REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
2177 reqev = (dns_requestevent_t *)event;
2178 request = reqev->request;
2181 dns_request_destroy(&request);
2182 isc_event_free(&event);
2187 if (reqev->result != ISC_R_SUCCESS) {
2188 if (!next_master("recvsoa", &master_servers[master_inuse],
2190 seenerror = ISC_TRUE;
2194 ddebug("Destroying request [%p]", request);
2195 dns_request_destroy(&request);
2196 dns_message_renderreset(updatemsg);
2197 dns_message_settsigkey(updatemsg, NULL);
2198 /* XXX MPA fix zonename is freed already */
2199 send_update(zname, &master_servers[master_inuse]);
2200 isc_event_free(&event);
2204 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &answer);
2205 check_result(result, "dns_message_create");
2206 result = dns_request_getresponse(request, answer,
2207 DNS_MESSAGEPARSE_PRESERVEORDER);
2210 if (answer->verify_attempted)
2211 ddebug("tsig verification successful");
2213 case DNS_R_CLOCKSKEW:
2214 case DNS_R_EXPECTEDTSIG:
2215 case DNS_R_TSIGERRORSET:
2216 case DNS_R_TSIGVERIFYFAILURE:
2217 case DNS_R_UNEXPECTEDTSIG:
2220 if (usegsstsig && answer->rcode == dns_rcode_noerror) {
2222 * For MS DNS that violates RFC 2845, section 4.2
2227 fprintf(stderr, "; TSIG error with server: %s\n",
2228 isc_result_totext(result));
2229 seenerror = ISC_TRUE;
2232 check_result(result, "dns_request_getresponse");
2235 if (answer->rcode != dns_rcode_noerror) {
2236 seenerror = ISC_TRUE;
2240 dns_rdataset_t *rds;
2242 isc_buffer_init(&b, buf, sizeof(buf) - 1);
2243 result = dns_rcode_totext(answer->rcode, &b);
2244 check_result(result, "dns_rcode_totext");
2245 rds = dns_message_gettsig(answer, NULL);
2247 check_tsig_error(rds, &b);
2248 fprintf(stderr, "update failed: %.*s\n",
2249 (int)isc_buffer_usedlength(&b), buf);
2253 show_message(stderr, answer, "\nReply from update query:");
2256 dns_request_destroy(&request);
2258 dns_name_free(&tmpzonename, gmctx);
2259 dns_name_free(&restart_master, gmctx);
2261 isc_event_free(&event);
2266 send_update(dns_name_t *zone, isc_sockaddr_t *master) {
2267 isc_result_t result;
2268 dns_request_t *request = NULL;
2269 unsigned int options = DNS_REQUESTOPT_CASE;
2270 isc_sockaddr_t *srcaddr;
2272 ddebug("send_update()");
2277 options |= DNS_REQUESTOPT_TCP;
2278 if (tsigkey == NULL && sig0key != NULL) {
2279 result = dns_message_setsig0key(updatemsg, sig0key);
2280 check_result(result, "dns_message_setsig0key");
2283 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2285 isc_sockaddr_format(master, addrbuf, sizeof(addrbuf));
2286 fprintf(stderr, "Sending update to %s\n", addrbuf);
2289 if (isc_sockaddr_pf(master) == AF_INET6)
2290 srcaddr = localaddr6;
2292 srcaddr = localaddr4;
2294 /* Windows doesn't like the tsig name to be compressed. */
2295 if (updatemsg->tsigname)
2296 updatemsg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
2298 result = dns_request_createvia3(requestmgr, updatemsg, srcaddr,
2299 master, options, tsigkey, timeout,
2300 udp_timeout, udp_retries, global_task,
2301 update_completed, NULL, &request);
2302 check_result(result, "dns_request_createvia3");
2305 show_message(stdout, updatemsg, "Outgoing update query:");
2311 next_server(const char *caller, isc_sockaddr_t *addr, isc_result_t eresult) {
2312 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2314 isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf));
2315 fprintf(stderr, "; Communication with %s failed: %s\n",
2316 addrbuf, isc_result_totext(eresult));
2317 if (++ns_inuse >= ns_total)
2318 fatal("could not reach any name server");
2320 ddebug("%s: trying next server", caller);
2324 recvsoa(isc_task_t *task, isc_event_t *event) {
2325 dns_requestevent_t *reqev = NULL;
2326 dns_request_t *request = NULL;
2327 isc_result_t result, eresult;
2328 dns_message_t *rcvmsg = NULL;
2329 dns_section_t section;
2330 dns_name_t *name = NULL;
2331 dns_rdataset_t *soaset = NULL;
2332 dns_rdata_soa_t soa;
2333 dns_rdata_t soarr = DNS_RDATA_INIT;
2336 nsu_requestinfo_t *reqinfo;
2337 dns_message_t *soaquery = NULL;
2338 isc_sockaddr_t *addr;
2339 isc_sockaddr_t *srcaddr;
2340 isc_boolean_t seencname = ISC_FALSE;
2342 unsigned int nlabels;
2346 ddebug("recvsoa()");
2350 REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
2351 reqev = (dns_requestevent_t *)event;
2352 request = reqev->request;
2353 eresult = reqev->result;
2354 reqinfo = reqev->ev_arg;
2355 soaquery = reqinfo->msg;
2356 addr = reqinfo->addr;
2359 dns_request_destroy(&request);
2360 dns_message_destroy(&soaquery);
2361 isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
2362 isc_event_free(&event);
2367 if (eresult != ISC_R_SUCCESS) {
2368 next_server("recvsoa", addr, eresult);
2369 ddebug("Destroying request [%p]", request);
2370 dns_request_destroy(&request);
2371 dns_message_renderreset(soaquery);
2372 dns_message_settsigkey(soaquery, NULL);
2373 sendrequest(&servers[ns_inuse], soaquery, &request);
2374 isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
2375 isc_event_free(&event);
2376 setzoneclass(dns_rdataclass_none);
2380 isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
2382 isc_event_free(&event);
2385 ddebug("About to create rcvmsg");
2386 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
2387 check_result(result, "dns_message_create");
2388 result = dns_request_getresponse(request, rcvmsg,
2389 DNS_MESSAGEPARSE_PRESERVEORDER);
2390 if (result == DNS_R_TSIGERRORSET && servers != NULL) {
2391 dns_message_destroy(&rcvmsg);
2392 ddebug("Destroying request [%p]", request);
2393 dns_request_destroy(&request);
2394 reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t));
2395 if (reqinfo == NULL)
2396 fatal("out of memory");
2397 reqinfo->msg = soaquery;
2398 reqinfo->addr = addr;
2399 dns_message_renderreset(soaquery);
2400 ddebug("retrying soa request without TSIG");
2402 if (isc_sockaddr_pf(addr) == AF_INET6)
2403 srcaddr = localaddr6;
2405 srcaddr = localaddr4;
2407 result = dns_request_createvia3(requestmgr, soaquery, srcaddr,
2411 global_task, recvsoa, reqinfo,
2413 check_result(result, "dns_request_createvia");
2417 check_result(result, "dns_request_getresponse");
2418 section = DNS_SECTION_ANSWER;
2421 show_message(stderr, rcvmsg, "Reply from SOA query:");
2423 if (rcvmsg->rcode != dns_rcode_noerror &&
2424 rcvmsg->rcode != dns_rcode_nxdomain)
2425 fatal("response to SOA query was unsuccessful");
2427 if (userzone != NULL && rcvmsg->rcode == dns_rcode_nxdomain) {
2428 char namebuf[DNS_NAME_FORMATSIZE];
2429 dns_name_format(userzone, namebuf, sizeof(namebuf));
2430 error("specified zone '%s' does not exist (NXDOMAIN)",
2432 dns_message_destroy(&rcvmsg);
2433 dns_request_destroy(&request);
2434 dns_message_destroy(&soaquery);
2435 ddebug("Out of recvsoa");
2437 seenerror = ISC_TRUE;
2443 section = DNS_SECTION_ANSWER;
2445 section = DNS_SECTION_AUTHORITY;
2449 result = dns_message_firstname(rcvmsg, section);
2450 if (result != ISC_R_SUCCESS) {
2454 while (result == ISC_R_SUCCESS) {
2456 dns_message_currentname(rcvmsg, section, &name);
2458 result = dns_message_findtype(name, dns_rdatatype_soa, 0,
2460 if (result == ISC_R_SUCCESS)
2462 if (section == DNS_SECTION_ANSWER) {
2463 dns_rdataset_t *tset = NULL;
2464 if (dns_message_findtype(name, dns_rdatatype_cname, 0,
2465 &tset) == ISC_R_SUCCESS ||
2466 dns_message_findtype(name, dns_rdatatype_dname, 0,
2467 &tset) == ISC_R_SUCCESS ) {
2468 seencname = ISC_TRUE;
2473 result = dns_message_nextname(rcvmsg, section);
2476 if (soaset == NULL && !seencname) {
2485 char namestr[DNS_NAME_FORMATSIZE];
2486 dns_name_format(name, namestr, sizeof(namestr));
2487 fprintf(stderr, "Found zone name: %s\n", namestr);
2490 result = dns_rdataset_first(soaset);
2491 check_result(result, "dns_rdataset_first");
2493 dns_rdata_init(&soarr);
2494 dns_rdataset_current(soaset, &soarr);
2495 result = dns_rdata_tostruct(&soarr, &soa, NULL);
2496 check_result(result, "dns_rdata_tostruct");
2498 dns_name_init(&master, NULL);
2499 dns_name_clone(&soa.origin, &master);
2504 if (userzone != NULL)
2510 char namestr[DNS_NAME_FORMATSIZE];
2511 dns_name_format(&master, namestr, sizeof(namestr));
2512 fprintf(stderr, "The master is: %s\n", namestr);
2515 if (default_servers) {
2516 char serverstr[DNS_NAME_MAXTEXT+1];
2520 isc_buffer_init(&buf, serverstr, sizeof(serverstr));
2521 result = dns_name_totext(&master, ISC_TRUE, &buf);
2522 check_result(result, "dns_name_totext");
2523 serverstr[isc_buffer_usedlength(&buf)] = 0;
2525 if (master_servers != NULL && master_servers != servers)
2526 isc_mem_put(gmctx, master_servers,
2527 master_total * sizeof(isc_sockaddr_t));
2528 master_total = MAX_SERVERADDRS;
2529 size = master_total * sizeof(isc_sockaddr_t);
2530 master_servers = isc_mem_get(gmctx, size);
2531 if (master_servers == NULL)
2532 fatal("out of memory");
2534 memset(master_servers, 0, size);
2535 get_addresses(serverstr, dnsport, master_servers, master_total);
2538 master_from_servers();
2539 dns_rdata_freestruct(&soa);
2543 dns_name_init(&tmpzonename, NULL);
2544 dns_name_dup(zname, gmctx, &tmpzonename);
2545 dns_name_init(&restart_master, NULL);
2546 dns_name_dup(&master, gmctx, &restart_master);
2547 start_gssrequest(&master);
2549 send_update(zname, &master_servers[master_inuse]);
2550 setzoneclass(dns_rdataclass_none);
2553 send_update(zname, &master_servers[master_inuse]);
2554 setzoneclass(dns_rdataclass_none);
2557 dns_message_destroy(&soaquery);
2558 dns_request_destroy(&request);
2561 dns_message_destroy(&rcvmsg);
2562 ddebug("Out of recvsoa");
2566 result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION);
2567 INSIST(result == ISC_R_SUCCESS);
2569 dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name);
2570 nlabels = dns_name_countlabels(name);
2572 fatal("could not find enclosing zone");
2573 dns_name_init(&tname, NULL);
2574 dns_name_getlabelsequence(name, 1, nlabels - 1, &tname);
2575 dns_name_clone(&tname, name);
2576 dns_request_destroy(&request);
2577 dns_message_renderreset(soaquery);
2578 dns_message_settsigkey(soaquery, NULL);
2579 sendrequest(&servers[ns_inuse], soaquery, &request);
2584 sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
2585 dns_request_t **request)
2587 isc_result_t result;
2588 nsu_requestinfo_t *reqinfo;
2589 isc_sockaddr_t *srcaddr;
2591 reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t));
2592 if (reqinfo == NULL)
2593 fatal("out of memory");
2595 reqinfo->addr = destaddr;
2597 if (isc_sockaddr_pf(destaddr) == AF_INET6)
2598 srcaddr = localaddr6;
2600 srcaddr = localaddr4;
2602 result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, 0,
2603 default_servers ? NULL : tsigkey,
2604 FIND_TIMEOUT * 20, FIND_TIMEOUT, 3,
2605 global_task, recvsoa, reqinfo, request);
2606 check_result(result, "dns_request_createvia");
2613 * Get the realm from the users kerberos ticket if possible
2616 get_ticket_realm(isc_mem_t *mctx) {
2620 krb5_principal princ;
2622 const char * ticket_realm;
2624 rc = krb5_init_context(&ctx);
2628 rc = krb5_cc_default(ctx, &ccache);
2630 krb5_free_context(ctx);
2634 rc = krb5_cc_get_principal(ctx, ccache, &princ);
2636 krb5_cc_close(ctx, ccache);
2637 krb5_free_context(ctx);
2641 rc = krb5_unparse_name(ctx, princ, &name);
2643 krb5_free_principal(ctx, princ);
2644 krb5_cc_close(ctx, ccache);
2645 krb5_free_context(ctx);
2649 ticket_realm = strrchr(name, '@');
2650 if (ticket_realm != NULL) {
2651 realm = isc_mem_strdup(mctx, ticket_realm);
2655 krb5_free_principal(ctx, princ);
2656 krb5_cc_close(ctx, ccache);
2657 krb5_free_context(ctx);
2658 if (realm != NULL && debugging)
2659 fprintf(stderr, "Found realm from ticket: %s\n", realm+1);
2663 failed_gssrequest() {
2664 seenerror = ISC_TRUE;
2666 dns_name_free(&tmpzonename, gmctx);
2667 dns_name_free(&restart_master, gmctx);
2673 start_gssrequest(dns_name_t *master) {
2674 gss_ctx_id_t context;
2676 isc_result_t result;
2677 isc_uint32_t val = 0;
2678 dns_message_t *rmsg = NULL;
2679 dns_request_t *request = NULL;
2680 dns_name_t *servname;
2681 dns_fixedname_t fname;
2682 char namestr[DNS_NAME_FORMATSIZE];
2683 char mykeystr[DNS_NAME_FORMATSIZE];
2684 char *err_message = NULL;
2686 debug("start_gssrequest");
2689 if (gssring != NULL)
2690 dns_tsigkeyring_detach(&gssring);
2692 result = dns_tsigkeyring_create(gmctx, &gssring);
2694 if (result != ISC_R_SUCCESS)
2695 fatal("dns_tsigkeyring_create failed: %s",
2696 isc_result_totext(result));
2698 dns_name_format(master, namestr, sizeof(namestr));
2699 if (kserver == NULL) {
2700 kserver = isc_mem_get(gmctx, sizeof(isc_sockaddr_t));
2701 if (kserver == NULL)
2702 fatal("out of memory");
2704 if (servers == NULL)
2705 get_addresses(namestr, dnsport, kserver, 1);
2707 memmove(kserver, &servers[ns_inuse], sizeof(isc_sockaddr_t));
2709 dns_fixedname_init(&fname);
2710 servname = dns_fixedname_name(&fname);
2713 get_ticket_realm(gmctx);
2715 result = isc_string_printf(servicename, sizeof(servicename),
2716 "DNS/%s%s", namestr, realm ? realm : "");
2717 if (result != ISC_R_SUCCESS)
2718 fatal("isc_string_printf(servicename) failed: %s",
2719 isc_result_totext(result));
2720 isc_buffer_init(&buf, servicename, strlen(servicename));
2721 isc_buffer_add(&buf, strlen(servicename));
2722 result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
2723 if (result != ISC_R_SUCCESS)
2724 fatal("dns_name_fromtext(servname) failed: %s",
2725 isc_result_totext(result));
2727 dns_fixedname_init(&fkname);
2728 keyname = dns_fixedname_name(&fkname);
2730 isc_random_get(&val);
2731 result = isc_string_printf(mykeystr, sizeof(mykeystr), "%u.sig-%s",
2733 if (result != ISC_R_SUCCESS)
2734 fatal("isc_string_printf(mykeystr) failed: %s",
2735 isc_result_totext(result));
2736 isc_buffer_init(&buf, mykeystr, strlen(mykeystr));
2737 isc_buffer_add(&buf, strlen(mykeystr));
2739 result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL);
2740 if (result != ISC_R_SUCCESS)
2741 fatal("dns_name_fromtext(keyname) failed: %s",
2742 isc_result_totext(result));
2744 /* Windows doesn't recognize name compression in the key name. */
2745 keyname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
2748 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &rmsg);
2749 if (result != ISC_R_SUCCESS)
2750 fatal("dns_message_create failed: %s",
2751 isc_result_totext(result));
2753 /* Build first request. */
2754 context = GSS_C_NO_CONTEXT;
2755 result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
2756 &context, use_win2k_gsstsig,
2757 gmctx, &err_message);
2758 if (result == ISC_R_FAILURE) {
2759 fprintf(stderr, "tkey query failed: %s\n",
2760 err_message != NULL ? err_message : "unknown error");
2763 if (result != ISC_R_SUCCESS)
2764 fatal("dns_tkey_buildgssquery failed: %s",
2765 isc_result_totext(result));
2767 send_gssrequest(kserver, rmsg, &request, context);
2772 dns_message_destroy(&rmsg);
2773 if (err_message != NULL)
2774 isc_mem_free(gmctx, err_message);
2775 failed_gssrequest();
2779 send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
2780 dns_request_t **request, gss_ctx_id_t context)
2782 isc_result_t result;
2783 nsu_gssinfo_t *reqinfo;
2784 unsigned int options = 0;
2785 isc_sockaddr_t *srcaddr;
2787 debug("send_gssrequest");
2788 reqinfo = isc_mem_get(gmctx, sizeof(nsu_gssinfo_t));
2789 if (reqinfo == NULL)
2790 fatal("out of memory");
2792 reqinfo->addr = destaddr;
2793 reqinfo->context = context;
2795 options |= DNS_REQUESTOPT_TCP;
2797 if (isc_sockaddr_pf(destaddr) == AF_INET6)
2798 srcaddr = localaddr6;
2800 srcaddr = localaddr4;
2802 result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr,
2803 options, tsigkey, FIND_TIMEOUT * 20,
2804 FIND_TIMEOUT, 3, global_task, recvgss,
2806 check_result(result, "dns_request_createvia3");
2808 show_message(stdout, msg, "Outgoing update query:");
2813 recvgss(isc_task_t *task, isc_event_t *event) {
2814 dns_requestevent_t *reqev = NULL;
2815 dns_request_t *request = NULL;
2816 isc_result_t result, eresult;
2817 dns_message_t *rcvmsg = NULL;
2818 nsu_gssinfo_t *reqinfo;
2819 dns_message_t *tsigquery = NULL;
2820 isc_sockaddr_t *addr;
2821 gss_ctx_id_t context;
2823 dns_name_t *servname;
2824 dns_fixedname_t fname;
2825 char *err_message = NULL;
2829 ddebug("recvgss()");
2833 REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
2834 reqev = (dns_requestevent_t *)event;
2835 request = reqev->request;
2836 eresult = reqev->result;
2837 reqinfo = reqev->ev_arg;
2838 tsigquery = reqinfo->msg;
2839 context = reqinfo->context;
2840 addr = reqinfo->addr;
2843 dns_request_destroy(&request);
2844 dns_message_destroy(&tsigquery);
2845 isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
2846 isc_event_free(&event);
2851 if (eresult != ISC_R_SUCCESS) {
2852 next_server("recvgss", addr, eresult);
2853 ddebug("Destroying request [%p]", request);
2854 dns_request_destroy(&request);
2855 dns_message_renderreset(tsigquery);
2856 sendrequest(&servers[ns_inuse], tsigquery, &request);
2857 isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
2858 isc_event_free(&event);
2861 isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
2863 isc_event_free(&event);
2866 ddebug("recvgss creating rcvmsg");
2867 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
2868 check_result(result, "dns_message_create");
2870 result = dns_request_getresponse(request, rcvmsg,
2871 DNS_MESSAGEPARSE_PRESERVEORDER);
2872 check_result(result, "dns_request_getresponse");
2875 show_message(stderr, rcvmsg,
2876 "recvmsg reply from GSS-TSIG query");
2878 if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) {
2879 ddebug("recvgss trying %s GSS-TSIG",
2880 use_win2k_gsstsig ? "Standard" : "Win2k");
2881 if (use_win2k_gsstsig)
2882 use_win2k_gsstsig = ISC_FALSE;
2884 use_win2k_gsstsig = ISC_TRUE;
2885 tried_other_gsstsig = ISC_TRUE;
2886 start_gssrequest(&restart_master);
2890 if (rcvmsg->rcode != dns_rcode_noerror &&
2891 rcvmsg->rcode != dns_rcode_nxdomain)
2892 fatal("response to GSS-TSIG query was unsuccessful");
2895 dns_fixedname_init(&fname);
2896 servname = dns_fixedname_name(&fname);
2897 isc_buffer_init(&buf, servicename, strlen(servicename));
2898 isc_buffer_add(&buf, strlen(servicename));
2899 result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
2900 check_result(result, "dns_name_fromtext");
2903 result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
2904 &context, &tsigkey, gssring,
2909 case DNS_R_CONTINUE:
2910 send_gssrequest(kserver, tsigquery, &request, context);
2915 * XXXSRA Waaay too much fun here. There's no good
2916 * reason why we need a TSIG here (the people who put
2917 * it into the spec admitted at the time that it was
2918 * not a security issue), and Windows clients don't
2919 * seem to work if named complies with the spec and
2920 * includes the gratuitous TSIG. So we're in the
2921 * bizarre situation of having to choose between
2922 * complying with a useless requirement in the spec
2923 * and interoperating. This is nuts. If we can
2924 * confirm this behavior, we should ask the WG to
2925 * consider removing the requirement for the
2926 * gratuitous TSIG here. For the moment, we ignore
2927 * the TSIG -- this too is a spec violation, but it's
2928 * the least insane thing to do.
2932 * Verify the signature.
2934 rcvmsg->state = DNS_SECTION_ANY;
2935 dns_message_setquerytsig(rcvmsg, NULL);
2936 result = dns_message_settsigkey(rcvmsg, tsigkey);
2937 check_result(result, "dns_message_settsigkey");
2938 result = dns_message_checksig(rcvmsg, NULL);
2939 ddebug("tsig verification: %s", dns_result_totext(result));
2940 check_result(result, "dns_message_checksig");
2943 send_update(&tmpzonename, &master_servers[master_inuse]);
2944 setzoneclass(dns_rdataclass_none);
2948 fatal("dns_tkey_negotiategss: %s %s",
2949 isc_result_totext(result),
2950 err_message != NULL ? err_message : "");
2954 dns_request_destroy(&request);
2955 dns_message_destroy(&tsigquery);
2957 dns_message_destroy(&rcvmsg);
2958 ddebug("Out of recvgss");
2963 start_update(void) {
2964 isc_result_t result;
2965 dns_rdataset_t *rdataset = NULL;
2966 dns_name_t *name = NULL;
2967 dns_request_t *request = NULL;
2968 dns_message_t *soaquery = NULL;
2969 dns_name_t *firstname;
2970 dns_section_t section = DNS_SECTION_UPDATE;
2972 ddebug("start_update()");
2975 dns_message_destroy(&answer);
2978 * If we have both the zone and the servers we have enough information
2979 * to send the update straight away otherwise we need to discover
2980 * the zone and / or the master server.
2982 if (userzone != NULL && !default_servers && !usegsstsig) {
2983 master_from_servers();
2984 send_update(userzone, &master_servers[master_inuse]);
2985 setzoneclass(dns_rdataclass_none);
2989 result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER,
2991 check_result(result, "dns_message_create");
2993 if (default_servers)
2994 soaquery->flags |= DNS_MESSAGEFLAG_RD;
2996 result = dns_message_gettempname(soaquery, &name);
2997 check_result(result, "dns_message_gettempname");
2999 result = dns_message_gettemprdataset(soaquery, &rdataset);
3000 check_result(result, "dns_message_gettemprdataset");
3002 dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa);
3004 if (userzone != NULL) {
3005 dns_name_init(name, NULL);
3006 dns_name_clone(userzone, name);
3008 dns_rdataset_t *tmprdataset;
3009 result = dns_message_firstname(updatemsg, section);
3010 if (result == ISC_R_NOMORE) {
3011 section = DNS_SECTION_PREREQUISITE;
3012 result = dns_message_firstname(updatemsg, section);
3014 if (result != ISC_R_SUCCESS) {
3015 dns_message_puttempname(soaquery, &name);
3016 dns_rdataset_disassociate(rdataset);
3017 dns_message_puttemprdataset(soaquery, &rdataset);
3018 dns_message_destroy(&soaquery);
3023 dns_message_currentname(updatemsg, section, &firstname);
3024 dns_name_init(name, NULL);
3025 dns_name_clone(firstname, name);
3027 * Looks to see if the first name references a DS record
3028 * and if that name is not the root remove a label as DS
3029 * records live in the parent zone so we need to start our
3030 * search one label up.
3032 tmprdataset = ISC_LIST_HEAD(firstname->list);
3033 if (section == DNS_SECTION_UPDATE &&
3034 !dns_name_equal(firstname, dns_rootname) &&
3035 tmprdataset->type == dns_rdatatype_ds) {
3036 unsigned int labels = dns_name_countlabels(name);
3037 dns_name_getlabelsequence(name, 1, labels - 1, name);
3041 ISC_LIST_INIT(name->list);
3042 ISC_LIST_APPEND(name->list, rdataset, link);
3043 dns_message_addname(soaquery, name, DNS_SECTION_QUESTION);
3046 sendrequest(&servers[ns_inuse], soaquery, &request);
3051 ddebug("cleanup()");
3054 dns_message_destroy(&answer);
3057 if (tsigkey != NULL) {
3058 ddebug("detach tsigkey x%p", tsigkey);
3059 dns_tsigkey_detach(&tsigkey);
3061 if (gssring != NULL) {
3062 ddebug("Detaching GSS-TSIG keyring");
3063 dns_tsigkeyring_detach(&gssring);
3065 if (kserver != NULL) {
3066 isc_mem_put(gmctx, kserver, sizeof(isc_sockaddr_t));
3069 if (realm != NULL) {
3070 isc_mem_free(gmctx, realm);
3075 if (sig0key != NULL)
3076 dst_key_free(&sig0key);
3078 ddebug("Shutting down task manager");
3079 isc_taskmgr_destroy(&taskmgr);
3081 ddebug("Destroying event");
3082 isc_event_free(&global_event);
3084 ddebug("Shutting down socket manager");
3085 isc_socketmgr_destroy(&socketmgr);
3087 ddebug("Shutting down timer manager");
3088 isc_timermgr_destroy(&timermgr);
3090 ddebug("Destroying hash context");
3093 ddebug("Destroying name state");
3096 ddebug("Removing log context");
3097 isc_log_destroy(&glctx);
3099 ddebug("Destroying memory context");
3101 isc_mem_stats(gmctx, stderr);
3102 isc_mem_destroy(&gmctx);
3106 getinput(isc_task_t *task, isc_event_t *event) {
3116 if (global_event == NULL)
3117 global_event = event;
3120 more = user_interaction();
3130 main(int argc, char **argv) {
3131 isc_result_t result;
3132 style = &dns_master_style_debug;
3136 interactive = ISC_TF(isatty(0));
3140 pre_parse_args(argc, argv);
3142 result = isc_mem_create(0, 0, &gmctx);
3143 check_result(result, "isc_mem_create");
3145 parse_args(argc, argv, gmctx, &entropy);
3149 result = isc_app_onrun(gmctx, global_task, getinput, NULL);
3150 check_result(result, "isc_app_onrun");
3152 (void)isc_app_run();