1 /* $NetBSD: nsupdate.c,v 1.13 2015/07/08 17:28:55 christos Exp $ */
4 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
31 #include <isc/base64.h>
32 #include <isc/buffer.h>
33 #include <isc/commandline.h>
34 #include <isc/entropy.h>
35 #include <isc/event.h>
41 #include <isc/parseint.h>
42 #include <isc/print.h>
43 #include <isc/random.h>
44 #include <isc/region.h>
45 #include <isc/sockaddr.h>
46 #include <isc/socket.h>
47 #include <isc/stdio.h>
48 #include <isc/string.h>
50 #include <isc/timer.h>
51 #include <isc/types.h>
54 #include <isccfg/namedconf.h>
56 #include <dns/callbacks.h>
57 #include <dns/dispatch.h>
58 #include <dns/dnssec.h>
59 #include <dns/events.h>
60 #include <dns/fixedname.h>
62 #include <dns/masterdump.h>
63 #include <dns/message.h>
65 #include <dns/rcode.h>
66 #include <dns/rdata.h>
67 #include <dns/rdataclass.h>
68 #include <dns/rdatalist.h>
69 #include <dns/rdataset.h>
70 #include <dns/rdatastruct.h>
71 #include <dns/rdatatype.h>
72 #include <dns/request.h>
73 #include <dns/result.h>
79 #include <lwres/lwres.h>
80 #include <lwres/net.h>
83 #include <dst/gssapi.h>
85 #include <krb5/krb5.h>
87 #include ISC_PLATFORM_KRB5HEADER
90 #include <bind9/getaddresses.h>
92 #if defined(HAVE_READLINE)
93 #include <readline/readline.h>
94 #include <readline/history.h>
98 #ifdef HAVE_GETADDRINFO
99 #ifdef HAVE_GAISTRERROR
100 #define USE_GETADDRINFO
105 #ifndef USE_GETADDRINFO
106 #ifndef ISC_PLATFORM_NONSTDHERRNO
111 #define MAXCMD (128 * 1024)
112 #define MAXWIRE (64 * 1024)
113 #define PACKETSIZE ((64 * 1024) - 1)
114 #define INITTEXT (2 * 1024)
115 #define MAXTEXT (128 * 1024)
116 #define FIND_TIMEOUT 5
117 #define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
119 #define DNSDEFAULTPORT 53
121 /* Number of addresses to request from bind9_getaddresses() */
122 #define MAX_SERVERADDRS 4
124 static isc_uint16_t dnsport
= DNSDEFAULTPORT
;
127 #define RESOLV_CONF "/etc/resolv.conf"
130 static isc_boolean_t debugging
= ISC_FALSE
, ddebugging
= ISC_FALSE
;
131 static isc_boolean_t memdebugging
= ISC_FALSE
;
132 static isc_boolean_t have_ipv4
= ISC_FALSE
;
133 static isc_boolean_t have_ipv6
= ISC_FALSE
;
134 static isc_boolean_t is_dst_up
= ISC_FALSE
;
135 static isc_boolean_t usevc
= ISC_FALSE
;
136 static isc_boolean_t usegsstsig
= ISC_FALSE
;
137 static isc_boolean_t use_win2k_gsstsig
= ISC_FALSE
;
138 static isc_boolean_t tried_other_gsstsig
= ISC_FALSE
;
139 static isc_boolean_t local_only
= ISC_FALSE
;
140 static isc_taskmgr_t
*taskmgr
= NULL
;
141 static isc_task_t
*global_task
= NULL
;
142 static isc_event_t
*global_event
= NULL
;
143 static isc_log_t
*glctx
= NULL
;
144 static isc_mem_t
*gmctx
= NULL
;
145 static dns_dispatchmgr_t
*dispatchmgr
= NULL
;
146 static dns_requestmgr_t
*requestmgr
= NULL
;
147 static isc_socketmgr_t
*socketmgr
= NULL
;
148 static isc_timermgr_t
*timermgr
= NULL
;
149 static dns_dispatch_t
*dispatchv4
= NULL
;
150 static dns_dispatch_t
*dispatchv6
= NULL
;
151 static dns_message_t
*updatemsg
= NULL
;
152 static dns_fixedname_t fuserzone
;
153 static dns_name_t
*userzone
= NULL
;
154 static dns_name_t
*zname
= NULL
;
155 static dns_name_t tmpzonename
;
156 static dns_name_t restart_master
;
157 static dns_tsig_keyring_t
*gssring
= NULL
;
158 static dns_tsigkey_t
*tsigkey
= NULL
;
159 static dst_key_t
*sig0key
= NULL
;
160 static lwres_context_t
*lwctx
= NULL
;
161 static lwres_conf_t
*lwconf
;
162 static isc_sockaddr_t
*servers
= NULL
;
163 static isc_sockaddr_t
*master_servers
= NULL
;
164 static isc_boolean_t default_servers
= ISC_TRUE
;
165 static int ns_inuse
= 0;
166 static int master_inuse
= 0;
167 static int ns_total
= 0;
168 static int master_total
= 0;
169 static isc_sockaddr_t
*localaddr4
= NULL
;
170 static isc_sockaddr_t
*localaddr6
= NULL
;
171 static const char *keyfile
= NULL
;
172 static char *keystr
= NULL
;
173 static isc_entropy_t
*entropy
= NULL
;
174 static isc_boolean_t shuttingdown
= ISC_FALSE
;
176 static isc_boolean_t interactive
= ISC_TRUE
;
177 static isc_boolean_t seenerror
= ISC_FALSE
;
178 static const dns_master_style_t
*style
;
179 static int requests
= 0;
180 static unsigned int logdebuglevel
= 0;
181 static unsigned int timeout
= 300;
182 static unsigned int udp_timeout
= 3;
183 static unsigned int udp_retries
= 3;
184 static dns_rdataclass_t defaultclass
= dns_rdataclass_in
;
185 static dns_rdataclass_t zoneclass
= dns_rdataclass_none
;
186 static dns_message_t
*answer
= NULL
;
187 static isc_uint32_t default_ttl
= 0;
188 static isc_boolean_t default_ttl_set
= ISC_FALSE
;
190 typedef struct nsu_requestinfo
{
192 isc_sockaddr_t
*addr
;
196 sendrequest(isc_sockaddr_t
*destaddr
, dns_message_t
*msg
,
197 dns_request_t
**request
);
199 send_update(dns_name_t
*zonename
, isc_sockaddr_t
*master
);
201 ISC_PLATFORM_NORETURN_PRE
static void
202 fatal(const char *format
, ...)
203 ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST
;
206 debug(const char *format
, ...) ISC_FORMAT_PRINTF(1, 2);
209 ddebug(const char *format
, ...) ISC_FORMAT_PRINTF(1, 2);
212 static dns_fixedname_t fkname
;
213 static isc_sockaddr_t
*kserver
= NULL
;
214 static char *realm
= NULL
;
215 static char servicename
[DNS_NAME_FORMATSIZE
];
216 static dns_name_t
*keyname
;
217 typedef struct nsu_gssinfo
{
219 isc_sockaddr_t
*addr
;
220 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
);
645 snprintf(keystr
, len
, "%s:%s:%s", algorithm
, mykeyname
, secretstr
);
650 if (sessionkey
!= NULL
)
651 cfg_obj_destroy(pctx
, &sessionkey
);
652 cfg_parser_destroy(&pctx
);
656 isc_mem_free(mctx
, keystr
);
662 setup_keyfile(isc_mem_t
*mctx
, isc_log_t
*lctx
) {
663 dst_key_t
*dstkey
= NULL
;
665 dns_name_t
*hmacname
= NULL
;
667 debug("Creating key...");
670 dst_key_free(&sig0key
);
672 /* Try reading the key from a K* pair */
673 result
= dst_key_fromnamedfile(keyfile
, NULL
,
674 DST_TYPE_PRIVATE
| DST_TYPE_KEY
, mctx
,
677 /* If that didn't work, try reading it as a session.key keyfile */
678 if (result
!= ISC_R_SUCCESS
) {
679 result
= read_sessionkey(mctx
, lctx
);
680 if (result
== ISC_R_SUCCESS
)
684 if (result
!= ISC_R_SUCCESS
) {
685 fprintf(stderr
, "could not read key from %.*s.{private,key}: "
686 "%s\n", basenamelen(keyfile
), keyfile
,
687 isc_result_totext(result
));
691 switch (dst_key_alg(dstkey
)) {
692 case DST_ALG_HMACMD5
:
693 hmacname
= DNS_TSIG_HMACMD5_NAME
;
695 case DST_ALG_HMACSHA1
:
696 hmacname
= DNS_TSIG_HMACSHA1_NAME
;
698 case DST_ALG_HMACSHA224
:
699 hmacname
= DNS_TSIG_HMACSHA224_NAME
;
701 case DST_ALG_HMACSHA256
:
702 hmacname
= DNS_TSIG_HMACSHA256_NAME
;
704 case DST_ALG_HMACSHA384
:
705 hmacname
= DNS_TSIG_HMACSHA384_NAME
;
707 case DST_ALG_HMACSHA512
:
708 hmacname
= DNS_TSIG_HMACSHA512_NAME
;
711 if (hmacname
!= NULL
) {
712 result
= dns_tsigkey_createfromkey(dst_key_name(dstkey
),
713 hmacname
, dstkey
, ISC_FALSE
,
714 NULL
, 0, 0, mctx
, NULL
,
716 dst_key_free(&dstkey
);
717 if (result
!= ISC_R_SUCCESS
) {
718 fprintf(stderr
, "could not create key from %s: %s\n",
719 keyfile
, isc_result_totext(result
));
723 dst_key_attach(dstkey
, &sig0key
);
724 dst_key_free(&dstkey
);
730 isc_task_detach(&global_task
);
733 * The isc_mem_put of master_servers must be before the
734 * isc_mem_put of servers as it sets the servers pointer
737 if (master_servers
!= NULL
&& master_servers
!= servers
)
738 isc_mem_put(gmctx
, master_servers
,
739 master_total
* sizeof(isc_sockaddr_t
));
742 isc_mem_put(gmctx
, servers
, ns_total
* sizeof(isc_sockaddr_t
));
744 if (localaddr4
!= NULL
)
745 isc_mem_put(gmctx
, localaddr4
, sizeof(isc_sockaddr_t
));
747 if (localaddr6
!= NULL
)
748 isc_mem_put(gmctx
, localaddr6
, sizeof(isc_sockaddr_t
));
750 if (tsigkey
!= NULL
) {
751 ddebug("Freeing TSIG key");
752 dns_tsigkey_detach(&tsigkey
);
755 if (sig0key
!= NULL
) {
756 ddebug("Freeing SIG(0) key");
757 dst_key_free(&sig0key
);
760 if (updatemsg
!= NULL
)
761 dns_message_destroy(&updatemsg
);
764 ddebug("Destroy DST lib");
766 is_dst_up
= ISC_FALSE
;
769 cleanup_entropy(&entropy
);
771 lwres_conf_clear(lwctx
);
772 lwres_context_destroy(&lwctx
);
774 ddebug("Destroying request manager");
775 dns_requestmgr_detach(&requestmgr
);
777 ddebug("Freeing the dispatchers");
779 dns_dispatch_detach(&dispatchv4
);
781 dns_dispatch_detach(&dispatchv6
);
783 ddebug("Shutting down dispatch manager");
784 dns_dispatchmgr_destroy(&dispatchmgr
);
789 maybeshutdown(void) {
790 ddebug("Shutting down request manager");
791 dns_requestmgr_shutdown(requestmgr
);
800 shutdown_program(isc_task_t
*task
, isc_event_t
*event
) {
801 REQUIRE(task
== global_task
);
804 ddebug("shutdown_program()");
805 isc_event_free(&event
);
807 shuttingdown
= ISC_TRUE
;
814 isc_sockaddr_t bind_any
, bind_any6
;
815 lwres_result_t lwresult
;
816 unsigned int attrs
, attrmask
;
818 isc_logconfig_t
*logconfig
= NULL
;
820 ddebug("setup_system()");
822 dns_result_register();
824 result
= isc_net_probeipv4();
825 if (result
== ISC_R_SUCCESS
)
826 have_ipv4
= ISC_TRUE
;
828 result
= isc_net_probeipv6();
829 if (result
== ISC_R_SUCCESS
)
830 have_ipv6
= ISC_TRUE
;
832 if (!have_ipv4
&& !have_ipv6
)
833 fatal("could not find either IPv4 or IPv6");
835 result
= isc_log_create(gmctx
, &glctx
, &logconfig
);
836 check_result(result
, "isc_log_create");
838 isc_log_setcontext(glctx
);
840 dns_log_setcontext(glctx
);
842 result
= isc_log_usechannel(logconfig
, "default_debug", NULL
, NULL
);
843 check_result(result
, "isc_log_usechannel");
845 isc_log_setdebuglevel(glctx
, logdebuglevel
);
847 lwresult
= lwres_context_create(&lwctx
, gmctx
, mem_alloc
, mem_free
, 1);
848 if (lwresult
!= LWRES_R_SUCCESS
)
849 fatal("lwres_context_create failed");
851 (void)lwres_conf_parse(lwctx
, RESOLV_CONF
);
852 lwconf
= lwres_conf_get(lwctx
);
854 if (servers
!= NULL
) {
855 if (master_servers
== servers
)
856 master_servers
= NULL
;
857 isc_mem_put(gmctx
, servers
, ns_total
* sizeof(isc_sockaddr_t
));
861 if (local_only
|| lwconf
->nsnext
<= 0) {
865 if (local_only
&& keyfile
== NULL
)
866 keyfile
= SESSION_KEYFILE
;
868 default_servers
= !local_only
;
870 ns_total
= (have_ipv4
? 1 : 0) + (have_ipv6
? 1 : 0);
871 servers
= isc_mem_get(gmctx
, ns_total
* sizeof(isc_sockaddr_t
));
873 fatal("out of memory");
876 in
.s_addr
= htonl(INADDR_LOOPBACK
);
877 isc_sockaddr_fromin(&servers
[0], &in
, dnsport
);
880 memset(&in6
, 0, sizeof(in6
));
882 isc_sockaddr_fromin6(&servers
[(have_ipv4
? 1 : 0)],
886 ns_total
= lwconf
->nsnext
;
887 servers
= isc_mem_get(gmctx
, ns_total
* sizeof(isc_sockaddr_t
));
889 fatal("out of memory");
890 for (i
= 0; i
< ns_total
; i
++) {
891 if (lwconf
->nameservers
[i
].family
== LWRES_ADDRTYPE_V4
)
895 lwconf
->nameservers
[i
].address
, 4);
896 isc_sockaddr_fromin(&servers
[i
],
901 lwconf
->nameservers
[i
].address
, 16);
902 isc_sockaddr_fromin6(&servers
[i
],
908 setup_entropy(gmctx
, NULL
, &entropy
);
910 result
= isc_hash_create(gmctx
, entropy
, DNS_NAME_MAXWIRE
);
911 check_result(result
, "isc_hash_create");
914 result
= dns_dispatchmgr_create(gmctx
, entropy
, &dispatchmgr
);
915 check_result(result
, "dns_dispatchmgr_create");
917 result
= isc_socketmgr_create(gmctx
, &socketmgr
);
918 check_result(result
, "dns_socketmgr_create");
920 result
= isc_timermgr_create(gmctx
, &timermgr
);
921 check_result(result
, "dns_timermgr_create");
923 result
= isc_taskmgr_create(gmctx
, 1, 0, &taskmgr
);
924 check_result(result
, "isc_taskmgr_create");
926 result
= isc_task_create(taskmgr
, 0, &global_task
);
927 check_result(result
, "isc_task_create");
929 result
= isc_task_onshutdown(global_task
, shutdown_program
, NULL
);
930 check_result(result
, "isc_task_onshutdown");
932 result
= dst_lib_init(gmctx
, entropy
, 0);
933 check_result(result
, "dst_lib_init");
934 is_dst_up
= ISC_TRUE
;
936 attrmask
= DNS_DISPATCHATTR_UDP
| DNS_DISPATCHATTR_TCP
;
937 attrmask
|= DNS_DISPATCHATTR_IPV4
| DNS_DISPATCHATTR_IPV6
;
940 attrs
= DNS_DISPATCHATTR_UDP
;
941 attrs
|= DNS_DISPATCHATTR_MAKEQUERY
;
942 attrs
|= DNS_DISPATCHATTR_IPV6
;
943 isc_sockaddr_any6(&bind_any6
);
944 result
= dns_dispatch_getudp(dispatchmgr
, socketmgr
, taskmgr
,
945 &bind_any6
, PACKETSIZE
,
947 attrs
, attrmask
, &dispatchv6
);
948 check_result(result
, "dns_dispatch_getudp (v6)");
952 attrs
= DNS_DISPATCHATTR_UDP
;
953 attrs
|= DNS_DISPATCHATTR_MAKEQUERY
;
954 attrs
|= DNS_DISPATCHATTR_IPV4
;
955 isc_sockaddr_any(&bind_any
);
956 result
= dns_dispatch_getudp(dispatchmgr
, socketmgr
, taskmgr
,
957 &bind_any
, PACKETSIZE
,
959 attrs
, attrmask
, &dispatchv4
);
960 check_result(result
, "dns_dispatch_getudp (v4)");
963 result
= dns_requestmgr_create(gmctx
, timermgr
,
964 socketmgr
, taskmgr
, dispatchmgr
,
965 dispatchv4
, dispatchv6
, &requestmgr
);
966 check_result(result
, "dns_requestmgr_create");
970 else if (local_only
) {
971 result
= read_sessionkey(gmctx
, glctx
);
972 if (result
!= ISC_R_SUCCESS
)
973 fatal("can't read key from %s: %s\n",
974 keyfile
, isc_result_totext(result
));
975 } else if (keyfile
!= NULL
)
976 setup_keyfile(gmctx
, glctx
);
980 get_addresses(char *host
, in_port_t port
,
981 isc_sockaddr_t
*sockaddr
, int naddrs
)
987 result
= bind9_getaddresses(host
, port
, sockaddr
, naddrs
, &count
);
989 if (result
!= ISC_R_SUCCESS
)
990 fatal("couldn't get address for '%s': %s",
991 host
, isc_result_totext(result
));
996 fputs("nsupdate " VERSION
"\n", stderr
);
999 #define PARSE_ARGS_FMT "dDML:y:ghlovk:p:Pr:R::t:Tu:V"
1002 pre_parse_args(int argc
, char **argv
) {
1006 isc_boolean_t doexit
= ISC_FALSE
;
1008 while ((ch
= isc_commandline_parse(argc
, argv
, PARSE_ARGS_FMT
)) != -1) {
1010 case 'M': /* was -dm */
1011 debugging
= ISC_TRUE
;
1012 ddebugging
= ISC_TRUE
;
1013 memdebugging
= ISC_TRUE
;
1014 isc_mem_debugging
= ISC_MEM_DEBUGTRACE
|
1015 ISC_MEM_DEBUGRECORD
;
1020 if (isc_commandline_option
!= '?')
1021 fprintf(stderr
, "%s: invalid argument -%c\n",
1022 argv
[0], isc_commandline_option
);
1023 fprintf(stderr
, "usage: nsupdate [-dD] [-L level] [-l]"
1024 "[-g | -o | -y keyname:secret | -k keyfile] "
1025 "[-v] [-V] [filename]\n");
1029 for (t
= 0xff00; t
<= 0xfffe; t
++) {
1030 if (dns_rdatatype_ismeta(t
))
1032 dns_rdatatype_format(t
, buf
, sizeof(buf
));
1033 if (strncmp(buf
, "TYPE", 4) != 0)
1034 fprintf(stdout
, "%s\n", buf
);
1040 for (t
= 1; t
<= 0xfeff; t
++) {
1041 if (dns_rdatatype_ismeta(t
))
1043 dns_rdatatype_format(t
, buf
, sizeof(buf
));
1044 if (strncmp(buf
, "TYPE", 4) != 0)
1045 fprintf(stdout
, "%s\n", buf
);
1061 isc_commandline_reset
= ISC_TRUE
;
1062 isc_commandline_index
= 1;
1066 parse_args(int argc
, char **argv
, isc_mem_t
*mctx
, isc_entropy_t
**ectx
) {
1069 isc_result_t result
;
1071 debug("parse_args");
1072 while ((ch
= isc_commandline_parse(argc
, argv
, PARSE_ARGS_FMT
)) != -1) {
1075 debugging
= ISC_TRUE
;
1077 case 'D': /* was -dd */
1078 debugging
= ISC_TRUE
;
1079 ddebugging
= ISC_TRUE
;
1084 local_only
= ISC_TRUE
;
1087 result
= isc_parse_uint32(&i
, isc_commandline_argument
,
1089 if (result
!= ISC_R_SUCCESS
) {
1090 fprintf(stderr
, "bad library debug value "
1091 "'%s'\n", isc_commandline_argument
);
1097 keystr
= isc_commandline_argument
;
1103 keyfile
= isc_commandline_argument
;
1106 usegsstsig
= ISC_TRUE
;
1107 use_win2k_gsstsig
= ISC_FALSE
;
1110 usegsstsig
= ISC_TRUE
;
1111 use_win2k_gsstsig
= ISC_TRUE
;
1114 result
= isc_parse_uint16(&dnsport
,
1115 isc_commandline_argument
, 10);
1116 if (result
!= ISC_R_SUCCESS
) {
1117 fprintf(stderr
, "bad port number "
1118 "'%s'\n", isc_commandline_argument
);
1123 result
= isc_parse_uint32(&timeout
,
1124 isc_commandline_argument
, 10);
1125 if (result
!= ISC_R_SUCCESS
) {
1126 fprintf(stderr
, "bad timeout '%s'\n", isc_commandline_argument
);
1133 result
= isc_parse_uint32(&udp_timeout
,
1134 isc_commandline_argument
, 10);
1135 if (result
!= ISC_R_SUCCESS
) {
1136 fprintf(stderr
, "bad udp timeout '%s'\n", isc_commandline_argument
);
1139 if (udp_timeout
== 0)
1140 udp_timeout
= UINT_MAX
;
1143 result
= isc_parse_uint32(&udp_retries
,
1144 isc_commandline_argument
, 10);
1145 if (result
!= ISC_R_SUCCESS
) {
1146 fprintf(stderr
, "bad udp retries '%s'\n", isc_commandline_argument
);
1152 setup_entropy(mctx
, isc_commandline_argument
, ectx
);
1156 fprintf(stderr
, "%s: unhandled option: %c\n",
1157 argv
[0], isc_commandline_option
);
1161 if (keyfile
!= NULL
&& keystr
!= NULL
) {
1162 fprintf(stderr
, "%s: cannot specify both -k and -y\n",
1168 if (usegsstsig
&& (keyfile
!= NULL
|| keystr
!= NULL
)) {
1169 fprintf(stderr
, "%s: cannot specify -g with -k or -y\n",
1175 fprintf(stderr
, "%s: cannot specify -g or -o, " \
1176 "program not linked with GSS API Library\n",
1182 if (argv
[isc_commandline_index
] != NULL
) {
1183 if (strcmp(argv
[isc_commandline_index
], "-") == 0) {
1186 result
= isc_stdio_open(argv
[isc_commandline_index
],
1188 if (result
!= ISC_R_SUCCESS
) {
1189 fprintf(stderr
, "could not open '%s': %s\n",
1190 argv
[isc_commandline_index
],
1191 isc_result_totext(result
));
1195 interactive
= ISC_FALSE
;
1200 parse_name(char **cmdlinep
, dns_message_t
*msg
, dns_name_t
**namep
) {
1201 isc_result_t result
;
1203 isc_buffer_t
*namebuf
= NULL
;
1204 isc_buffer_t source
;
1206 word
= nsu_strsep(cmdlinep
, " \t\r\n");
1207 if (word
== NULL
|| *word
== 0) {
1208 fprintf(stderr
, "could not read owner name\n");
1209 return (STATUS_SYNTAX
);
1212 result
= dns_message_gettempname(msg
, namep
);
1213 check_result(result
, "dns_message_gettempname");
1214 result
= isc_buffer_allocate(gmctx
, &namebuf
, DNS_NAME_MAXWIRE
);
1215 check_result(result
, "isc_buffer_allocate");
1216 dns_name_init(*namep
, NULL
);
1217 dns_name_setbuffer(*namep
, namebuf
);
1218 dns_message_takebuffer(msg
, &namebuf
);
1219 isc_buffer_init(&source
, word
, strlen(word
));
1220 isc_buffer_add(&source
, strlen(word
));
1221 result
= dns_name_fromtext(*namep
, &source
, dns_rootname
, 0, NULL
);
1222 check_result(result
, "dns_name_fromtext");
1223 isc_buffer_invalidate(&source
);
1224 return (STATUS_MORE
);
1228 parse_rdata(char **cmdlinep
, dns_rdataclass_t rdataclass
,
1229 dns_rdatatype_t rdatatype
, dns_message_t
*msg
,
1232 char *cmdline
= *cmdlinep
;
1233 isc_buffer_t source
, *buf
= NULL
, *newbuf
= NULL
;
1235 isc_lex_t
*lex
= NULL
;
1236 dns_rdatacallbacks_t callbacks
;
1237 isc_result_t result
;
1239 if (cmdline
== NULL
) {
1240 rdata
->flags
= DNS_RDATA_UPDATE
;
1241 return (STATUS_MORE
);
1244 while (*cmdline
!= 0 && isspace((unsigned char)*cmdline
))
1247 if (*cmdline
!= 0) {
1248 dns_rdatacallbacks_init(&callbacks
);
1249 result
= isc_lex_create(gmctx
, strlen(cmdline
), &lex
);
1250 check_result(result
, "isc_lex_create");
1251 isc_buffer_init(&source
, cmdline
, strlen(cmdline
));
1252 isc_buffer_add(&source
, strlen(cmdline
));
1253 result
= isc_lex_openbuffer(lex
, &source
);
1254 check_result(result
, "isc_lex_openbuffer");
1255 result
= isc_buffer_allocate(gmctx
, &buf
, MAXWIRE
);
1256 check_result(result
, "isc_buffer_allocate");
1257 result
= dns_rdata_fromtext(NULL
, rdataclass
, rdatatype
, lex
,
1258 dns_rootname
, 0, gmctx
, buf
,
1260 isc_lex_destroy(&lex
);
1261 if (result
== ISC_R_SUCCESS
) {
1262 isc_buffer_usedregion(buf
, &r
);
1263 result
= isc_buffer_allocate(gmctx
, &newbuf
, r
.length
);
1264 check_result(result
, "isc_buffer_allocate");
1265 isc_buffer_putmem(newbuf
, r
.base
, r
.length
);
1266 isc_buffer_usedregion(newbuf
, &r
);
1267 dns_rdata_fromregion(rdata
, rdataclass
, rdatatype
, &r
);
1268 isc_buffer_free(&buf
);
1269 dns_message_takebuffer(msg
, &newbuf
);
1271 fprintf(stderr
, "invalid rdata format: %s\n",
1272 isc_result_totext(result
));
1273 isc_buffer_free(&buf
);
1274 return (STATUS_SYNTAX
);
1277 rdata
->flags
= DNS_RDATA_UPDATE
;
1279 *cmdlinep
= cmdline
;
1280 return (STATUS_MORE
);
1284 make_prereq(char *cmdline
, isc_boolean_t ispositive
, isc_boolean_t isrrset
) {
1285 isc_result_t result
;
1287 dns_name_t
*name
= NULL
;
1288 isc_textregion_t region
;
1289 dns_rdataset_t
*rdataset
= NULL
;
1290 dns_rdatalist_t
*rdatalist
= NULL
;
1291 dns_rdataclass_t rdataclass
;
1292 dns_rdatatype_t rdatatype
;
1293 dns_rdata_t
*rdata
= NULL
;
1294 isc_uint16_t retval
;
1296 ddebug("make_prereq()");
1299 * Read the owner name
1301 retval
= parse_name(&cmdline
, updatemsg
, &name
);
1302 if (retval
!= STATUS_MORE
)
1306 * If this is an rrset prereq, read the class or type.
1309 word
= nsu_strsep(&cmdline
, " \t\r\n");
1310 if (word
== NULL
|| *word
== 0) {
1311 fprintf(stderr
, "could not read class or type\n");
1315 region
.length
= strlen(word
);
1316 result
= dns_rdataclass_fromtext(&rdataclass
, ®ion
);
1317 if (result
== ISC_R_SUCCESS
) {
1318 if (!setzoneclass(rdataclass
)) {
1319 fprintf(stderr
, "class mismatch: %s\n", word
);
1323 * Now read the type.
1325 word
= nsu_strsep(&cmdline
, " \t\r\n");
1326 if (word
== NULL
|| *word
== 0) {
1327 fprintf(stderr
, "could not read type\n");
1331 region
.length
= strlen(word
);
1332 result
= dns_rdatatype_fromtext(&rdatatype
, ®ion
);
1333 if (result
!= ISC_R_SUCCESS
) {
1334 fprintf(stderr
, "invalid type: %s\n", word
);
1338 rdataclass
= getzoneclass();
1339 result
= dns_rdatatype_fromtext(&rdatatype
, ®ion
);
1340 if (result
!= ISC_R_SUCCESS
) {
1341 fprintf(stderr
, "invalid type: %s\n", word
);
1346 rdatatype
= dns_rdatatype_any
;
1348 result
= dns_message_gettemprdata(updatemsg
, &rdata
);
1349 check_result(result
, "dns_message_gettemprdata");
1351 dns_rdata_init(rdata
);
1353 if (isrrset
&& ispositive
) {
1354 retval
= parse_rdata(&cmdline
, rdataclass
, rdatatype
,
1356 if (retval
!= STATUS_MORE
)
1359 rdata
->flags
= DNS_RDATA_UPDATE
;
1361 result
= dns_message_gettemprdatalist(updatemsg
, &rdatalist
);
1362 check_result(result
, "dns_message_gettemprdatalist");
1363 result
= dns_message_gettemprdataset(updatemsg
, &rdataset
);
1364 check_result(result
, "dns_message_gettemprdataset");
1365 dns_rdatalist_init(rdatalist
);
1366 rdatalist
->type
= rdatatype
;
1368 if (isrrset
&& rdata
->data
!= NULL
)
1369 rdatalist
->rdclass
= rdataclass
;
1371 rdatalist
->rdclass
= dns_rdataclass_any
;
1373 rdatalist
->rdclass
= dns_rdataclass_none
;
1374 rdatalist
->covers
= 0;
1376 rdata
->rdclass
= rdatalist
->rdclass
;
1377 rdata
->type
= rdatatype
;
1378 ISC_LIST_INIT(rdatalist
->rdata
);
1379 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
1380 dns_rdatalist_tordataset(rdatalist
, rdataset
);
1381 ISC_LIST_INIT(name
->list
);
1382 ISC_LIST_APPEND(name
->list
, rdataset
, link
);
1383 dns_message_addname(updatemsg
, name
, DNS_SECTION_PREREQUISITE
);
1384 return (STATUS_MORE
);
1388 dns_message_puttempname(updatemsg
, &name
);
1389 return (STATUS_SYNTAX
);
1393 evaluate_prereq(char *cmdline
) {
1395 isc_boolean_t ispositive
, isrrset
;
1397 ddebug("evaluate_prereq()");
1398 word
= nsu_strsep(&cmdline
, " \t\r\n");
1399 if (word
== NULL
|| *word
== 0) {
1400 fprintf(stderr
, "could not read operation code\n");
1401 return (STATUS_SYNTAX
);
1403 if (strcasecmp(word
, "nxdomain") == 0) {
1404 ispositive
= ISC_FALSE
;
1405 isrrset
= ISC_FALSE
;
1406 } else if (strcasecmp(word
, "yxdomain") == 0) {
1407 ispositive
= ISC_TRUE
;
1408 isrrset
= ISC_FALSE
;
1409 } else if (strcasecmp(word
, "nxrrset") == 0) {
1410 ispositive
= ISC_FALSE
;
1412 } else if (strcasecmp(word
, "yxrrset") == 0) {
1413 ispositive
= ISC_TRUE
;
1416 fprintf(stderr
, "incorrect operation code: %s\n", word
);
1417 return (STATUS_SYNTAX
);
1419 return (make_prereq(cmdline
, ispositive
, isrrset
));
1423 evaluate_server(char *cmdline
) {
1424 char *word
, *server
;
1428 fprintf(stderr
, "cannot reset server in localhost-only mode\n");
1429 return (STATUS_SYNTAX
);
1432 word
= nsu_strsep(&cmdline
, " \t\r\n");
1433 if (word
== NULL
|| *word
== 0) {
1434 fprintf(stderr
, "could not read server name\n");
1435 return (STATUS_SYNTAX
);
1439 word
= nsu_strsep(&cmdline
, " \t\r\n");
1440 if (word
== NULL
|| *word
== 0)
1444 port
= strtol(word
, &endp
, 10);
1446 fprintf(stderr
, "port '%s' is not numeric\n", word
);
1447 return (STATUS_SYNTAX
);
1448 } else if (port
< 1 || port
> 65535) {
1449 fprintf(stderr
, "port '%s' is out of range "
1450 "(1 to 65535)\n", word
);
1451 return (STATUS_SYNTAX
);
1455 if (servers
!= NULL
) {
1456 if (master_servers
== servers
)
1457 master_servers
= NULL
;
1458 isc_mem_put(gmctx
, servers
, ns_total
* sizeof(isc_sockaddr_t
));
1461 default_servers
= ISC_FALSE
;
1463 ns_total
= MAX_SERVERADDRS
;
1465 servers
= isc_mem_get(gmctx
, ns_total
* sizeof(isc_sockaddr_t
));
1466 if (servers
== NULL
)
1467 fatal("out of memory");
1469 memset(servers
, 0, ns_total
* sizeof(isc_sockaddr_t
));
1470 get_addresses(server
, (in_port_t
)port
, servers
, ns_total
);
1472 return (STATUS_MORE
);
1476 evaluate_local(char *cmdline
) {
1480 struct in6_addr in6
;
1482 word
= nsu_strsep(&cmdline
, " \t\r\n");
1483 if (word
== NULL
|| *word
== 0) {
1484 fprintf(stderr
, "could not read server name\n");
1485 return (STATUS_SYNTAX
);
1489 word
= nsu_strsep(&cmdline
, " \t\r\n");
1490 if (word
== NULL
|| *word
== 0)
1494 port
= strtol(word
, &endp
, 10);
1496 fprintf(stderr
, "port '%s' is not numeric\n", word
);
1497 return (STATUS_SYNTAX
);
1498 } else if (port
< 1 || port
> 65535) {
1499 fprintf(stderr
, "port '%s' is out of range "
1500 "(1 to 65535)\n", word
);
1501 return (STATUS_SYNTAX
);
1505 if (have_ipv6
&& inet_pton(AF_INET6
, local
, &in6
) == 1) {
1506 if (localaddr6
== NULL
)
1507 localaddr6
= isc_mem_get(gmctx
, sizeof(isc_sockaddr_t
));
1508 if (localaddr6
== NULL
)
1509 fatal("out of memory");
1510 isc_sockaddr_fromin6(localaddr6
, &in6
, (in_port_t
)port
);
1511 } else if (have_ipv4
&& inet_pton(AF_INET
, local
, &in4
) == 1) {
1512 if (localaddr4
== NULL
)
1513 localaddr4
= isc_mem_get(gmctx
, sizeof(isc_sockaddr_t
));
1514 if (localaddr4
== NULL
)
1515 fatal("out of memory");
1516 isc_sockaddr_fromin(localaddr4
, &in4
, (in_port_t
)port
);
1518 fprintf(stderr
, "invalid address %s", local
);
1519 return (STATUS_SYNTAX
);
1522 return (STATUS_MORE
);
1526 evaluate_key(char *cmdline
) {
1530 isc_result_t result
;
1531 dns_fixedname_t fkeyname
;
1532 dns_name_t
*mykeyname
;
1534 unsigned char *secret
= NULL
;
1535 isc_buffer_t secretbuf
;
1536 dns_name_t
*hmacname
= NULL
;
1537 isc_uint16_t digestbits
= 0;
1540 namestr
= nsu_strsep(&cmdline
, " \t\r\n");
1541 if (namestr
== NULL
|| *namestr
== 0) {
1542 fprintf(stderr
, "could not read key name\n");
1543 return (STATUS_SYNTAX
);
1546 dns_fixedname_init(&fkeyname
);
1547 mykeyname
= dns_fixedname_name(&fkeyname
);
1549 n
= strchr(namestr
, ':');
1551 digestbits
= parse_hmac(&hmacname
, namestr
, n
- namestr
);
1554 hmacname
= DNS_TSIG_HMACMD5_NAME
;
1556 isc_buffer_init(&b
, namestr
, strlen(namestr
));
1557 isc_buffer_add(&b
, strlen(namestr
));
1558 result
= dns_name_fromtext(mykeyname
, &b
, dns_rootname
, 0, NULL
);
1559 if (result
!= ISC_R_SUCCESS
) {
1560 fprintf(stderr
, "could not parse key name\n");
1561 return (STATUS_SYNTAX
);
1564 secretstr
= nsu_strsep(&cmdline
, "\r\n");
1565 if (secretstr
== NULL
|| *secretstr
== 0) {
1566 fprintf(stderr
, "could not read key secret\n");
1567 return (STATUS_SYNTAX
);
1569 secretlen
= strlen(secretstr
) * 3 / 4;
1570 secret
= isc_mem_allocate(gmctx
, secretlen
);
1572 fatal("out of memory");
1574 isc_buffer_init(&secretbuf
, secret
, secretlen
);
1575 result
= isc_base64_decodestring(secretstr
, &secretbuf
);
1576 if (result
!= ISC_R_SUCCESS
) {
1577 fprintf(stderr
, "could not create key from %s: %s\n",
1578 secretstr
, isc_result_totext(result
));
1579 isc_mem_free(gmctx
, secret
);
1580 return (STATUS_SYNTAX
);
1582 secretlen
= isc_buffer_usedlength(&secretbuf
);
1584 if (tsigkey
!= NULL
)
1585 dns_tsigkey_detach(&tsigkey
);
1586 result
= dns_tsigkey_create(mykeyname
, hmacname
, secret
, secretlen
,
1587 ISC_FALSE
, NULL
, 0, 0, gmctx
, NULL
,
1589 isc_mem_free(gmctx
, secret
);
1590 if (result
!= ISC_R_SUCCESS
) {
1591 fprintf(stderr
, "could not create key from %s %s: %s\n",
1592 namestr
, secretstr
, dns_result_totext(result
));
1593 return (STATUS_SYNTAX
);
1595 dst_key_setbits(tsigkey
->key
, digestbits
);
1596 return (STATUS_MORE
);
1600 evaluate_zone(char *cmdline
) {
1603 isc_result_t result
;
1605 word
= nsu_strsep(&cmdline
, " \t\r\n");
1606 if (word
== NULL
|| *word
== 0) {
1607 fprintf(stderr
, "could not read zone name\n");
1608 return (STATUS_SYNTAX
);
1611 dns_fixedname_init(&fuserzone
);
1612 userzone
= dns_fixedname_name(&fuserzone
);
1613 isc_buffer_init(&b
, word
, strlen(word
));
1614 isc_buffer_add(&b
, strlen(word
));
1615 result
= dns_name_fromtext(userzone
, &b
, dns_rootname
, 0, NULL
);
1616 if (result
!= ISC_R_SUCCESS
) {
1617 userzone
= NULL
; /* Lest it point to an invalid name */
1618 fprintf(stderr
, "could not parse zone name\n");
1619 return (STATUS_SYNTAX
);
1622 return (STATUS_MORE
);
1626 evaluate_realm(char *cmdline
) {
1632 if (realm
!= NULL
) {
1633 isc_mem_free(gmctx
, realm
);
1637 word
= nsu_strsep(&cmdline
, " \t\r\n");
1638 if (word
== NULL
|| *word
== 0)
1639 return (STATUS_MORE
);
1641 n
= snprintf(buf
, sizeof(buf
), "@%s", word
);
1642 if (n
< 0 || (size_t)n
>= sizeof(buf
))
1643 fatal("realm is too long");
1644 realm
= isc_mem_strdup(gmctx
, buf
);
1646 fatal("out of memory");
1647 return (STATUS_MORE
);
1650 return (STATUS_SYNTAX
);
1655 evaluate_ttl(char *cmdline
) {
1657 isc_result_t result
;
1660 word
= nsu_strsep(&cmdline
, " \t\r\n");
1661 if (word
== NULL
|| *word
== 0) {
1662 fprintf(stderr
, "could not ttl\n");
1663 return (STATUS_SYNTAX
);
1666 if (!strcasecmp(word
, "none")) {
1668 default_ttl_set
= ISC_FALSE
;
1669 return (STATUS_MORE
);
1672 result
= isc_parse_uint32(&ttl
, word
, 10);
1673 if (result
!= ISC_R_SUCCESS
)
1674 return (STATUS_SYNTAX
);
1676 if (ttl
> TTL_MAX
) {
1677 fprintf(stderr
, "ttl '%s' is out of range (0 to %u)\n",
1679 return (STATUS_SYNTAX
);
1682 default_ttl_set
= ISC_TRUE
;
1684 return (STATUS_MORE
);
1688 evaluate_class(char *cmdline
) {
1691 isc_result_t result
;
1692 dns_rdataclass_t rdclass
;
1694 word
= nsu_strsep(&cmdline
, " \t\r\n");
1695 if (word
== NULL
|| *word
== 0) {
1696 fprintf(stderr
, "could not read class name\n");
1697 return (STATUS_SYNTAX
);
1701 r
.length
= strlen(word
);
1702 result
= dns_rdataclass_fromtext(&rdclass
, &r
);
1703 if (result
!= ISC_R_SUCCESS
) {
1704 fprintf(stderr
, "could not parse class name: %s\n", word
);
1705 return (STATUS_SYNTAX
);
1708 case dns_rdataclass_none
:
1709 case dns_rdataclass_any
:
1710 case dns_rdataclass_reserved0
:
1711 fprintf(stderr
, "bad default class: %s\n", word
);
1712 return (STATUS_SYNTAX
);
1714 defaultclass
= rdclass
;
1717 return (STATUS_MORE
);
1721 update_addordelete(char *cmdline
, isc_boolean_t isdelete
) {
1722 isc_result_t result
;
1723 dns_name_t
*name
= NULL
;
1726 dns_rdataclass_t rdataclass
;
1727 dns_rdatatype_t rdatatype
;
1728 dns_rdata_t
*rdata
= NULL
;
1729 dns_rdatalist_t
*rdatalist
= NULL
;
1730 dns_rdataset_t
*rdataset
= NULL
;
1731 isc_textregion_t region
;
1732 isc_uint16_t retval
;
1734 ddebug("update_addordelete()");
1737 * Read the owner name.
1739 retval
= parse_name(&cmdline
, updatemsg
, &name
);
1740 if (retval
!= STATUS_MORE
)
1743 result
= dns_message_gettemprdata(updatemsg
, &rdata
);
1744 check_result(result
, "dns_message_gettemprdata");
1746 dns_rdata_init(rdata
);
1749 * If this is an add, read the TTL and verify that it's in range.
1750 * If it's a delete, ignore a TTL if present (for compatibility).
1752 word
= nsu_strsep(&cmdline
, " \t\r\n");
1753 if (word
== NULL
|| *word
== 0) {
1755 fprintf(stderr
, "could not read owner ttl\n");
1760 rdataclass
= dns_rdataclass_any
;
1761 rdatatype
= dns_rdatatype_any
;
1762 rdata
->flags
= DNS_RDATA_UPDATE
;
1766 result
= isc_parse_uint32(&ttl
, word
, 10);
1767 if (result
!= ISC_R_SUCCESS
) {
1771 } else if (default_ttl_set
) {
1775 fprintf(stderr
, "ttl '%s': %s\n", word
,
1776 isc_result_totext(result
));
1783 else if (ttl
> TTL_MAX
) {
1784 fprintf(stderr
, "ttl '%s' is out of range (0 to %u)\n",
1790 * Read the class or type.
1792 word
= nsu_strsep(&cmdline
, " \t\r\n");
1794 if (word
== NULL
|| *word
== 0) {
1796 rdataclass
= dns_rdataclass_any
;
1797 rdatatype
= dns_rdatatype_any
;
1798 rdata
->flags
= DNS_RDATA_UPDATE
;
1801 fprintf(stderr
, "could not read class or type\n");
1806 region
.length
= strlen(word
);
1807 rdataclass
= dns_rdataclass_any
;
1808 result
= dns_rdataclass_fromtext(&rdataclass
, ®ion
);
1809 if (result
== ISC_R_SUCCESS
&& rdataclass
!= dns_rdataclass_any
) {
1810 if (!setzoneclass(rdataclass
)) {
1811 fprintf(stderr
, "class mismatch: %s\n", word
);
1815 * Now read the type.
1817 word
= nsu_strsep(&cmdline
, " \t\r\n");
1818 if (word
== NULL
|| *word
== 0) {
1820 rdataclass
= dns_rdataclass_any
;
1821 rdatatype
= dns_rdatatype_any
;
1822 rdata
->flags
= DNS_RDATA_UPDATE
;
1825 fprintf(stderr
, "could not read type\n");
1830 region
.length
= strlen(word
);
1831 result
= dns_rdatatype_fromtext(&rdatatype
, ®ion
);
1832 if (result
!= ISC_R_SUCCESS
) {
1833 fprintf(stderr
, "'%s' is not a valid type: %s\n",
1834 word
, isc_result_totext(result
));
1838 rdataclass
= getzoneclass();
1839 result
= dns_rdatatype_fromtext(&rdatatype
, ®ion
);
1840 if (result
!= ISC_R_SUCCESS
) {
1841 fprintf(stderr
, "'%s' is not a valid class or type: "
1842 "%s\n", word
, isc_result_totext(result
));
1847 retval
= parse_rdata(&cmdline
, rdataclass
, rdatatype
, updatemsg
,
1849 if (retval
!= STATUS_MORE
)
1853 if ((rdata
->flags
& DNS_RDATA_UPDATE
) != 0)
1854 rdataclass
= dns_rdataclass_any
;
1856 rdataclass
= dns_rdataclass_none
;
1858 if ((rdata
->flags
& DNS_RDATA_UPDATE
) != 0) {
1859 fprintf(stderr
, "could not read rdata\n");
1866 result
= dns_message_gettemprdatalist(updatemsg
, &rdatalist
);
1867 check_result(result
, "dns_message_gettemprdatalist");
1868 result
= dns_message_gettemprdataset(updatemsg
, &rdataset
);
1869 check_result(result
, "dns_message_gettemprdataset");
1870 dns_rdatalist_init(rdatalist
);
1871 rdatalist
->type
= rdatatype
;
1872 rdatalist
->rdclass
= rdataclass
;
1873 rdatalist
->covers
= rdatatype
;
1874 rdatalist
->ttl
= (dns_ttl_t
)ttl
;
1875 ISC_LIST_INIT(rdatalist
->rdata
);
1876 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
1877 dns_rdatalist_tordataset(rdatalist
, rdataset
);
1878 ISC_LIST_INIT(name
->list
);
1879 ISC_LIST_APPEND(name
->list
, rdataset
, link
);
1880 dns_message_addname(updatemsg
, name
, DNS_SECTION_UPDATE
);
1881 return (STATUS_MORE
);
1885 dns_message_puttempname(updatemsg
, &name
);
1886 dns_message_puttemprdata(updatemsg
, &rdata
);
1887 return (STATUS_SYNTAX
);
1891 evaluate_update(char *cmdline
) {
1893 isc_boolean_t isdelete
;
1895 ddebug("evaluate_update()");
1896 word
= nsu_strsep(&cmdline
, " \t\r\n");
1897 if (word
== NULL
|| *word
== 0) {
1898 fprintf(stderr
, "could not read operation code\n");
1899 return (STATUS_SYNTAX
);
1901 if (strcasecmp(word
, "delete") == 0)
1902 isdelete
= ISC_TRUE
;
1903 else if (strcasecmp(word
, "del") == 0)
1904 isdelete
= ISC_TRUE
;
1905 else if (strcasecmp(word
, "add") == 0)
1906 isdelete
= ISC_FALSE
;
1908 fprintf(stderr
, "incorrect operation code: %s\n", word
);
1909 return (STATUS_SYNTAX
);
1911 return (update_addordelete(cmdline
, isdelete
));
1915 setzone(dns_name_t
*zonename
) {
1916 isc_result_t result
;
1917 dns_name_t
*name
= NULL
;
1918 dns_rdataset_t
*rdataset
= NULL
;
1920 result
= dns_message_firstname(updatemsg
, DNS_SECTION_ZONE
);
1921 if (result
== ISC_R_SUCCESS
) {
1922 dns_message_currentname(updatemsg
, DNS_SECTION_ZONE
, &name
);
1923 dns_message_removename(updatemsg
, name
, DNS_SECTION_ZONE
);
1924 for (rdataset
= ISC_LIST_HEAD(name
->list
);
1926 rdataset
= ISC_LIST_HEAD(name
->list
)) {
1927 ISC_LIST_UNLINK(name
->list
, rdataset
, link
);
1928 dns_rdataset_disassociate(rdataset
);
1929 dns_message_puttemprdataset(updatemsg
, &rdataset
);
1931 dns_message_puttempname(updatemsg
, &name
);
1934 if (zonename
!= NULL
) {
1935 result
= dns_message_gettempname(updatemsg
, &name
);
1936 check_result(result
, "dns_message_gettempname");
1937 dns_name_init(name
, NULL
);
1938 dns_name_clone(zonename
, name
);
1939 result
= dns_message_gettemprdataset(updatemsg
, &rdataset
);
1940 check_result(result
, "dns_message_gettemprdataset");
1941 dns_rdataset_makequestion(rdataset
, getzoneclass(),
1943 ISC_LIST_INIT(name
->list
);
1944 ISC_LIST_APPEND(name
->list
, rdataset
, link
);
1945 dns_message_addname(updatemsg
, name
, DNS_SECTION_ZONE
);
1950 show_message(FILE *stream
, dns_message_t
*msg
, const char *description
) {
1951 isc_result_t result
;
1952 isc_buffer_t
*buf
= NULL
;
1955 ddebug("show_message()");
1961 if (bufsz
> MAXTEXT
) {
1962 fprintf(stderr
, "could not allocate large enough "
1963 "buffer to display message\n");
1967 isc_buffer_free(&buf
);
1968 result
= isc_buffer_allocate(gmctx
, &buf
, bufsz
);
1969 check_result(result
, "isc_buffer_allocate");
1970 result
= dns_message_totext(msg
, style
, 0, buf
);
1972 } while (result
== ISC_R_NOSPACE
);
1973 if (result
!= ISC_R_SUCCESS
) {
1974 fprintf(stderr
, "could not convert message to text format.\n");
1975 isc_buffer_free(&buf
);
1978 fprintf(stream
, "%s\n%.*s", description
,
1979 (int)isc_buffer_usedlength(buf
), (char*)isc_buffer_base(buf
));
1980 isc_buffer_free(&buf
);
1984 do_next_command(char *cmdline
) {
1987 ddebug("do_next_command()");
1988 word
= nsu_strsep(&cmdline
, " \t\r\n");
1990 if (word
== NULL
|| *word
== 0)
1991 return (STATUS_SEND
);
1993 return (STATUS_MORE
);
1994 if (strcasecmp(word
, "quit") == 0)
1995 return (STATUS_QUIT
);
1996 if (strcasecmp(word
, "prereq") == 0)
1997 return (evaluate_prereq(cmdline
));
1998 if (strcasecmp(word
, "nxdomain") == 0)
1999 return (make_prereq(cmdline
, ISC_FALSE
, ISC_FALSE
));
2000 if (strcasecmp(word
, "yxdomain") == 0)
2001 return (make_prereq(cmdline
, ISC_TRUE
, ISC_FALSE
));
2002 if (strcasecmp(word
, "nxrrset") == 0)
2003 return (make_prereq(cmdline
, ISC_FALSE
, ISC_TRUE
));
2004 if (strcasecmp(word
, "yxrrset") == 0)
2005 return (make_prereq(cmdline
, ISC_TRUE
, ISC_TRUE
));
2006 if (strcasecmp(word
, "update") == 0)
2007 return (evaluate_update(cmdline
));
2008 if (strcasecmp(word
, "delete") == 0)
2009 return (update_addordelete(cmdline
, ISC_TRUE
));
2010 if (strcasecmp(word
, "del") == 0)
2011 return (update_addordelete(cmdline
, ISC_TRUE
));
2012 if (strcasecmp(word
, "add") == 0)
2013 return (update_addordelete(cmdline
, ISC_FALSE
));
2014 if (strcasecmp(word
, "server") == 0)
2015 return (evaluate_server(cmdline
));
2016 if (strcasecmp(word
, "local") == 0)
2017 return (evaluate_local(cmdline
));
2018 if (strcasecmp(word
, "zone") == 0)
2019 return (evaluate_zone(cmdline
));
2020 if (strcasecmp(word
, "class") == 0)
2021 return (evaluate_class(cmdline
));
2022 if (strcasecmp(word
, "send") == 0)
2023 return (STATUS_SEND
);
2024 if (strcasecmp(word
, "debug") == 0) {
2026 ddebugging
= ISC_TRUE
;
2028 debugging
= ISC_TRUE
;
2029 return (STATUS_MORE
);
2031 if (strcasecmp(word
, "ttl") == 0)
2032 return (evaluate_ttl(cmdline
));
2033 if (strcasecmp(word
, "show") == 0) {
2034 show_message(stdout
, updatemsg
, "Outgoing update query:");
2035 return (STATUS_MORE
);
2037 if (strcasecmp(word
, "answer") == 0) {
2039 show_message(stdout
, answer
, "Answer:");
2040 return (STATUS_MORE
);
2042 if (strcasecmp(word
, "key") == 0) {
2043 usegsstsig
= ISC_FALSE
;
2044 return (evaluate_key(cmdline
));
2046 if (strcasecmp(word
, "realm") == 0)
2047 return (evaluate_realm(cmdline
));
2048 if (strcasecmp(word
, "gsstsig") == 0) {
2050 usegsstsig
= ISC_TRUE
;
2051 use_win2k_gsstsig
= ISC_FALSE
;
2053 fprintf(stderr
, "gsstsig not supported\n");
2055 return (STATUS_MORE
);
2057 if (strcasecmp(word
, "oldgsstsig") == 0) {
2059 usegsstsig
= ISC_TRUE
;
2060 use_win2k_gsstsig
= ISC_TRUE
;
2062 fprintf(stderr
, "gsstsig not supported\n");
2064 return (STATUS_MORE
);
2066 if (strcasecmp(word
, "help") == 0) {
2068 "nsupdate " VERSION
":\n"
2069 "local address [port] (set local resolver)\n"
2070 "server address [port] (set master server for zone)\n"
2071 "send (send the update request)\n"
2072 "show (show the update request)\n"
2073 "answer (show the answer to the last request)\n"
2074 "quit (quit, any pending update is not sent\n"
2075 "help (display this message_\n"
2076 "key [hmac:]keyname secret (use TSIG to sign the request)\n"
2077 "gsstsig (use GSS_TSIG to sign the request)\n"
2078 "oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n"
2079 "zone name (set the zone to be updated)\n"
2080 "class CLASS (set the zone's DNS class, e.g. IN (default), CH)\n"
2081 "[prereq] nxdomain name (does this name not exist)\n"
2082 "[prereq] yxdomain name (does this name exist)\n"
2083 "[prereq] nxrrset .... (does this RRset exist)\n"
2084 "[prereq] yxrrset .... (does this RRset not exist)\n"
2085 "[update] add .... (add the given record to the zone)\n"
2086 "[update] del[ete] .... (remove the given record(s) from the zone)\n");
2087 return (STATUS_MORE
);
2089 if (strcasecmp(word
, "version") == 0) {
2090 fprintf(stdout
, "nsupdate " VERSION
"\n");
2091 return (STATUS_MORE
);
2093 fprintf(stderr
, "incorrect section name: %s\n", word
);
2094 return (STATUS_SYNTAX
);
2098 get_next_command(void) {
2099 isc_uint16_t result
= STATUS_QUIT
;
2100 char cmdlinebuf
[MAXCMD
];
2105 #ifdef HAVE_READLINE
2106 cmdline
= readline("> ");
2107 if (cmdline
!= NULL
)
2108 add_history(cmdline
);
2110 fprintf(stdout
, "> ");
2112 cmdline
= fgets(cmdlinebuf
, MAXCMD
, input
);
2115 cmdline
= fgets(cmdlinebuf
, MAXCMD
, input
);
2118 if (cmdline
!= NULL
) {
2119 char *tmp
= cmdline
;
2122 * Normalize input by removing any eol as readline()
2123 * removes eol but fgets doesn't.
2125 (void)nsu_strsep(&tmp
, "\r\n");
2126 result
= do_next_command(cmdline
);
2128 #ifdef HAVE_READLINE
2135 static isc_boolean_t
2136 user_interaction(void) {
2137 isc_uint16_t result
= STATUS_MORE
;
2139 ddebug("user_interaction()");
2140 while ((result
== STATUS_MORE
) || (result
== STATUS_SYNTAX
)) {
2141 result
= get_next_command();
2142 if (!interactive
&& result
== STATUS_SYNTAX
)
2143 fatal("syntax error");
2145 if (result
== STATUS_SEND
)
2153 isc_event_t
*event
= global_event
;
2154 ddebug("done_update()");
2155 isc_task_send(global_task
, &event
);
2159 check_tsig_error(dns_rdataset_t
*rdataset
, isc_buffer_t
*b
) {
2160 isc_result_t result
;
2161 dns_rdata_t rdata
= DNS_RDATA_INIT
;
2162 dns_rdata_any_tsig_t tsig
;
2164 result
= dns_rdataset_first(rdataset
);
2165 check_result(result
, "dns_rdataset_first");
2166 dns_rdataset_current(rdataset
, &rdata
);
2167 result
= dns_rdata_tostruct(&rdata
, &tsig
, NULL
);
2168 check_result(result
, "dns_rdata_tostruct");
2169 if (tsig
.error
!= 0) {
2170 if (isc_buffer_remaininglength(b
) < 1)
2171 check_result(ISC_R_NOSPACE
, "isc_buffer_remaininglength");
2172 isc_buffer_putstr(b
, "(" /*)*/);
2173 result
= dns_tsigrcode_totext(tsig
.error
, b
);
2174 check_result(result
, "dns_tsigrcode_totext");
2175 if (isc_buffer_remaininglength(b
) < 1)
2176 check_result(ISC_R_NOSPACE
, "isc_buffer_remaininglength");
2177 isc_buffer_putstr(b
, /*(*/ ")");
2181 static isc_boolean_t
2182 next_master(const char *caller
, isc_sockaddr_t
*addr
, isc_result_t eresult
) {
2183 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
2185 isc_sockaddr_format(addr
, addrbuf
, sizeof(addrbuf
));
2186 fprintf(stderr
, "; Communication with %s failed: %s\n",
2187 addrbuf
, isc_result_totext(eresult
));
2188 if (++master_inuse
>= master_total
)
2190 ddebug("%s: trying next server", caller
);
2195 update_completed(isc_task_t
*task
, isc_event_t
*event
) {
2196 dns_requestevent_t
*reqev
= NULL
;
2197 isc_result_t result
;
2198 dns_request_t
*request
;
2202 ddebug("update_completed()");
2206 REQUIRE(event
->ev_type
== DNS_EVENT_REQUESTDONE
);
2207 reqev
= (dns_requestevent_t
*)event
;
2208 request
= reqev
->request
;
2211 dns_request_destroy(&request
);
2212 isc_event_free(&event
);
2217 if (reqev
->result
!= ISC_R_SUCCESS
) {
2218 if (!next_master("recvsoa", &master_servers
[master_inuse
],
2220 seenerror
= ISC_TRUE
;
2224 ddebug("Destroying request [%p]", request
);
2225 dns_request_destroy(&request
);
2226 dns_message_renderreset(updatemsg
);
2227 dns_message_settsigkey(updatemsg
, NULL
);
2228 send_update(zname
, &master_servers
[master_inuse
]);
2229 isc_event_free(&event
);
2233 result
= dns_message_create(gmctx
, DNS_MESSAGE_INTENTPARSE
, &answer
);
2234 check_result(result
, "dns_message_create");
2235 result
= dns_request_getresponse(request
, answer
,
2236 DNS_MESSAGEPARSE_PRESERVEORDER
);
2239 if (answer
->verify_attempted
)
2240 ddebug("tsig verification successful");
2242 case DNS_R_CLOCKSKEW
:
2243 case DNS_R_EXPECTEDTSIG
:
2244 case DNS_R_TSIGERRORSET
:
2245 case DNS_R_TSIGVERIFYFAILURE
:
2246 case DNS_R_UNEXPECTEDTSIG
:
2249 if (usegsstsig
&& answer
->rcode
== dns_rcode_noerror
) {
2251 * For MS DNS that violates RFC 2845, section 4.2
2256 fprintf(stderr
, "; TSIG error with server: %s\n",
2257 isc_result_totext(result
));
2258 seenerror
= ISC_TRUE
;
2261 check_result(result
, "dns_request_getresponse");
2264 if (answer
->rcode
!= dns_rcode_noerror
) {
2265 seenerror
= ISC_TRUE
;
2269 dns_rdataset_t
*rds
;
2271 isc_buffer_init(&b
, buf
, sizeof(buf
) - 1);
2272 result
= dns_rcode_totext(answer
->rcode
, &b
);
2273 check_result(result
, "dns_rcode_totext");
2274 rds
= dns_message_gettsig(answer
, NULL
);
2276 check_tsig_error(rds
, &b
);
2277 fprintf(stderr
, "update failed: %.*s\n",
2278 (int)isc_buffer_usedlength(&b
), buf
);
2282 show_message(stderr
, answer
, "\nReply from update query:");
2285 dns_request_destroy(&request
);
2287 dns_name_free(&tmpzonename
, gmctx
);
2288 dns_name_free(&restart_master
, gmctx
);
2290 isc_event_free(&event
);
2295 send_update(dns_name_t
*zone
, isc_sockaddr_t
*master
) {
2296 isc_result_t result
;
2297 dns_request_t
*request
= NULL
;
2298 unsigned int options
= DNS_REQUESTOPT_CASE
;
2299 isc_sockaddr_t
*srcaddr
;
2301 ddebug("send_update()");
2306 options
|= DNS_REQUESTOPT_TCP
;
2307 if (tsigkey
== NULL
&& sig0key
!= NULL
) {
2308 result
= dns_message_setsig0key(updatemsg
, sig0key
);
2309 check_result(result
, "dns_message_setsig0key");
2312 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
2314 isc_sockaddr_format(master
, addrbuf
, sizeof(addrbuf
));
2315 fprintf(stderr
, "Sending update to %s\n", addrbuf
);
2318 if (isc_sockaddr_pf(master
) == AF_INET6
)
2319 srcaddr
= localaddr6
;
2321 srcaddr
= localaddr4
;
2323 /* Windows doesn't like the tsig name to be compressed. */
2324 if (updatemsg
->tsigname
)
2325 updatemsg
->tsigname
->attributes
|= DNS_NAMEATTR_NOCOMPRESS
;
2327 result
= dns_request_createvia3(requestmgr
, updatemsg
, srcaddr
,
2328 master
, options
, tsigkey
, timeout
,
2329 udp_timeout
, udp_retries
, global_task
,
2330 update_completed
, NULL
, &request
);
2331 check_result(result
, "dns_request_createvia3");
2334 show_message(stdout
, updatemsg
, "Outgoing update query:");
2340 next_server(const char *caller
, isc_sockaddr_t
*addr
, isc_result_t eresult
) {
2341 char addrbuf
[ISC_SOCKADDR_FORMATSIZE
];
2343 isc_sockaddr_format(addr
, addrbuf
, sizeof(addrbuf
));
2344 fprintf(stderr
, "; Communication with %s failed: %s\n",
2345 addrbuf
, isc_result_totext(eresult
));
2346 if (++ns_inuse
>= ns_total
)
2347 fatal("could not reach any name server");
2349 ddebug("%s: trying next server", caller
);
2353 recvsoa(isc_task_t
*task
, isc_event_t
*event
) {
2354 dns_requestevent_t
*reqev
= NULL
;
2355 dns_request_t
*request
= NULL
;
2356 isc_result_t result
, eresult
;
2357 dns_message_t
*rcvmsg
= NULL
;
2358 dns_section_t section
;
2359 dns_name_t
*name
= NULL
;
2360 dns_rdataset_t
*soaset
= NULL
;
2361 dns_rdata_soa_t soa
;
2362 dns_rdata_t soarr
= DNS_RDATA_INIT
;
2365 nsu_requestinfo_t
*reqinfo
;
2366 dns_message_t
*soaquery
= NULL
;
2367 isc_sockaddr_t
*addr
;
2368 isc_sockaddr_t
*srcaddr
;
2369 isc_boolean_t seencname
= ISC_FALSE
;
2371 unsigned int nlabels
;
2375 ddebug("recvsoa()");
2379 REQUIRE(event
->ev_type
== DNS_EVENT_REQUESTDONE
);
2380 reqev
= (dns_requestevent_t
*)event
;
2381 request
= reqev
->request
;
2382 eresult
= reqev
->result
;
2383 reqinfo
= reqev
->ev_arg
;
2384 soaquery
= reqinfo
->msg
;
2385 addr
= reqinfo
->addr
;
2388 dns_request_destroy(&request
);
2389 dns_message_destroy(&soaquery
);
2390 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_requestinfo_t
));
2391 isc_event_free(&event
);
2396 if (eresult
!= ISC_R_SUCCESS
) {
2397 next_server("recvsoa", addr
, eresult
);
2398 ddebug("Destroying request [%p]", request
);
2399 dns_request_destroy(&request
);
2400 dns_message_renderreset(soaquery
);
2401 dns_message_settsigkey(soaquery
, NULL
);
2402 sendrequest(&servers
[ns_inuse
], soaquery
, &request
);
2403 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_requestinfo_t
));
2404 isc_event_free(&event
);
2405 setzoneclass(dns_rdataclass_none
);
2409 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_requestinfo_t
));
2411 isc_event_free(&event
);
2414 ddebug("About to create rcvmsg");
2415 result
= dns_message_create(gmctx
, DNS_MESSAGE_INTENTPARSE
, &rcvmsg
);
2416 check_result(result
, "dns_message_create");
2417 result
= dns_request_getresponse(request
, rcvmsg
,
2418 DNS_MESSAGEPARSE_PRESERVEORDER
);
2419 if (result
== DNS_R_TSIGERRORSET
&& servers
!= NULL
) {
2420 dns_message_destroy(&rcvmsg
);
2421 ddebug("Destroying request [%p]", request
);
2422 dns_request_destroy(&request
);
2423 reqinfo
= isc_mem_get(gmctx
, sizeof(nsu_requestinfo_t
));
2424 if (reqinfo
== NULL
)
2425 fatal("out of memory");
2426 reqinfo
->msg
= soaquery
;
2427 reqinfo
->addr
= addr
;
2428 dns_message_renderreset(soaquery
);
2429 ddebug("retrying soa request without TSIG");
2431 if (isc_sockaddr_pf(addr
) == AF_INET6
)
2432 srcaddr
= localaddr6
;
2434 srcaddr
= localaddr4
;
2436 result
= dns_request_createvia3(requestmgr
, soaquery
, srcaddr
,
2440 global_task
, recvsoa
, reqinfo
,
2442 check_result(result
, "dns_request_createvia");
2446 check_result(result
, "dns_request_getresponse");
2447 section
= DNS_SECTION_ANSWER
;
2450 show_message(stderr
, rcvmsg
, "Reply from SOA query:");
2452 if (rcvmsg
->rcode
!= dns_rcode_noerror
&&
2453 rcvmsg
->rcode
!= dns_rcode_nxdomain
)
2454 fatal("response to SOA query was unsuccessful");
2456 if (userzone
!= NULL
&& rcvmsg
->rcode
== dns_rcode_nxdomain
) {
2457 char namebuf
[DNS_NAME_FORMATSIZE
];
2458 dns_name_format(userzone
, namebuf
, sizeof(namebuf
));
2459 error("specified zone '%s' does not exist (NXDOMAIN)",
2461 dns_message_destroy(&rcvmsg
);
2462 dns_request_destroy(&request
);
2463 dns_message_destroy(&soaquery
);
2464 ddebug("Out of recvsoa");
2466 seenerror
= ISC_TRUE
;
2472 section
= DNS_SECTION_ANSWER
;
2474 section
= DNS_SECTION_AUTHORITY
;
2478 result
= dns_message_firstname(rcvmsg
, section
);
2479 if (result
!= ISC_R_SUCCESS
) {
2483 while (result
== ISC_R_SUCCESS
) {
2485 dns_message_currentname(rcvmsg
, section
, &name
);
2487 result
= dns_message_findtype(name
, dns_rdatatype_soa
, 0,
2489 if (result
== ISC_R_SUCCESS
)
2491 if (section
== DNS_SECTION_ANSWER
) {
2492 dns_rdataset_t
*tset
= NULL
;
2493 if (dns_message_findtype(name
, dns_rdatatype_cname
, 0,
2494 &tset
) == ISC_R_SUCCESS
||
2495 dns_message_findtype(name
, dns_rdatatype_dname
, 0,
2496 &tset
) == ISC_R_SUCCESS
) {
2497 seencname
= ISC_TRUE
;
2502 result
= dns_message_nextname(rcvmsg
, section
);
2505 if (soaset
== NULL
&& !seencname
) {
2514 char namestr
[DNS_NAME_FORMATSIZE
];
2515 dns_name_format(name
, namestr
, sizeof(namestr
));
2516 fprintf(stderr
, "Found zone name: %s\n", namestr
);
2519 result
= dns_rdataset_first(soaset
);
2520 check_result(result
, "dns_rdataset_first");
2522 dns_rdata_init(&soarr
);
2523 dns_rdataset_current(soaset
, &soarr
);
2524 result
= dns_rdata_tostruct(&soarr
, &soa
, NULL
);
2525 check_result(result
, "dns_rdata_tostruct");
2527 dns_name_init(&master
, NULL
);
2528 dns_name_clone(&soa
.origin
, &master
);
2530 if (userzone
!= NULL
)
2536 char namestr
[DNS_NAME_FORMATSIZE
];
2537 dns_name_format(&master
, namestr
, sizeof(namestr
));
2538 fprintf(stderr
, "The master is: %s\n", namestr
);
2541 if (default_servers
) {
2542 char serverstr
[DNS_NAME_MAXTEXT
+1];
2546 isc_buffer_init(&buf
, serverstr
, sizeof(serverstr
));
2547 result
= dns_name_totext(&master
, ISC_TRUE
, &buf
);
2548 check_result(result
, "dns_name_totext");
2549 serverstr
[isc_buffer_usedlength(&buf
)] = 0;
2551 if (master_servers
!= NULL
&& master_servers
!= servers
)
2552 isc_mem_put(gmctx
, master_servers
,
2553 master_total
* sizeof(isc_sockaddr_t
));
2554 master_total
= MAX_SERVERADDRS
;
2555 size
= master_total
* sizeof(isc_sockaddr_t
);
2556 master_servers
= isc_mem_get(gmctx
, size
);
2557 if (master_servers
== NULL
)
2558 fatal("out of memory");
2560 memset(master_servers
, 0, size
);
2561 get_addresses(serverstr
, dnsport
, master_servers
, master_total
);
2564 master_from_servers();
2565 dns_rdata_freestruct(&soa
);
2569 dns_name_init(&tmpzonename
, NULL
);
2570 dns_name_dup(zname
, gmctx
, &tmpzonename
);
2571 dns_name_init(&restart_master
, NULL
);
2572 dns_name_dup(&master
, gmctx
, &restart_master
);
2573 start_gssrequest(&master
);
2575 send_update(zname
, &master_servers
[master_inuse
]);
2576 setzoneclass(dns_rdataclass_none
);
2579 send_update(zname
, &master_servers
[master_inuse
]);
2580 setzoneclass(dns_rdataclass_none
);
2583 dns_message_destroy(&soaquery
);
2584 dns_request_destroy(&request
);
2587 dns_message_destroy(&rcvmsg
);
2588 ddebug("Out of recvsoa");
2592 result
= dns_message_firstname(soaquery
, DNS_SECTION_QUESTION
);
2593 INSIST(result
== ISC_R_SUCCESS
);
2595 dns_message_currentname(soaquery
, DNS_SECTION_QUESTION
, &name
);
2596 nlabels
= dns_name_countlabels(name
);
2598 fatal("could not find enclosing zone");
2599 dns_name_init(&tname
, NULL
);
2600 dns_name_getlabelsequence(name
, 1, nlabels
- 1, &tname
);
2601 dns_name_clone(&tname
, name
);
2602 dns_request_destroy(&request
);
2603 dns_message_renderreset(soaquery
);
2604 dns_message_settsigkey(soaquery
, NULL
);
2605 sendrequest(&servers
[ns_inuse
], soaquery
, &request
);
2610 sendrequest(isc_sockaddr_t
*destaddr
, dns_message_t
*msg
,
2611 dns_request_t
**request
)
2613 isc_result_t result
;
2614 nsu_requestinfo_t
*reqinfo
;
2615 isc_sockaddr_t
*srcaddr
;
2617 reqinfo
= isc_mem_get(gmctx
, sizeof(nsu_requestinfo_t
));
2618 if (reqinfo
== NULL
)
2619 fatal("out of memory");
2621 reqinfo
->addr
= destaddr
;
2623 if (isc_sockaddr_pf(destaddr
) == AF_INET6
)
2624 srcaddr
= localaddr6
;
2626 srcaddr
= localaddr4
;
2628 result
= dns_request_createvia3(requestmgr
, msg
, srcaddr
, destaddr
, 0,
2629 default_servers
? NULL
: tsigkey
,
2630 FIND_TIMEOUT
* 20, FIND_TIMEOUT
, 3,
2631 global_task
, recvsoa
, reqinfo
, request
);
2632 check_result(result
, "dns_request_createvia");
2639 * Get the realm from the users kerberos ticket if possible
2642 get_ticket_realm(isc_mem_t
*mctx
) {
2646 krb5_principal princ
;
2647 char *name
, *ticket_realm
;
2649 rc
= krb5_init_context(&ctx
);
2653 rc
= krb5_cc_default(ctx
, &ccache
);
2655 krb5_free_context(ctx
);
2659 rc
= krb5_cc_get_principal(ctx
, ccache
, &princ
);
2661 krb5_cc_close(ctx
, ccache
);
2662 krb5_free_context(ctx
);
2666 rc
= krb5_unparse_name(ctx
, princ
, &name
);
2668 krb5_free_principal(ctx
, princ
);
2669 krb5_cc_close(ctx
, ccache
);
2670 krb5_free_context(ctx
);
2674 ticket_realm
= strrchr(name
, '@');
2675 if (ticket_realm
!= NULL
) {
2676 realm
= isc_mem_strdup(mctx
, ticket_realm
);
2680 krb5_free_principal(ctx
, princ
);
2681 krb5_cc_close(ctx
, ccache
);
2682 krb5_free_context(ctx
);
2683 if (realm
!= NULL
&& debugging
)
2684 fprintf(stderr
, "Found realm from ticket: %s\n", realm
+1);
2689 start_gssrequest(dns_name_t
*master
) {
2690 gss_ctx_id_t context
;
2692 isc_result_t result
;
2693 isc_uint32_t val
= 0;
2694 dns_message_t
*rmsg
;
2695 dns_request_t
*request
= NULL
;
2696 dns_name_t
*servname
;
2697 dns_fixedname_t fname
;
2698 char namestr
[DNS_NAME_FORMATSIZE
];
2699 char mykeystr
[DNS_NAME_FORMATSIZE
];
2700 char *err_message
= NULL
;
2702 debug("start_gssrequest");
2705 if (gssring
!= NULL
)
2706 dns_tsigkeyring_detach(&gssring
);
2708 result
= dns_tsigkeyring_create(gmctx
, &gssring
);
2710 if (result
!= ISC_R_SUCCESS
)
2711 fatal("dns_tsigkeyring_create failed: %s",
2712 isc_result_totext(result
));
2714 dns_name_format(master
, namestr
, sizeof(namestr
));
2715 if (kserver
== NULL
) {
2716 kserver
= isc_mem_get(gmctx
, sizeof(isc_sockaddr_t
));
2717 if (kserver
== NULL
)
2718 fatal("out of memory");
2720 if (servers
== NULL
)
2721 get_addresses(namestr
, dnsport
, kserver
, 1);
2723 memmove(kserver
, &servers
[ns_inuse
], sizeof(isc_sockaddr_t
));
2725 dns_fixedname_init(&fname
);
2726 servname
= dns_fixedname_name(&fname
);
2729 get_ticket_realm(gmctx
);
2731 result
= isc_string_printf(servicename
, sizeof(servicename
),
2732 "DNS/%s%s", namestr
, realm
? realm
: "");
2733 if (result
!= ISC_R_SUCCESS
)
2734 fatal("isc_string_printf(servicename) failed: %s",
2735 isc_result_totext(result
));
2736 isc_buffer_init(&buf
, servicename
, strlen(servicename
));
2737 isc_buffer_add(&buf
, strlen(servicename
));
2738 result
= dns_name_fromtext(servname
, &buf
, dns_rootname
, 0, NULL
);
2739 if (result
!= ISC_R_SUCCESS
)
2740 fatal("dns_name_fromtext(servname) failed: %s",
2741 isc_result_totext(result
));
2743 dns_fixedname_init(&fkname
);
2744 keyname
= dns_fixedname_name(&fkname
);
2746 isc_random_get(&val
);
2747 result
= isc_string_printf(mykeystr
, sizeof(mykeystr
), "%u.sig-%s",
2749 if (result
!= ISC_R_SUCCESS
)
2750 fatal("isc_string_printf(mykeystr) failed: %s",
2751 isc_result_totext(result
));
2752 isc_buffer_init(&buf
, mykeystr
, strlen(mykeystr
));
2753 isc_buffer_add(&buf
, strlen(mykeystr
));
2755 result
= dns_name_fromtext(keyname
, &buf
, dns_rootname
, 0, NULL
);
2756 if (result
!= ISC_R_SUCCESS
)
2757 fatal("dns_name_fromtext(keyname) failed: %s",
2758 isc_result_totext(result
));
2760 /* Windows doesn't recognize name compression in the key name. */
2761 keyname
->attributes
|= DNS_NAMEATTR_NOCOMPRESS
;
2764 result
= dns_message_create(gmctx
, DNS_MESSAGE_INTENTRENDER
, &rmsg
);
2765 if (result
!= ISC_R_SUCCESS
)
2766 fatal("dns_message_create failed: %s",
2767 isc_result_totext(result
));
2769 /* Build first request. */
2770 context
= GSS_C_NO_CONTEXT
;
2771 result
= dns_tkey_buildgssquery(rmsg
, keyname
, servname
, NULL
, 0,
2772 &context
, use_win2k_gsstsig
,
2773 gmctx
, &err_message
);
2774 if (result
== ISC_R_FAILURE
)
2775 fatal("tkey query failed: %s",
2776 err_message
!= NULL
? err_message
: "unknown error");
2777 if (result
!= ISC_R_SUCCESS
)
2778 fatal("dns_tkey_buildgssquery failed: %s",
2779 isc_result_totext(result
));
2781 send_gssrequest(kserver
, rmsg
, &request
, context
);
2785 send_gssrequest(isc_sockaddr_t
*destaddr
, dns_message_t
*msg
,
2786 dns_request_t
**request
, gss_ctx_id_t context
)
2788 isc_result_t result
;
2789 nsu_gssinfo_t
*reqinfo
;
2790 unsigned int options
= 0;
2791 isc_sockaddr_t
*srcaddr
;
2793 debug("send_gssrequest");
2794 reqinfo
= isc_mem_get(gmctx
, sizeof(nsu_gssinfo_t
));
2795 if (reqinfo
== NULL
)
2796 fatal("out of memory");
2798 reqinfo
->addr
= destaddr
;
2799 reqinfo
->context
= context
;
2801 options
|= DNS_REQUESTOPT_TCP
;
2803 if (isc_sockaddr_pf(destaddr
) == AF_INET6
)
2804 srcaddr
= localaddr6
;
2806 srcaddr
= localaddr4
;
2808 result
= dns_request_createvia3(requestmgr
, msg
, srcaddr
, destaddr
,
2809 options
, tsigkey
, FIND_TIMEOUT
* 20,
2810 FIND_TIMEOUT
, 3, global_task
, recvgss
,
2812 check_result(result
, "dns_request_createvia3");
2814 show_message(stdout
, msg
, "Outgoing update query:");
2819 recvgss(isc_task_t
*task
, isc_event_t
*event
) {
2820 dns_requestevent_t
*reqev
= NULL
;
2821 dns_request_t
*request
= NULL
;
2822 isc_result_t result
, eresult
;
2823 dns_message_t
*rcvmsg
= NULL
;
2824 nsu_gssinfo_t
*reqinfo
;
2825 dns_message_t
*tsigquery
= NULL
;
2826 isc_sockaddr_t
*addr
;
2827 gss_ctx_id_t context
;
2829 dns_name_t
*servname
;
2830 dns_fixedname_t fname
;
2831 char *err_message
= NULL
;
2835 ddebug("recvgss()");
2839 REQUIRE(event
->ev_type
== DNS_EVENT_REQUESTDONE
);
2840 reqev
= (dns_requestevent_t
*)event
;
2841 request
= reqev
->request
;
2842 eresult
= reqev
->result
;
2843 reqinfo
= reqev
->ev_arg
;
2844 tsigquery
= reqinfo
->msg
;
2845 context
= reqinfo
->context
;
2846 addr
= reqinfo
->addr
;
2849 dns_request_destroy(&request
);
2850 dns_message_destroy(&tsigquery
);
2851 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_gssinfo_t
));
2852 isc_event_free(&event
);
2857 if (eresult
!= ISC_R_SUCCESS
) {
2858 next_server("recvgss", addr
, eresult
);
2859 ddebug("Destroying request [%p]", request
);
2860 dns_request_destroy(&request
);
2861 dns_message_renderreset(tsigquery
);
2862 sendrequest(&servers
[ns_inuse
], tsigquery
, &request
);
2863 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_gssinfo_t
));
2864 isc_event_free(&event
);
2867 isc_mem_put(gmctx
, reqinfo
, sizeof(nsu_gssinfo_t
));
2869 isc_event_free(&event
);
2872 ddebug("recvgss creating rcvmsg");
2873 result
= dns_message_create(gmctx
, DNS_MESSAGE_INTENTPARSE
, &rcvmsg
);
2874 check_result(result
, "dns_message_create");
2876 result
= dns_request_getresponse(request
, rcvmsg
,
2877 DNS_MESSAGEPARSE_PRESERVEORDER
);
2878 check_result(result
, "dns_request_getresponse");
2881 show_message(stderr
, rcvmsg
,
2882 "recvmsg reply from GSS-TSIG query");
2884 if (rcvmsg
->rcode
== dns_rcode_formerr
&& !tried_other_gsstsig
) {
2885 ddebug("recvgss trying %s GSS-TSIG",
2886 use_win2k_gsstsig
? "Standard" : "Win2k");
2887 if (use_win2k_gsstsig
)
2888 use_win2k_gsstsig
= ISC_FALSE
;
2890 use_win2k_gsstsig
= ISC_TRUE
;
2891 tried_other_gsstsig
= ISC_TRUE
;
2892 start_gssrequest(&restart_master
);
2896 if (rcvmsg
->rcode
!= dns_rcode_noerror
&&
2897 rcvmsg
->rcode
!= dns_rcode_nxdomain
)
2898 fatal("response to GSS-TSIG query was unsuccessful");
2901 dns_fixedname_init(&fname
);
2902 servname
= dns_fixedname_name(&fname
);
2903 isc_buffer_init(&buf
, servicename
, strlen(servicename
));
2904 isc_buffer_add(&buf
, strlen(servicename
));
2905 result
= dns_name_fromtext(servname
, &buf
, dns_rootname
, 0, NULL
);
2906 check_result(result
, "dns_name_fromtext");
2909 result
= dns_tkey_gssnegotiate(tsigquery
, rcvmsg
, servname
,
2910 &context
, &tsigkey
, gssring
,
2915 case DNS_R_CONTINUE
:
2916 send_gssrequest(kserver
, tsigquery
, &request
, context
);
2921 * XXXSRA Waaay too much fun here. There's no good
2922 * reason why we need a TSIG here (the people who put
2923 * it into the spec admitted at the time that it was
2924 * not a security issue), and Windows clients don't
2925 * seem to work if named complies with the spec and
2926 * includes the gratuitous TSIG. So we're in the
2927 * bizarre situation of having to choose between
2928 * complying with a useless requirement in the spec
2929 * and interoperating. This is nuts. If we can
2930 * confirm this behavior, we should ask the WG to
2931 * consider removing the requirement for the
2932 * gratuitous TSIG here. For the moment, we ignore
2933 * the TSIG -- this too is a spec violation, but it's
2934 * the least insane thing to do.
2938 * Verify the signature.
2940 rcvmsg
->state
= DNS_SECTION_ANY
;
2941 dns_message_setquerytsig(rcvmsg
, NULL
);
2942 result
= dns_message_settsigkey(rcvmsg
, tsigkey
);
2943 check_result(result
, "dns_message_settsigkey");
2944 result
= dns_message_checksig(rcvmsg
, NULL
);
2945 ddebug("tsig verification: %s", dns_result_totext(result
));
2946 check_result(result
, "dns_message_checksig");
2949 send_update(&tmpzonename
, &master_servers
[master_inuse
]);
2950 setzoneclass(dns_rdataclass_none
);
2954 fatal("dns_tkey_negotiategss: %s %s",
2955 isc_result_totext(result
),
2956 err_message
!= NULL
? err_message
: "");
2960 dns_request_destroy(&request
);
2961 dns_message_destroy(&tsigquery
);
2963 dns_message_destroy(&rcvmsg
);
2964 ddebug("Out of recvgss");
2969 start_update(void) {
2970 isc_result_t result
;
2971 dns_rdataset_t
*rdataset
= NULL
;
2972 dns_name_t
*name
= NULL
;
2973 dns_request_t
*request
= NULL
;
2974 dns_message_t
*soaquery
= NULL
;
2975 dns_name_t
*firstname
;
2976 dns_section_t section
= DNS_SECTION_UPDATE
;
2978 ddebug("start_update()");
2981 dns_message_destroy(&answer
);
2984 * If we have both the zone and the servers we have enough information
2985 * to send the update straight away otherwise we need to discover
2986 * the zone and / or the master server.
2988 if (userzone
!= NULL
&& !default_servers
&& !usegsstsig
) {
2989 master_from_servers();
2990 send_update(userzone
, &master_servers
[master_inuse
]);
2991 setzoneclass(dns_rdataclass_none
);
2995 result
= dns_message_create(gmctx
, DNS_MESSAGE_INTENTRENDER
,
2997 check_result(result
, "dns_message_create");
2999 if (default_servers
)
3000 soaquery
->flags
|= DNS_MESSAGEFLAG_RD
;
3002 result
= dns_message_gettempname(soaquery
, &name
);
3003 check_result(result
, "dns_message_gettempname");
3005 result
= dns_message_gettemprdataset(soaquery
, &rdataset
);
3006 check_result(result
, "dns_message_gettemprdataset");
3008 dns_rdataset_makequestion(rdataset
, getzoneclass(), dns_rdatatype_soa
);
3010 if (userzone
!= NULL
) {
3011 dns_name_init(name
, NULL
);
3012 dns_name_clone(userzone
, name
);
3014 dns_rdataset_t
*tmprdataset
;
3015 result
= dns_message_firstname(updatemsg
, section
);
3016 if (result
== ISC_R_NOMORE
) {
3017 section
= DNS_SECTION_PREREQUISITE
;
3018 result
= dns_message_firstname(updatemsg
, section
);
3020 if (result
!= ISC_R_SUCCESS
) {
3021 dns_message_puttempname(soaquery
, &name
);
3022 dns_rdataset_disassociate(rdataset
);
3023 dns_message_puttemprdataset(soaquery
, &rdataset
);
3024 dns_message_destroy(&soaquery
);
3029 dns_message_currentname(updatemsg
, section
, &firstname
);
3030 dns_name_init(name
, NULL
);
3031 dns_name_clone(firstname
, name
);
3033 * Looks to see if the first name references a DS record
3034 * and if that name is not the root remove a label as DS
3035 * records live in the parent zone so we need to start our
3036 * search one label up.
3038 tmprdataset
= ISC_LIST_HEAD(firstname
->list
);
3039 if (section
== DNS_SECTION_UPDATE
&&
3040 !dns_name_equal(firstname
, dns_rootname
) &&
3041 tmprdataset
->type
== dns_rdatatype_ds
) {
3042 unsigned int labels
= dns_name_countlabels(name
);
3043 dns_name_getlabelsequence(name
, 1, labels
- 1, name
);
3047 ISC_LIST_INIT(name
->list
);
3048 ISC_LIST_APPEND(name
->list
, rdataset
, link
);
3049 dns_message_addname(soaquery
, name
, DNS_SECTION_QUESTION
);
3052 sendrequest(&servers
[ns_inuse
], soaquery
, &request
);
3057 ddebug("cleanup()");
3060 dns_message_destroy(&answer
);
3063 if (tsigkey
!= NULL
) {
3064 ddebug("detach tsigkey x%p", tsigkey
);
3065 dns_tsigkey_detach(&tsigkey
);
3067 if (gssring
!= NULL
) {
3068 ddebug("Detaching GSS-TSIG keyring");
3069 dns_tsigkeyring_detach(&gssring
);
3071 if (kserver
!= NULL
) {
3072 isc_mem_put(gmctx
, kserver
, sizeof(isc_sockaddr_t
));
3075 if (realm
!= NULL
) {
3076 isc_mem_free(gmctx
, realm
);
3081 if (sig0key
!= NULL
)
3082 dst_key_free(&sig0key
);
3084 ddebug("Shutting down task manager");
3085 isc_taskmgr_destroy(&taskmgr
);
3087 ddebug("Destroying event");
3088 isc_event_free(&global_event
);
3090 ddebug("Shutting down socket manager");
3091 isc_socketmgr_destroy(&socketmgr
);
3093 ddebug("Shutting down timer manager");
3094 isc_timermgr_destroy(&timermgr
);
3096 ddebug("Destroying hash context");
3099 ddebug("Destroying name state");
3102 ddebug("Removing log context");
3103 isc_log_destroy(&glctx
);
3105 ddebug("Destroying memory context");
3107 isc_mem_stats(gmctx
, stderr
);
3108 isc_mem_destroy(&gmctx
);
3112 getinput(isc_task_t
*task
, isc_event_t
*event
) {
3122 if (global_event
== NULL
)
3123 global_event
= event
;
3126 more
= user_interaction();
3136 main(int argc
, char **argv
) {
3137 isc_result_t result
;
3138 style
= &dns_master_style_debug
;
3142 interactive
= ISC_TF(isatty(0));
3146 pre_parse_args(argc
, argv
);
3148 result
= isc_mem_create(0, 0, &gmctx
);
3149 check_result(result
, "isc_mem_create");
3151 parse_args(argc
, argv
, gmctx
, &entropy
);
3155 result
= isc_app_onrun(gmctx
, global_task
, getinput
, NULL
);
3156 check_result(result
, "isc_app_onrun");
3158 (void)isc_app_run();