示例#1
0
文件: tsig.c 项目: execunix/vinos
isc_result_t
dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) {
	isc_result_t result;
	dns_rbtnodechain_t chain;
	dns_name_t foundname;
	dns_fixedname_t fixedorigin;
	dns_name_t *origin;
	isc_stdtime_t now;
	dns_rbtnode_t *node;
	dns_tsigkey_t *tkey;
	dns_tsig_keyring_t *ring;
	unsigned int references;

	REQUIRE(ringp != NULL && *ringp != NULL);

	ring = *ringp;
	*ringp = NULL;

	RWLOCK(&ring->lock, isc_rwlocktype_write);
	INSIST(ring->references > 0);
	ring->references--;
	references = ring->references;
	RWUNLOCK(&ring->lock, isc_rwlocktype_write);

	if (references != 0)
		return (DNS_R_CONTINUE);

	isc_stdtime_get(&now);
	dns_name_init(&foundname, NULL);
	dns_fixedname_init(&fixedorigin);
	origin = dns_fixedname_name(&fixedorigin);
	dns_rbtnodechain_init(&chain, ring->mctx);
	result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
					origin);
	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
		dns_rbtnodechain_invalidate(&chain);
		goto destroy;
	}

	for (;;) {
		node = NULL;
		dns_rbtnodechain_current(&chain, &foundname, origin, &node);
		tkey = node->data;
		if (tkey != NULL && tkey->generated && tkey->expire >= now)
			dump_key(tkey, fp);
		result = dns_rbtnodechain_next(&chain, &foundname,
					       origin);
		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
			dns_rbtnodechain_invalidate(&chain);
			if (result == ISC_R_NOMORE)
				result = ISC_R_SUCCESS;
			goto destroy;
		}
	}

 destroy:
	destroyring(ring);
	return (result);
}
示例#2
0
static void
iterate(dns_rbt_t *rbt, isc_boolean_t forward) {
	dns_name_t foundname, *origin;
	dns_rbtnodechain_t chain;
	dns_fixedname_t fixedorigin;
	isc_result_t result;
	isc_result_t (*move)(dns_rbtnodechain_t *chain, dns_name_t *name,
			     dns_name_t *origin);

	dns_rbtnodechain_init(&chain, mctx);

	dns_name_init(&foundname, NULL);
	dns_fixedname_init(&fixedorigin);
	origin = dns_fixedname_name(&fixedorigin);

	if (forward) {
		printf("iterating forward\n" );
		move = dns_rbtnodechain_next;

		result = dns_rbtnodechain_first(&chain, rbt, &foundname,
						origin);

	} else {
		printf("iterating backward\n" );
		move = dns_rbtnodechain_prev;

		result = dns_rbtnodechain_last(&chain, rbt, &foundname,
					       origin);
	}

	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
		printf("start not found!\n");

	else {
		for (;;) {
			if (result == DNS_R_NEWORIGIN) {
				printf("  new origin: ");
				print_name(origin);
				printf("\n");
			}

			if (result == ISC_R_SUCCESS ||
			    result == DNS_R_NEWORIGIN) {
				print_name(&foundname);
				printf("\n");

			} else {
				if (result != ISC_R_NOMORE)
				       printf("UNEXEPCTED ITERATION ERROR: %s",
					      dns_result_totext(result));
				break;
			}

			result = move(&chain, &foundname, origin);
		}
	}
}
示例#3
0
文件: tsig.c 项目: execunix/vinos
/*
 * Find a few nodes to destroy if possible.
 */
static void
cleanup_ring(dns_tsig_keyring_t *ring)
{
	isc_result_t result;
	dns_rbtnodechain_t chain;
	dns_name_t foundname;
	dns_fixedname_t fixedorigin;
	dns_name_t *origin;
	isc_stdtime_t now;
	dns_rbtnode_t *node;
	dns_tsigkey_t *tkey;

	/*
	 * Start up a new iterator each time.
	 */
	isc_stdtime_get(&now);
	dns_name_init(&foundname, NULL);
	dns_fixedname_init(&fixedorigin);
	origin = dns_fixedname_name(&fixedorigin);

 again:
	dns_rbtnodechain_init(&chain, ring->mctx);
	result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
					origin);
	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
		dns_rbtnodechain_invalidate(&chain);
		return;
	}

	for (;;) {
		node = NULL;
		dns_rbtnodechain_current(&chain, &foundname, origin, &node);
		tkey = node->data;
		if (tkey != NULL) {
			if (tkey->generated
			    && isc_refcount_current(&tkey->refs) == 1
			    && tkey->inception != tkey->expire
			    && tkey->expire < now) {
				tsig_log(tkey, 2, "tsig expire: deleting");
				/* delete the key */
				dns_rbtnodechain_invalidate(&chain);
				remove_fromring(tkey);
				goto again;
			}
		}
		result = dns_rbtnodechain_next(&chain, &foundname,
					       origin);
		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
			dns_rbtnodechain_invalidate(&chain);
			return;
		}
	}
}
示例#4
0
文件: zt.c 项目: crossbuild/bind
isc_result_t
dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
	      isc_result_t (*action)(dns_zone_t *, void *), void *uap)
{
	dns_rbtnode_t *node;
	dns_rbtnodechain_t chain;
	isc_result_t result, tresult = ISC_R_SUCCESS;
	dns_zone_t *zone;

	REQUIRE(VALID_ZT(zt));
	REQUIRE(action != NULL);

	dns_rbtnodechain_init(&chain, zt->mctx);
	result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
	if (result == ISC_R_NOTFOUND) {
		/*
		 * The tree is empty.
		 */
		tresult = result;
		result = ISC_R_NOMORE;
	}
	while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
		result = dns_rbtnodechain_current(&chain, NULL, NULL,
						  &node);
		if (result == ISC_R_SUCCESS) {
			zone = node->data;
			if (zone != NULL)
				result = (action)(zone, uap);
			if (result != ISC_R_SUCCESS && stop) {
				tresult = result;
				goto cleanup;	/* don't break */
			} else if (result != ISC_R_SUCCESS &&
				   tresult == ISC_R_SUCCESS)
				tresult = result;
		}
		result = dns_rbtnodechain_next(&chain, NULL, NULL);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_SUCCESS;

 cleanup:
	dns_rbtnodechain_invalidate(&chain);
	if (sub != NULL)
		*sub = tresult;

	return (result);
}
示例#5
0
isc_result_t
dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
	isc_result_t result;
	dns_keynode_t *knode;
	dns_rbtnode_t *node;
	dns_rbtnodechain_t chain;

	REQUIRE(VALID_KEYTABLE(keytable));
	REQUIRE(text != NULL && *text != NULL);

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
	dns_rbtnodechain_init(&chain, keytable->mctx);
	result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
		if (result == ISC_R_NOTFOUND)
			result = ISC_R_SUCCESS;
		goto cleanup;
	}
	for (;;) {
		char pbuf[DST_KEY_FORMATSIZE];

		dns_rbtnodechain_current(&chain, NULL, NULL, &node);
		for (knode = node->data; knode != NULL; knode = knode->next) {
			char obuf[DNS_NAME_FORMATSIZE + 200];
			if (knode->key == NULL)
				continue;
			dst_key_format(knode->key, pbuf, sizeof(pbuf));
			snprintf(obuf, sizeof(obuf), "%s ; %s\n", pbuf,
				knode->managed ? "managed" : "trusted");
			result = putstr(text, obuf);
			if (result != ISC_R_SUCCESS)
				break;
		}
		result = dns_rbtnodechain_next(&chain, NULL, NULL);
		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
			if (result == ISC_R_NOMORE)
				result = ISC_R_SUCCESS;
			break;
		}
	}

   cleanup:
	dns_rbtnodechain_invalidate(&chain);
	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
	return (result);
}
示例#6
0
isc_result_t
dns_keytable_dump(dns_keytable_t *keytable, FILE *fp)
{
	isc_result_t result;
	dns_keynode_t *knode;
	dns_rbtnode_t *node;
	dns_rbtnodechain_t chain;

	REQUIRE(VALID_KEYTABLE(keytable));

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
	dns_rbtnodechain_init(&chain, keytable->mctx);
	result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
		goto cleanup;
	for (;;) {
		char pbuf[DST_KEY_FORMATSIZE];

		dns_rbtnodechain_current(&chain, NULL, NULL, &node);
		for (knode = node->data; knode != NULL; knode = knode->next) {
			dst_key_format(knode->key, pbuf, sizeof(pbuf));
			fprintf(fp, "%s ; %s\n", pbuf,
				knode->managed ? "managed" : "trusted");
		}
		result = dns_rbtnodechain_next(&chain, NULL, NULL);
		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
			if (result == ISC_R_NOMORE)
				result = ISC_R_SUCCESS;
			break;
		}
	}

   cleanup:
	dns_rbtnodechain_invalidate(&chain);
	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
	return (result);
}
示例#7
0
isc_result_t
dns_keytable_forall(dns_keytable_t *keytable,
		    void (*func)(dns_keytable_t *, dns_keynode_t *, void *),
		    void *arg)
{
	isc_result_t result;
	dns_rbtnode_t *node;
	dns_rbtnodechain_t chain;

	REQUIRE(VALID_KEYTABLE(keytable));

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
	dns_rbtnodechain_init(&chain, keytable->mctx);
	result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
		if (result == ISC_R_NOTFOUND)
			result = ISC_R_SUCCESS;
		goto cleanup;
	}
	for (;;) {
		dns_rbtnodechain_current(&chain, NULL, NULL, &node);
		if (node->data != NULL)
			(*func)(keytable, node->data, arg);
		result = dns_rbtnodechain_next(&chain, NULL, NULL);
		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
			if (result == ISC_R_NOMORE)
				result = ISC_R_SUCCESS;
			break;
		}
	}

   cleanup:
	dns_rbtnodechain_invalidate(&chain);
	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
	return (result);
}
示例#8
0
static int
t_dns_rbtnodechain_init(char *dbfile, char *findname,
			char *nextname, char *nextorigin,
			char *prevname, char *prevorigin,
			char *firstname, char *firstorigin,
			char *lastname, char *lastorigin)
{
	int			result;
	int			len;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnode_t		*node;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_findname;
	dns_fixedname_t		dns_foundname;
	dns_fixedname_t		dns_firstname;
	dns_fixedname_t		dns_lastname;
	dns_fixedname_t		dns_prevname;
	dns_fixedname_t		dns_nextname;
	dns_fixedname_t		dns_origin;
	isc_buffer_t		isc_buffer;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	len = strlen(findname);
	isc_buffer_init(&isc_buffer, findname, len);
	isc_buffer_add(&isc_buffer, len);

	dns_fixedname_init(&dns_foundname);
	dns_fixedname_init(&dns_findname);
	dns_fixedname_init(&dns_firstname);
	dns_fixedname_init(&dns_origin);
	dns_fixedname_init(&dns_lastname);
	dns_fixedname_init(&dns_prevname);
	dns_fixedname_init(&dns_nextname);

	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
					&isc_buffer, NULL, 0, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_name_fromtext failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Set the starting node.
	 */
	node = NULL;
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check next.
	 */
	t_info("checking for next name of %s and new origin of %s\n",
	       nextname, nextorigin);
	dns_result = dns_rbtnodechain_next(&chain,
					   dns_fixedname_name(&dns_nextname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}

	nfails += t_namechk(dns_result, &dns_nextname, nextname, &dns_origin,
			    nextorigin, DNS_R_NEWORIGIN);

	/*
	 * Set the starting node again.
	 */
	node = NULL;
	dns_fixedname_init(&dns_foundname);
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("\tdns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check previous.
	 */
	t_info("checking for previous name of %s and new origin of %s\n",
	       prevname, prevorigin);
	dns_fixedname_init(&dns_origin);
	dns_result = dns_rbtnodechain_prev(&chain,
					   dns_fixedname_name(&dns_prevname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_prevname, prevname, &dns_origin,
			    prevorigin, DNS_R_NEWORIGIN);

	/*
	 * Check first.
	 */
	t_info("checking for first name of %s and new origin of %s\n",
	       firstname, firstorigin);
	dns_result = dns_rbtnodechain_first(&chain, rbt,
					    dns_fixedname_name(&dns_firstname),
					    dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_firstname, firstname,
			    &dns_origin, firstorigin, DNS_R_NEWORIGIN);

	/*
	 * Check last.
	 */
	t_info("checking for last name of %s\n", lastname);
	dns_result = dns_rbtnodechain_last(&chain, rbt,
					   dns_fixedname_name(&dns_lastname),
					   dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_lastname, lastname, &dns_origin,
			    lastorigin, DNS_R_NEWORIGIN);

	/*
	 * Check node ordering.
	 */
	t_info("checking node ordering\n");
	nfails += t9_walkchain(&chain, rbt);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);
	dns_rbt_destroy(&rbt);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);

	return(result);
}
示例#9
0
static int
t9_walkchain(dns_rbtnodechain_t *chain, dns_rbt_t *rbt) {
	int		cnt;
	int		order;
	unsigned int	nlabels;
	int		nprobs;
	isc_result_t	dns_result;

	dns_fixedname_t	name;
	dns_fixedname_t	origin;
	dns_fixedname_t	fullname1;
	dns_fixedname_t	fullname2;

	cnt = 0;
	nprobs = 0;

	do {

		if (cnt == 0) {
			dns_fixedname_init(&name);
			dns_fixedname_init(&origin);
			dns_result = dns_rbtnodechain_first(chain, rbt,
						dns_fixedname_name(&name),
						dns_fixedname_name(&origin));
			if (dns_result != DNS_R_NEWORIGIN) {
				t_info("dns_rbtnodechain_first returned %s, "
				       "expecting DNS_R_NEWORIGIN\n",
				       dns_result_totext(dns_result));
				++nprobs;
				break;
			}
			t_info("first name:\t<%s>\n", fixedname_totext(&name));
			t_info("first origin:\t<%s>\n",
			       fixedname_totext(&origin));
		} else {
			dns_fixedname_init(&fullname1);
			dns_result = dns_name_concatenate(
			       dns_fixedname_name(&name),
			       dns_name_isabsolute(dns_fixedname_name(&name)) ?
					    NULL : dns_fixedname_name(&origin),
			       dns_fixedname_name(&fullname1), NULL);
			if (dns_result != ISC_R_SUCCESS) {
				t_info("dns_name_concatenate failed %s\n",
				       dns_result_totext(dns_result));
				++nprobs;
				break;
			}

			/*
			 * Expecting origin not to get touched if next
			 * doesn't return NEWORIGIN.
			 */
			dns_fixedname_init(&name);
			dns_result = dns_rbtnodechain_next(chain,
						  dns_fixedname_name(&name),
						  dns_fixedname_name(&origin));
			if ((dns_result != ISC_R_SUCCESS) &&
			    (dns_result != DNS_R_NEWORIGIN)) {
				if (dns_result != ISC_R_NOMORE) {
					t_info("dns_rbtnodechain_next "
					       "failed %s\n",
					       dns_result_totext(dns_result));
					++nprobs;
				}
				break;
			}

			t_info("next name:\t<%s>\n", fixedname_totext(&name));
			t_info("next origin:\t<%s>\n",
			       fixedname_totext(&origin));

			dns_fixedname_init(&fullname2);
			dns_result = dns_name_concatenate(
			       dns_fixedname_name(&name),
			       dns_name_isabsolute(dns_fixedname_name(&name)) ?
					    NULL : dns_fixedname_name(&origin),
			       dns_fixedname_name(&fullname2), NULL);
			if (dns_result != ISC_R_SUCCESS) {
				t_info("dns_name_concatenate failed %s\n",
				       dns_result_totext(dns_result));
				++nprobs;
				break;
			}

			t_info("comparing\t<%s>\n",
			       fixedname_totext(&fullname1));
			t_info("\twith\t<%s>\n", fixedname_totext(&fullname2));

			(void)dns_name_fullcompare(
						dns_fixedname_name(&fullname1),
						dns_fixedname_name(&fullname2),
						&order, &nlabels);

			if (order >= 0) {
			    t_info("unexpected order %s %s %s\n",
			       dnsname_totext(dns_fixedname_name(&fullname1)),
			       order == -1 ? "<" : (order == 0 ? "==" : ">"),
			       dnsname_totext(dns_fixedname_name(&fullname2)));
				++nprobs;
			}
		}

		++cnt;
	} while (1);

	return (nprobs);
}
示例#10
0
static int
t_dns_rbtnodechain_first(char *dbfile, char *expected_firstname,
				char *expected_firstorigin,
				char *expected_nextname,
				char *expected_nextorigin)
{
	int			result;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_name;
	dns_fixedname_t		dns_origin;
	isc_result_t		expected_result;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	dns_fixedname_init(&dns_name);
	dns_fixedname_init(&dns_origin);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	t_info("testing for first name of %s, origin of %s\n",
	       expected_firstname, expected_firstorigin);

	dns_result = dns_rbtnodechain_first(&chain, rbt,
					    dns_fixedname_name(&dns_name),
					    dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN)
		t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
		       dns_result_totext(dns_result));

	nfails += t_namechk(dns_result, &dns_name, expected_firstname,
			    &dns_origin, expected_firstorigin, DNS_R_NEWORIGIN);

	dns_fixedname_init(&dns_name);
	dns_result = dns_rbtnodechain_next(&chain,
			dns_fixedname_name(&dns_name),
			dns_fixedname_name(&dns_origin));

	t_info("testing for next name of %s, origin of %s\n",
			expected_nextname, expected_nextorigin);

	if ((dns_result != ISC_R_SUCCESS) && (dns_result != DNS_R_NEWORIGIN))
		t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
		       dns_result_totext(dns_result));

	if (strcasecmp(expected_firstorigin, expected_nextorigin) == 0)
		expected_result = ISC_R_SUCCESS;
	else
		expected_result = DNS_R_NEWORIGIN;
	nfails += t_namechk(dns_result, &dns_name, expected_nextname,
			    &dns_origin, expected_nextorigin, expected_result);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);

	dns_rbt_destroy(&rbt);
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);
	return(result);
}