Example #1
0
static isc_result_t
build_event(dns_lookup_t *lookup) {
	dns_name_t *name = NULL;
	dns_rdataset_t *rdataset = NULL;
	dns_rdataset_t *sigrdataset = NULL;
	isc_result_t result;

	name = isc_mem_get(lookup->mctx, sizeof(dns_name_t));
	if (name == NULL) {
		result = ISC_R_NOMEMORY;
		goto fail;
	}
	dns_name_init(name, NULL);
	result = dns_name_dup(dns_fixedname_name(&lookup->name),
			      lookup->mctx, name);
	if (result != ISC_R_SUCCESS)
		goto fail;

	if (dns_rdataset_isassociated(&lookup->rdataset)) {
		rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
		if (rdataset == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		dns_rdataset_init(rdataset);
		dns_rdataset_clone(&lookup->rdataset, rdataset);
	}

	if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
		sigrdataset = isc_mem_get(lookup->mctx,
					  sizeof(dns_rdataset_t));
		if (sigrdataset == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		dns_rdataset_init(sigrdataset);
		dns_rdataset_clone(&lookup->sigrdataset, sigrdataset);
	}

	lookup->event->name = name;
	lookup->event->rdataset = rdataset;
	lookup->event->sigrdataset = sigrdataset;

	return (ISC_R_SUCCESS);

 fail:
	if (name != NULL) {
		if (dns_name_dynamic(name))
			dns_name_free(name, lookup->mctx);
		isc_mem_put(lookup->mctx, name, sizeof(dns_name_t));
	}
	if (rdataset != NULL) {
		if (dns_rdataset_isassociated(rdataset))
			dns_rdataset_disassociate(rdataset);
		isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t));
	}
	return (result);
}
Example #2
0
static isc_result_t
sendquery(isc_task_t *task) {
	dns_request_t *request;
	dns_message_t *message;
	dns_name_t *qname;
	dns_rdataset_t *qrdataset;
	isc_result_t result;
	dns_fixedname_t queryname;
	isc_buffer_t buf;
	static char host[256];
	int c;

	c = scanf("%255s", host);
	if (c == EOF)
		return ISC_R_NOMORE;

	onfly++;

	dns_fixedname_init(&queryname);
	isc_buffer_init(&buf, host, strlen(host));
	isc_buffer_add(&buf, strlen(host));
	result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
				   dns_rootname, 0, NULL);
	CHECK("dns_name_fromtext", result);

	message = NULL;
	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
	CHECK("dns_message_create", result);

	message->opcode = dns_opcode_query;
	message->flags |= DNS_MESSAGEFLAG_RD;
	message->rdclass = dns_rdataclass_in;
	message->id = (unsigned short)(random() & 0xFFFF);

	qname = NULL;
	result = dns_message_gettempname(message, &qname);
	CHECK("dns_message_gettempname", result);

	qrdataset = NULL;
	result = dns_message_gettemprdataset(message, &qrdataset);
	CHECK("dns_message_gettemprdataset", result);

	dns_name_init(qname, NULL);
	dns_name_clone(dns_fixedname_name(&queryname), qname);
	dns_rdataset_init(qrdataset);
	dns_rdataset_makequestion(qrdataset, dns_rdataclass_in,
				  dns_rdatatype_a);
	ISC_LIST_APPEND(qname->list, qrdataset, link);
	dns_message_addname(message, qname, DNS_SECTION_QUESTION);

	request = NULL;
	result = dns_request_createvia(requestmgr, message,
				       have_src ? &srcaddr : NULL, &dstaddr,
				       DNS_REQUESTOPT_TCP|DNS_REQUESTOPT_SHARE,
				       NULL, TIMEOUT, task, recvresponse,
				       message, &request);
	CHECK("dns_request_create", result);

	return ISC_R_SUCCESS;
}
Example #3
0
static void
deleterdataset(isc_assertioncallback_t callback) {
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_fixedname_t fixed;
	dns_dbnode_t *node = NULL;

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	setup_db();

	dns_rdataset_init(&rdataset);
	dns_fixedname_init(&fixed);

	result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	isc_assertion_setcallback(callback);
	result = dns_db_deleterdataset(db1, node, VERSION(callback),
				       dns_rdatatype_soa, 0);
	if (callback != NULL)
		atf_tc_fail("dns_db_deleterdataset did not assert");
	ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED);

	dns_db_detachnode(db1, &node);
	ATF_REQUIRE_EQ(node, NULL);

	close_db();

	dns_test_end();
}
Example #4
0
static isc_result_t
add_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,
		isc_uint32_t ttl, dns_namelist_t *namelist)
{
	isc_result_t result;
	isc_region_t r, newr;
	dns_rdata_t *newrdata = NULL;
	dns_name_t *newname = NULL;
	dns_rdatalist_t *newlist = NULL;
	dns_rdataset_t *newset = NULL;
	isc_buffer_t *tmprdatabuf = NULL;

	RETERR(dns_message_gettemprdata(msg, &newrdata));

	dns_rdata_toregion(rdata, &r);
	RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length));
	isc_buffer_availableregion(tmprdatabuf, &newr);
	memcpy(newr.base, r.base, r.length);
	dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);
	dns_message_takebuffer(msg, &tmprdatabuf);

	RETERR(dns_message_gettempname(msg, &newname));
	dns_name_init(newname, NULL);
	RETERR(dns_name_dup(name, msg->mctx, newname));

	RETERR(dns_message_gettemprdatalist(msg, &newlist));
	newlist->rdclass = newrdata->rdclass;
	newlist->type = newrdata->type;
	newlist->covers = 0;
	newlist->ttl = ttl;
	ISC_LIST_INIT(newlist->rdata);
	ISC_LIST_APPEND(newlist->rdata, newrdata, link);

	RETERR(dns_message_gettemprdataset(msg, &newset));
	dns_rdataset_init(newset);
	RETERR(dns_rdatalist_tordataset(newlist, newset));

	ISC_LIST_INIT(newname->list);
	ISC_LIST_APPEND(newname->list, newset, link);

	ISC_LIST_APPEND(*namelist, newname, link);

	return (ISC_R_SUCCESS);

 failure:
	if (newrdata != NULL) {
		if (ISC_LINK_LINKED(newrdata, link))
			ISC_LIST_UNLINK(newlist->rdata, newrdata, link);
		dns_message_puttemprdata(msg, &newrdata);
	}
	if (newname != NULL)
		dns_message_puttempname(msg, &newname);
	if (newset != NULL) {
		dns_rdataset_disassociate(newset);
		dns_message_puttemprdataset(msg, &newset);
	}
	if (newlist != NULL)
		dns_message_puttemprdatalist(msg, &newlist);
	return (result);
}
Example #5
0
File: db.c Project: pecharmin/bind9
/*
 * Auxiliary functions add_*() create minimal database which can be loaded.
 * This is necessary because this driver create empty 'fake' zone which
 * is not loaded from disk so there is no way for user to supply SOA, NS and A
 * records.
 *
 * Following functions were copied from BIND 9.10.2rc1 named/server.c,
 * credit goes to ISC.
 */
static isc_result_t
add_soa(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
	const dns_name_t *origin, const dns_name_t *contact)
{
	dns_dbnode_t *node = NULL;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdatalist_t rdatalist;
	dns_rdataset_t rdataset;
	isc_result_t result;
	unsigned char buf[DNS_SOA_BUFFERSIZE];

	dns_rdataset_init(&rdataset);
	dns_rdatalist_init(&rdatalist);
	CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db),
				 0, 28800, 7200, 604800, 86400, buf, &rdata));
	rdatalist.type = rdata.type;
	rdatalist.covers = 0;
	rdatalist.rdclass = rdata.rdclass;
	rdatalist.ttl = 86400;
	ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
	CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
	CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
	CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
 cleanup:
	if (node != NULL)
		dns_db_detachnode(db, &node);
	return (result);
}
Example #6
0
isc_result_t
dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
	       dns_name_t *target, dns_ttl_t ttl)
{
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	unsigned char data[DNS_NSEC_BUFFERSIZE];
	dns_rdatalist_t rdatalist;
	dns_rdataset_t rdataset;

	dns_rdataset_init(&rdataset);
	dns_rdata_init(&rdata);

	RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata));

	rdatalist.rdclass = dns_db_class(db);
	rdatalist.type = dns_rdatatype_nsec;
	rdatalist.covers = 0;
	rdatalist.ttl = ttl;
	ISC_LIST_INIT(rdatalist.rdata);
	ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
	RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset));
	result = dns_db_addrdataset(db, node, version, 0, &rdataset,
				    0, NULL);
	if (result == DNS_R_UNCHANGED)
		result = ISC_R_SUCCESS;
	RETERR(result);
 failure:
	if (dns_rdataset_isassociated(&rdataset))
		dns_rdataset_disassociate(&rdataset);
	return (result);
}
Example #7
0
static isc_result_t
check_node(dns_rdataset_t *rootns, dns_name_t *name,
	   dns_rdatasetiter_t *rdsiter) {
	isc_result_t result;
	dns_rdataset_t rdataset;

	dns_rdataset_init(&rdataset);
	result = dns_rdatasetiter_first(rdsiter);
	while (result == ISC_R_SUCCESS) {
		dns_rdatasetiter_current(rdsiter, &rdataset);
		switch (rdataset.type) {
		case dns_rdatatype_a:
		case dns_rdatatype_aaaa:
			result = in_rootns(rootns, name);
			if (result != ISC_R_SUCCESS)
				goto cleanup;
			break;
		case dns_rdatatype_ns:
			if (dns_name_compare(name, dns_rootname) == 0)
				break;
			/*FALLTHROUGH*/
		default:
			result = ISC_R_FAILURE;
			goto cleanup;
		}
		dns_rdataset_disassociate(&rdataset);
		result = dns_rdatasetiter_next(rdsiter);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_SUCCESS;
 cleanup:
	if (dns_rdataset_isassociated(&rdataset))
		dns_rdataset_disassociate(&rdataset);
	return (result);
}
Example #8
0
static void
find(isc_assertioncallback_t callback) {
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_fixedname_t fixed;

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	setup_db();

	dns_rdataset_init(&rdataset);
	dns_fixedname_init(&fixed);

	isc_assertion_setcallback(callback);
	result = dns_db_find(db1, dns_rootname, VERSION(callback),
			     dns_rdatatype_soa, 0, 0, NULL,
			     dns_fixedname_name(&fixed), &rdataset, NULL);
	if (callback != NULL)
		atf_tc_fail("dns_db_find did not assert");
	ATF_REQUIRE_EQ(result, DNS_R_NXDOMAIN);

	close_db();

	dns_test_end();
}
Example #9
0
/*
 * Common routine to make query data
 */
static isc_result_t
make_querymessage(dns_message_t *message, dns_name_t *qname0,
		  dns_rdatatype_t rdtype)
{
	dns_name_t *qname = NULL;
	dns_rdataset_t *qrdataset = NULL;
	isc_result_t result;

	message->opcode = dns_opcode_query;
	message->rdclass = dns_rdataclass_in;

	result = dns_message_gettempname(message, &qname);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	result = dns_message_gettemprdataset(message, &qrdataset);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	dns_name_init(qname, NULL);
	dns_name_clone(qname0, qname);
	dns_rdataset_init(qrdataset);
	dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
	ISC_LIST_APPEND(qname->list, qrdataset, link);
	dns_message_addname(message, qname, DNS_SECTION_QUESTION);

	return (ISC_R_SUCCESS);

 cleanup:
	if (qname != NULL)
		dns_message_puttempname(message, &qname);
	if (qrdataset != NULL)
		dns_message_puttemprdataset(message, &qrdataset);
	return (result);
}
Example #10
0
File: db.c Project: pecharmin/bind9
static isc_result_t
add_a(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
      struct in_addr addr)
{
	dns_dbnode_t *node = NULL;
	dns_rdata_in_a_t a;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdatalist_t rdatalist;
	dns_rdataset_t rdataset;
	isc_result_t result;
	isc_buffer_t b;
	unsigned char buf[DNS_NAME_MAXWIRE];

	isc_buffer_init(&b, buf, sizeof(buf));

	dns_rdataset_init(&rdataset);
	dns_rdatalist_init(&rdatalist);
	a.common.rdtype = dns_rdatatype_a;
	a.common.rdclass = dns_db_class(db);
	a.in_addr = addr;
	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_a,
				   &a, &b));
	rdatalist.type = rdata.type;
	rdatalist.covers = 0;
	rdatalist.rdclass = rdata.rdclass;
	rdatalist.ttl = 86400;
	ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
	CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
	CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
	CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
 cleanup:
	if (node != NULL)
		dns_db_detachnode(db, &node);
	return (result);
}
Example #11
0
static isc_result_t
loadkeyset(char *dirname, dns_rdataset_t *rdataset) {
	isc_result_t	 result;
	char		 filename[PATH_MAX + 1];
	isc_buffer_t	 buf;

	dns_rdataset_init(rdataset);

	isc_buffer_init(&buf, filename, sizeof(filename));
	if (dirname != NULL) {
		/* allow room for a trailing slash */
		if (strlen(dirname) >= isc_buffer_availablelength(&buf))
			return (ISC_R_NOSPACE);
		isc_buffer_putstr(&buf, dirname);
		if (dirname[strlen(dirname) - 1] != '/')
			isc_buffer_putstr(&buf, "/");
	}

	if (isc_buffer_availablelength(&buf) < 7)
		return (ISC_R_NOSPACE);
	isc_buffer_putstr(&buf, "keyset-");

	result = dns_name_tofilenametext(name, ISC_FALSE, &buf);
	check_result(result, "dns_name_tofilenametext()");
	if (isc_buffer_availablelength(&buf) == 0)
		return (ISC_R_NOSPACE);
	isc_buffer_putuint8(&buf, 0);

	return (loadsetfromfile(filename, rdataset));
}
Example #12
0
static isc_result_t
make_querymessage(dns_message_t *message, const char *namestr,
		  dns_rdatatype_t rdtype)
{
	dns_name_t *qname = NULL, *qname0;
	dns_rdataset_t *qrdataset = NULL;
	isc_result_t result;
	isc_buffer_t b;
	unsigned int namelen;

	REQUIRE(message != NULL);
	REQUIRE(namestr != NULL);

	/* Construct qname */
	namelen = strlen(namestr);
	isc_buffer_constinit(&b, namestr, namelen);
	isc_buffer_add(&b, namelen);
	dns_fixedname_init(&fixedqname);
	qname0 = dns_fixedname_name(&fixedqname);
	result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to convert qname: %d\n", result);
		return (result);
	}

	/* Construct query message */
	message->opcode = dns_opcode_query;
	message->rdclass = dns_rdataclass_in;

	result = dns_message_gettempname(message, &qname);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	result = dns_message_gettemprdataset(message, &qrdataset);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	dns_name_init(qname, NULL);
	dns_name_clone(qname0, qname);
	dns_rdataset_init(qrdataset);
	dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
	ISC_LIST_APPEND(qname->list, qrdataset, link);
	dns_message_addname(message, qname, DNS_SECTION_QUESTION);

	return (ISC_R_SUCCESS);

 cleanup:
	if (qname != NULL)
		dns_message_puttempname(message, &qname);
	if (qrdataset != NULL)
		dns_message_puttemprdataset(message, &qrdataset);
	dns_message_destroy(&message);
	return (result);
}
Example #13
0
static isc_result_t
check_hints(dns_db_t *db) {
	isc_result_t result;
	dns_rdataset_t rootns;
	dns_dbiterator_t *dbiter = NULL;
	dns_dbnode_t *node = NULL;
	isc_stdtime_t now;
	dns_fixedname_t fixname;
	dns_name_t *name;
	dns_rdatasetiter_t *rdsiter = NULL;

	isc_stdtime_get(&now);

	dns_fixedname_init(&fixname);
	name = dns_fixedname_name(&fixname);

	dns_rdataset_init(&rootns);
	(void)dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
			  now, NULL, name, &rootns, NULL);
	result = dns_db_createiterator(db, 0, &dbiter);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = dns_dbiterator_first(dbiter);
	while (result == ISC_R_SUCCESS) {
		result = dns_dbiterator_current(dbiter, &node, name);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		result = dns_db_allrdatasets(db, node, NULL, now, &rdsiter);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		result = check_node(&rootns, name, rdsiter);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		dns_rdatasetiter_destroy(&rdsiter);
		dns_db_detachnode(db, &node);
		result = dns_dbiterator_next(dbiter);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_SUCCESS;

 cleanup:
	if (dns_rdataset_isassociated(&rootns))
		dns_rdataset_disassociate(&rootns);
	if (rdsiter != NULL)
		dns_rdatasetiter_destroy(&rdsiter);
	if (node != NULL)
		dns_db_detachnode(db, &node);
	if (dbiter != NULL)
		dns_dbiterator_destroy(&dbiter);
	return (result);
}
Example #14
0
isc_result_t
dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
		  isc_boolean_t *answer)
{
	dns_dbnode_t *node = NULL;
	dns_rdataset_t rdataset;
	dns_rdata_dnskey_t dnskey;
	isc_result_t result;

	REQUIRE(answer != NULL);

	dns_rdataset_init(&rdataset);

	result = dns_db_getoriginnode(db, &node);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
				     0, 0, &rdataset, NULL);
	dns_db_detachnode(db, &node);

	if (result == ISC_R_NOTFOUND) {
		*answer = ISC_FALSE;
		return (ISC_R_SUCCESS);
	}
	if (result != ISC_R_SUCCESS)
		return (result);
	for (result = dns_rdataset_first(&rdataset);
	     result == ISC_R_SUCCESS;
	     result = dns_rdataset_next(&rdataset)) {
		dns_rdata_t rdata = DNS_RDATA_INIT;

		dns_rdataset_current(&rdataset, &rdata);
		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
		RUNTIME_CHECK(result == ISC_R_SUCCESS);

		if (dnskey.algorithm == DST_ALG_RSAMD5 ||
		    dnskey.algorithm == DST_ALG_RSASHA1 ||
		    dnskey.algorithm == DST_ALG_DSA ||
		    dnskey.algorithm == DST_ALG_ECC)
			break;
	}
	dns_rdataset_disassociate(&rdataset);
	if (result == ISC_R_SUCCESS)
		*answer = ISC_TRUE;
	if (result == ISC_R_NOMORE) {
		*answer = ISC_FALSE;
		result = ISC_R_SUCCESS;
	}
	return (result);
}
Example #15
0
static void
log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) {
	isc_result_t result;
	isc_buffer_t buf;
	char mem[2000];
	dns_rdatalist_t rdl;
	dns_rdataset_t rds;
	dns_rdata_t rd = DNS_RDATA_INIT;

	rdl.type = rdata->type;
	rdl.rdclass = rdata->rdclass;
	rdl.ttl = ttl;
	if (rdata->type == dns_rdatatype_sig ||
	    rdata->type == dns_rdatatype_rrsig)
		rdl.covers = dns_rdata_covers(rdata);
	else
		rdl.covers = dns_rdatatype_none;
	ISC_LIST_INIT(rdl.rdata);
	ISC_LINK_INIT(&rdl, link);
	dns_rdataset_init(&rds);
	dns_rdata_init(&rd);
	dns_rdata_clone(rdata, &rd);
	ISC_LIST_APPEND(rdl.rdata, &rd, link);
	RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);

	isc_buffer_init(&buf, mem, sizeof(mem));
	result = dns_rdataset_totext(&rds, name,
				     ISC_FALSE, ISC_FALSE, &buf);

	/*
	 * We could use xfrout_log(), but that would produce
	 * very long lines with a repetitive prefix.
	 */
	if (result == ISC_R_SUCCESS) {
		/*
		 * Get rid of final newline.
		 */
		INSIST(buf.used >= 1 &&
		       ((char *) buf.base)[buf.used - 1] == '\n');
		buf.used--;

		isc_log_write(XFROUT_RR_LOGARGS, "%.*s",
			      (int)isc_buffer_usedlength(&buf),
			      (char *)isc_buffer_base(&buf));
	} else {
		isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>");
	}
}
Example #16
0
static void
print_rdatasets(dns_name_t *name, dns_rdatasetiter_t *rdsiter) {
	isc_result_t result;
	dns_rdataset_t rdataset;

	dns_rdataset_init(&rdataset);
	result = dns_rdatasetiter_first(rdsiter);
	while (result == ISC_R_SUCCESS) {
		dns_rdatasetiter_current(rdsiter, &rdataset);
		print_rdataset(name, &rdataset);
		dns_rdataset_disassociate(&rdataset);
		result = dns_rdatasetiter_next(rdsiter);
	}
	if (result != ISC_R_NOMORE)
		print_result("", result);
}
Example #17
0
static isc_result_t
diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata,
		      dns_rdatalist_t *rdl, dns_rdataset_t *rds)
{
	REQUIRE(DNS_DIFFTUPLE_VALID(t));
	REQUIRE(rdl != NULL);
	REQUIRE(rds != NULL);

	dns_rdatalist_init(rdl);
	rdl->type = t->rdata.type;
	rdl->rdclass = t->rdata.rdclass;
	rdl->ttl = t->ttl;
	dns_rdataset_init(rds);
	ISC_LINK_INIT(rdata, link);
	dns_rdata_clone(&t->rdata, rdata);
	ISC_LIST_APPEND(rdl->rdata, rdata, link);
	return (dns_rdatalist_tordataset(rdl, rds));
}
Example #18
0
isc_result_t
dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
{
	isc_result_t result;
	dns_dbnode_t *node = NULL;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_buffer_t buffer;

	REQUIRE(dns_db_iszone(db) || dns_db_isstub(db));

	result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t)0, &rdataset, NULL);
	if (result != ISC_R_SUCCESS)
		goto freenode;

	result = dns_rdataset_first(&rdataset);
	if (result != ISC_R_SUCCESS)
		goto freerdataset;
	dns_rdataset_current(&rdataset, &rdata);
	result = dns_rdataset_next(&rdataset);
	INSIST(result == ISC_R_NOMORE);

	INSIST(rdata.length > 20);
	isc_buffer_init(&buffer, rdata.data, rdata.length);
	isc_buffer_add(&buffer, rdata.length);
	isc_buffer_forward(&buffer, rdata.length - 20);
	*serialp = isc_buffer_getuint32(&buffer);

	result = ISC_R_SUCCESS;

 freerdataset:
	dns_rdataset_disassociate(&rdataset);

 freenode:
	dns_db_detachnode(db, &node);
	return (result);
}
Example #19
0
static inline isc_boolean_t active_node (dns_db_t * db, dns_dbversion_t * version, dns_dbnode_t * node)
{
    dns_rdatasetiter_t *rdsiter;

    isc_boolean_t active = ISC_FALSE;

    isc_result_t result;

    dns_rdataset_t rdataset;

    dns_rdataset_init (&rdataset);
    rdsiter = NULL;
    result = dns_db_allrdatasets (db, node, version, 0, &rdsiter);
    check_result (result, "dns_db_allrdatasets()");
    result = dns_rdatasetiter_first (rdsiter);
    while (result == ISC_R_SUCCESS)
    {
        dns_rdatasetiter_current (rdsiter, &rdataset);
        if (rdataset.type != dns_rdatatype_nsec)
            active = ISC_TRUE;
        dns_rdataset_disassociate (&rdataset);
        if (!active)
            result = dns_rdatasetiter_next (rdsiter);
        else
            result = ISC_R_NOMORE;
    }
    if (result != ISC_R_NOMORE)
        fatal ("rdataset iteration failed");
    dns_rdatasetiter_destroy (&rdsiter);

    if (!active)
    {
        /*
         * Make sure there is no NSEC record for this node.
         */
        result = dns_db_deleterdataset (db, node, version, dns_rdatatype_nsec, 0);
        if (result == DNS_R_UNCHANGED)
            result = ISC_R_SUCCESS;
        check_result (result, "dns_db_deleterdataset");
    }

    return (active);
}
Example #20
0
static isc_result_t
db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
		    isc_stdtime_t now)
{
	isc_result_t result;
	it->db = db;
	it->dbit = NULL;
	it->ver = ver;
	it->now = now;
	it->node = NULL;
	result = dns_db_createiterator(it->db, 0, &it->dbit);
	if (result != ISC_R_SUCCESS)
		return (result);
	it->rdatasetit = NULL;
	dns_rdata_init(&it->rdata);
	dns_rdataset_init(&it->rdataset);
	dns_fixedname_init(&it->fixedname);
	INSIST(! dns_rdataset_isassociated(&it->rdataset));
	it->result = ISC_R_SUCCESS;
	return (it->result);
}
Example #21
0
ATF_TC_BODY(totext, tc) {
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_rdatalist_t rdatalist;
	isc_buffer_t target;
	unsigned char buf[BIGBUFLEN];

	UNUSED(tc);

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* First, test with an empty rdataset */
	rdatalist.rdclass = dns_rdataclass_in;
	rdatalist.type = dns_rdatatype_none;
	rdatalist.covers = dns_rdatatype_none;
	rdatalist.ttl = 0;
	ISC_LIST_INIT(rdatalist.rdata);
	ISC_LINK_INIT(&rdatalist, link);

	dns_rdataset_init(&rdataset);
	result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	isc_buffer_init(&target, buf, BIGBUFLEN);
	result = dns_master_rdatasettotext(dns_rootname,
					   &rdataset, &dns_master_style_debug,
					   &target);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);
	ATF_CHECK_EQ(isc_buffer_usedlength(&target), 0);

	/*
	 * XXX: We will also need to add tests for dumping various
	 * rdata types, classes, etc, and comparing the results against
	 * known-good output.
	 */

	dns_test_end();
}
Example #22
0
static void
addrdataset(isc_assertioncallback_t callback) {
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_fixedname_t fixed;
	dns_dbnode_t *node = NULL;
	dns_rdatalist_t rdatalist;

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	setup_db();

	dns_rdataset_init(&rdataset);
	dns_rdatalist_init(&rdatalist);
	dns_fixedname_init(&fixed);

	rdatalist.rdclass = dns_rdataclass_in;

	result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	isc_assertion_setcallback(callback);
	result = dns_db_addrdataset(db1, node, VERSION(callback), 0, &rdataset,
				    0, NULL);
	if (callback != NULL)
		atf_tc_fail("dns_db_adddataset did not assert");
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	dns_db_detachnode(db1, &node);
	ATF_REQUIRE_EQ(node, NULL);

	close_db();

	dns_test_end();
}
Example #23
0
int
main (int *argc, char **argv)
{
  isc_mem_t *mctx = NULL;
  isc_entropy_t *ectx = NULL;
  isc_result_t result;
  char *basedn;
  ldap_info *tmp;
  LDAPMod *base_attrs[2];
  LDAPMod base;
  isc_buffer_t buff;
  char *zonefile;
  char fullbasedn[1024];
  char *ctmp;
  dns_fixedname_t fixedzone, fixedname;
  dns_rdataset_t rdataset;
  char **dc_list;
  dns_rdata_t rdata = DNS_RDATA_INIT;
  dns_rdatasetiter_t *riter;
  dns_name_t *zone, *name;
  dns_db_t *db = NULL;
  dns_dbiterator_t *dbit = NULL;
  dns_dbnode_t *node;
  extern char *optarg;
  extern int optind, opterr, optopt;
  int create_base = 0;
  int topt;

  if ((int) argc < 2)
    {
      usage ();
      exit (-1);
    }

  while ((topt = getopt ((int) argc, argv, "D:w:b:z:f:h:?dcv")) != -1)
    {
      switch (topt)
	{
	case 'v':
		printf("%s\n", VERSION);
		exit(0);
	case 'c':
	  create_base++;
	  break;
	case 'd':
	  debug++;
	  break;
	case 'D':
	  binddn = strdup (optarg);
	  break;
	case 'w':
	  bindpw = strdup (optarg);
	  break;
	case 'b':
	  ldapbase = strdup (optarg);
	  break;
	case 'z':
	  argzone = strdup (optarg);
	  // We wipe argzone all to hell when we parse it for the DN */
	  gbl_zone = strdup(argzone);
	  break;
	case 'f':
	  zonefile = strdup (optarg);
	  break;
	case 'h':
	  ldapsystem = strdup (optarg);
	  break;
	case '?':
	default:
	  usage ();
	  exit (0);
	}
    }

  if ((argzone == NULL) || (zonefile == NULL))
    {
      usage ();
      exit (-1);
    }

  if (debug)
    printf ("Initializing ISC Routines, parsing zone file\n");

  result = isc_mem_create (0, 0, &mctx);
  isc_result_check (result, "isc_mem_create");

  result = isc_entropy_create(mctx, &ectx);
  isc_result_check (result, "isc_entropy_create");

  result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
  isc_result_check (result, "isc_hash_create");

  isc_buffer_init (&buff, argzone, strlen (argzone));
  isc_buffer_add (&buff, strlen (argzone));
  dns_fixedname_init (&fixedzone);
  zone = dns_fixedname_name (&fixedzone);
  result = dns_name_fromtext (zone, &buff, dns_rootname, 0, NULL);
  isc_result_check (result, "dns_name_fromtext");

  result = dns_db_create (mctx, "rbt", zone, dns_dbtype_zone,
			  dns_rdataclass_in, 0, NULL, &db);
  isc_result_check (result, "dns_db_create");

  result = dns_db_load (db, zonefile);
  isc_result_check (result, "Check Zone Syntax: dns_db_load");

  result = dns_db_createiterator (db, 0, &dbit);
  isc_result_check (result, "dns_db_createiterator");

  result = dns_dbiterator_first (dbit);
  isc_result_check (result, "dns_dbiterator_first");

  dns_fixedname_init (&fixedname);
  name = dns_fixedname_name (&fixedname);
  dns_rdataset_init (&rdataset);
  dns_rdata_init (&rdata);

  while (result == ISC_R_SUCCESS)
    {
      node = NULL;
      result = dns_dbiterator_current (dbit, &node, name);

      if (result == ISC_R_NOMORE)
	break;

      isc_result_check (result, "dns_dbiterator_current");

      riter = NULL;
      result = dns_db_allrdatasets (db, node, NULL, 0, &riter);
      isc_result_check (result, "dns_db_allrdatasets");

      result = dns_rdatasetiter_first (riter);
      //isc_result_check(result, "dns_rdatasetiter_first");

      while (result == ISC_R_SUCCESS)
	{
	  dns_rdatasetiter_current (riter, &rdataset);
	  result = dns_rdataset_first (&rdataset);
	  isc_result_check (result, "dns_rdatasetiter_current");

	  while (result == ISC_R_SUCCESS)
	    {
	      dns_rdataset_current (&rdataset, &rdata);
	      generate_ldap (name, &rdata, rdataset.ttl);
	      dns_rdata_reset (&rdata);
	      result = dns_rdataset_next (&rdataset);
	    }
	  dns_rdataset_disassociate (&rdataset);
	  result = dns_rdatasetiter_next (riter);

	}
      dns_rdatasetiter_destroy (&riter);
      result = dns_dbiterator_next (dbit);

    }

  /* Initialize the LDAP Connection */
  if (debug)
    printf ("Initializing LDAP Connection to %s as %s\n", ldapsystem, binddn);

  init_ldap_conn ();

  if (create_base)
    {
      if (debug)
	printf ("Creating base zone DN %s\n", argzone);

      dc_list = hostname_to_dn_list (argzone, argzone, DNS_TOP);
      basedn = build_dn_from_dc_list (dc_list, 0, NO_SPEC);

      for (ctmp = &basedn[strlen (basedn)]; ctmp >= &basedn[0]; ctmp--)
	{
	  if ((*ctmp == ',') || (ctmp == &basedn[0]))
	    {
	      base.mod_op = LDAP_MOD_ADD;
	      base.mod_type = "objectClass";
	      base.mod_values = topObjectClasses;
	      base_attrs[0] = &base;
	      base_attrs[1] = NULL;

	      if (ldapbase)
		{
		  if (ctmp != &basedn[0])
		    sprintf (fullbasedn, "%s,%s", ctmp + 1, ldapbase);
		  else
		    sprintf (fullbasedn, "%s,%s", ctmp, ldapbase);

		}
	      else
		{
		  if (ctmp != &basedn[0])
		    sprintf (fullbasedn, "%s", ctmp + 1);
		  else
		    sprintf (fullbasedn, "%s", ctmp);
		}
	      result = ldap_add_s (conn, fullbasedn, base_attrs);
	      ldap_result_check ("intial ldap_add_s", fullbasedn, result);
	    }

	}
    }
  else
    {
      if (debug)
	printf ("Skipping zone base dn creation for %s\n", argzone);
    }

  for (tmp = ldap_info_base; tmp != NULL; tmp = tmp->next)
    {

      if (debug)
	printf ("Adding DN: %s\n", tmp->dn);

      add_ldap_values (tmp);
    }

  if (debug)
	printf("Operation Complete.\n");

  /* Cleanup */
  isc_hash_destroy();
  isc_entropy_detach(&ectx);
  isc_mem_destroy(&mctx);
  if (zonefile)
	free(zonefile);

  return 0;
}
Example #24
0
isc_result_t
dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
			  dns_rdatatype_t covers, dns_rdataset_t *rdataset)
{
	dns_name_t tname;
	dns_rdata_rrsig_t rrsig;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdataset_t clone;
	dns_rdatatype_t type;
	dns_trust_t trust = dns_trust_none;
	isc_buffer_t source;
	isc_region_t remaining, sigregion;
	isc_result_t result;
	unsigned char *raw;
	unsigned int count;

	REQUIRE(ncacherdataset != NULL);
	REQUIRE(ncacherdataset->type == 0);
	REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
	REQUIRE(name != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));

	dns_rdataset_init(&clone);
	dns_rdataset_clone(ncacherdataset, &clone);
	result = dns_rdataset_first(&clone);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&clone, &rdata);
		isc_buffer_init(&source, rdata.data, rdata.length);
		isc_buffer_add(&source, rdata.length);
		dns_name_init(&tname, NULL);
		isc_buffer_remainingregion(&source, &remaining);
		dns_name_fromregion(&tname, &remaining);
		INSIST(remaining.length >= tname.length);
		isc_buffer_forward(&source, tname.length);
		isc_region_consume(&remaining, tname.length);

		INSIST(remaining.length >= 2);
		type = isc_buffer_getuint16(&source);
		isc_region_consume(&remaining, 2);

		if (type != dns_rdatatype_rrsig ||
		    !dns_name_equal(&tname, name)) {
			result = dns_rdataset_next(&clone);
			dns_rdata_reset(&rdata);
			continue;
		}

		INSIST(remaining.length >= 1);
		trust = isc_buffer_getuint8(&source);
		INSIST(trust <= dns_trust_ultimate);
		isc_region_consume(&remaining, 1);

		raw = remaining.base;
		count = raw[0] * 256 + raw[1];
		INSIST(count > 0);
		raw += 2;
		sigregion.length = raw[0] * 256 + raw[1];
		raw += 2;
		sigregion.base = raw;
		dns_rdata_reset(&rdata);
		dns_rdata_fromregion(&rdata, rdataset->rdclass,
				     dns_rdatatype_rrsig, &sigregion);
		(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
		if (rrsig.covered == covers) {
			isc_buffer_remainingregion(&source, &remaining);
			break;
		}

		result = dns_rdataset_next(&clone);
		dns_rdata_reset(&rdata);
	}
	dns_rdataset_disassociate(&clone);
	if (result == ISC_R_NOMORE)
		return (ISC_R_NOTFOUND);
	if (result != ISC_R_SUCCESS)
		return (result);

	INSIST(remaining.length != 0);

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ncacherdataset->rdclass;
	rdataset->type = dns_rdatatype_rrsig;
	rdataset->covers = covers;
	rdataset->ttl = ncacherdataset->ttl;
	rdataset->trust = trust;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	rdataset->private6 = NULL;
	return (ISC_R_SUCCESS);
}
Example #25
0
isc_result_t
dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
		       dns_rdatatype_t type, dns_rdataset_t *rdataset)
{
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_region_t remaining;
	isc_buffer_t source;
	dns_name_t tname;
	dns_rdatatype_t ttype;
	dns_trust_t trust = dns_trust_none;
	dns_rdataset_t clone;

	REQUIRE(ncacherdataset != NULL);
	REQUIRE(ncacherdataset->type == 0);
	REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
	REQUIRE(name != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));
	REQUIRE(type != dns_rdatatype_rrsig);

	dns_rdataset_init(&clone);
	dns_rdataset_clone(ncacherdataset, &clone);
	result = dns_rdataset_first(&clone);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&clone, &rdata);
		isc_buffer_init(&source, rdata.data, rdata.length);
		isc_buffer_add(&source, rdata.length);
		dns_name_init(&tname, NULL);
		isc_buffer_remainingregion(&source, &remaining);
		dns_name_fromregion(&tname, &remaining);
		INSIST(remaining.length >= tname.length);
		isc_buffer_forward(&source, tname.length);
		remaining.length -= tname.length;

		INSIST(remaining.length >= 3);
		ttype = isc_buffer_getuint16(&source);

		if (ttype == type && dns_name_equal(&tname, name)) {
			trust = isc_buffer_getuint8(&source);
			INSIST(trust <= dns_trust_ultimate);
			isc_buffer_remainingregion(&source, &remaining);
			break;
		}
		result = dns_rdataset_next(&clone);
		dns_rdata_reset(&rdata);
	}
	dns_rdataset_disassociate(&clone);
	if (result == ISC_R_NOMORE)
		return (ISC_R_NOTFOUND);
	if (result != ISC_R_SUCCESS)
		return (result);

	INSIST(remaining.length != 0);

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ncacherdataset->rdclass;
	rdataset->type = type;
	rdataset->covers = 0;
	rdataset->ttl = ncacherdataset->ttl;
	rdataset->trust = trust;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	rdataset->private6 = NULL;
	return (ISC_R_SUCCESS);
}
Example #26
0
static isc_result_t
addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
	  dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
	  isc_boolean_t optout, isc_boolean_t secure,
	  dns_rdataset_t *addedrdataset)
{
	isc_result_t result;
	isc_buffer_t buffer;
	isc_region_t r;
	dns_rdataset_t *rdataset;
	dns_rdatatype_t type;
	dns_name_t *name;
	dns_ttl_t ttl;
	dns_trust_t trust;
	dns_rdata_t rdata[DNS_NCACHE_RDATA];
	dns_rdataset_t ncrdataset;
	dns_rdatalist_t ncrdatalist;
	unsigned char data[4096];
	unsigned int next = 0;

	/*
	 * Convert the authority data from 'message' into a negative cache
	 * rdataset, and store it in 'cache' at 'node'.
	 */

	REQUIRE(message != NULL);

	/*
	 * We assume that all data in the authority section has been
	 * validated by the caller.
	 */

	/*
	 * Initialize the list.
	 */
	dns_rdatalist_init(&ncrdatalist);
	ncrdatalist.rdclass = dns_db_class(cache);
	ncrdatalist.covers = covers;
	ncrdatalist.ttl = maxttl;

	/*
	 * Build an ncache rdatas into buffer.
	 */
	ttl = maxttl;
	trust = 0xffff;
	isc_buffer_init(&buffer, data, sizeof(data));
	if (message->counts[DNS_SECTION_AUTHORITY])
		result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
	else
		result = ISC_R_NOMORE;
	while (result == ISC_R_SUCCESS) {
		name = NULL;
		dns_message_currentname(message, DNS_SECTION_AUTHORITY,
					&name);
		if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
			for (rdataset = ISC_LIST_HEAD(name->list);
			     rdataset != NULL;
			     rdataset = ISC_LIST_NEXT(rdataset, link)) {
				if ((rdataset->attributes &
				     DNS_RDATASETATTR_NCACHE) == 0)
					continue;
				type = rdataset->type;
				if (type == dns_rdatatype_rrsig)
					type = rdataset->covers;
				if (type == dns_rdatatype_soa ||
				    type == dns_rdatatype_nsec ||
				    type == dns_rdatatype_nsec3) {
					if (ttl > rdataset->ttl)
						ttl = rdataset->ttl;
					if (trust > rdataset->trust)
						trust = rdataset->trust;
					/*
					 * Copy the owner name to the buffer.
					 */
					dns_name_toregion(name, &r);
					result = isc_buffer_copyregion(&buffer,
								       &r);
					if (result != ISC_R_SUCCESS)
						return (result);
					/*
					 * Copy the type to the buffer.
					 */
					isc_buffer_availableregion(&buffer,
								   &r);
					if (r.length < 3)
						return (ISC_R_NOSPACE);
					isc_buffer_putuint16(&buffer,
							     rdataset->type);
					isc_buffer_putuint8(&buffer,
					       (unsigned char)rdataset->trust);
					/*
					 * Copy the rdataset into the buffer.
					 */
					result = copy_rdataset(rdataset,
							       &buffer);
					if (result != ISC_R_SUCCESS)
						return (result);

					if (next >= DNS_NCACHE_RDATA)
						return (ISC_R_NOSPACE);
					dns_rdata_init(&rdata[next]);
					isc_buffer_remainingregion(&buffer, &r);
					rdata[next].data = r.base;
					rdata[next].length = r.length;
					rdata[next].rdclass =
						ncrdatalist.rdclass;
					rdata[next].type = 0;
					rdata[next].flags = 0;
					ISC_LIST_APPEND(ncrdatalist.rdata,
							&rdata[next], link);
					isc_buffer_forward(&buffer, r.length);
					next++;
				}
			}
		}
		result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
	}
	if (result != ISC_R_NOMORE)
		return (result);

	if (trust == 0xffff) {
		if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
		    message->counts[DNS_SECTION_ANSWER] == 0) {
			/*
			 * The response has aa set and we haven't followed
			 * any CNAME or DNAME chains.
			 */
			trust = dns_trust_authauthority;
		} else
			trust = dns_trust_additional;
		ttl = 0;
	}

	INSIST(trust != 0xffff);

	ncrdatalist.ttl = ttl;

	dns_rdataset_init(&ncrdataset);
	RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
		      == ISC_R_SUCCESS);
	if (!secure && trust > dns_trust_answer)
		trust = dns_trust_answer;
	ncrdataset.trust = trust;
	ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
	if (message->rcode == dns_rcode_nxdomain)
		ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
	if (optout)
		ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;

	return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
				   0, addedrdataset));
}
Example #27
0
void
dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) {
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdata_ns_t ns;
	dns_rdataset_t hintns, rootns;
	const char *viewname = "", *sep = "";
	isc_stdtime_t now;
	dns_name_t *name;
	dns_fixedname_t fixed;

	REQUIRE(hints != NULL);
	REQUIRE(db != NULL);
	REQUIRE(view != NULL);

	isc_stdtime_get(&now);

	if (strcmp(view->name, "_bind") != 0 &&
	    strcmp(view->name, "_default") != 0) {
		viewname = view->name;
		sep = ": view ";
	}

	dns_rdataset_init(&hintns);
	dns_rdataset_init(&rootns);
	dns_fixedname_init(&fixed);
	name = dns_fixedname_name(&fixed);

	result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0,
			     now, NULL, name, &hintns, NULL);
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
			      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
			      "checkhints%s%s: unable to get root NS rrset "
			      "from hints: %s", sep, viewname,
			      dns_result_totext(result));
		goto cleanup;
	}

	result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
			     now, NULL, name, &rootns, NULL);
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
			      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
			      "checkhints%s%s: unable to get root NS rrset "
			      "from cache: %s", sep, viewname,
			      dns_result_totext(result));
		goto cleanup;
	}

	/*
	 * Look for missing root NS names.
	 */
	result = dns_rdataset_first(&rootns);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&rootns, &rdata);
		result = dns_rdata_tostruct(&rdata, &ns, NULL);
		RUNTIME_CHECK(result == ISC_R_SUCCESS);
		result = in_rootns(&hintns, &ns.name);
		if (result != ISC_R_SUCCESS) {
			char namebuf[DNS_NAME_FORMATSIZE];
			/* missing from hints */
			dns_name_format(&ns.name, namebuf, sizeof(namebuf));
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
				      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
				      "checkhints%s%s: unable to find root "
				      "NS '%s' in hints", sep, viewname,
				      namebuf);
		} else
			check_address_records(view, hints, db, &ns.name, now);
		dns_rdata_reset(&rdata);
		result = dns_rdataset_next(&rootns);
	}
	if (result != ISC_R_NOMORE) {
		goto cleanup;
	}

	/*
	 * Look for extra root NS names.
	 */
	result = dns_rdataset_first(&hintns);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&hintns, &rdata);
		result = dns_rdata_tostruct(&rdata, &ns, NULL);
		RUNTIME_CHECK(result == ISC_R_SUCCESS);
		result = in_rootns(&rootns, &ns.name);
		if (result != ISC_R_SUCCESS) {
			char namebuf[DNS_NAME_FORMATSIZE];
			/* extra entry in hints */
			dns_name_format(&ns.name, namebuf, sizeof(namebuf));
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
				      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
				      "checkhints%s%s: extra NS '%s' in hints",
				      sep, viewname, namebuf);
		}
		dns_rdata_reset(&rdata);
		result = dns_rdataset_next(&hintns);
	}
	if (result != ISC_R_NOMORE) {
		goto cleanup;
	}

 cleanup:
	if (dns_rdataset_isassociated(&rootns))
		dns_rdataset_disassociate(&rootns);
	if (dns_rdataset_isassociated(&hintns))
		dns_rdataset_disassociate(&hintns);
}
Example #28
0
static void
check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
		      dns_name_t *name, isc_stdtime_t now)
{
	isc_result_t hresult, rresult, result;
	dns_rdataset_t hintrrset, rootrrset;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_name_t *foundname;
	dns_fixedname_t fixed;

	dns_rdataset_init(&hintrrset);
	dns_rdataset_init(&rootrrset);
	dns_fixedname_init(&fixed);
	foundname = dns_fixedname_name(&fixed);

	hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0,
			      now, NULL, foundname, &hintrrset, NULL);
	rresult = dns_db_find(db, name, NULL, dns_rdatatype_a,
			      DNS_DBFIND_GLUEOK, now, NULL, foundname,
			      &rootrrset, NULL);
	if (hresult == ISC_R_SUCCESS &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			if (!inrrset(&hintrrset, &rdata))
				report(view, name, ISC_TRUE, &rdata);
			result = dns_rdataset_next(&rootrrset);
		}
		result = dns_rdataset_first(&hintrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&hintrrset, &rdata);
			if (!inrrset(&rootrrset, &rdata))
				report(view, name, ISC_FALSE, &rdata);
			result = dns_rdataset_next(&hintrrset);
		}
	}
	if (hresult == ISC_R_NOTFOUND &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			report(view, name, ISC_TRUE, &rdata);
			result = dns_rdataset_next(&rootrrset);
		}
	}
	if (dns_rdataset_isassociated(&rootrrset))
		dns_rdataset_disassociate(&rootrrset);
	if (dns_rdataset_isassociated(&hintrrset))
		dns_rdataset_disassociate(&hintrrset);

	/*
	 * Check AAAA records.
	 */
	hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0,
			      now, NULL, foundname, &hintrrset, NULL);
	rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
			      DNS_DBFIND_GLUEOK, now, NULL, foundname,
			      &rootrrset, NULL);
	if (hresult == ISC_R_SUCCESS &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			if (!inrrset(&hintrrset, &rdata))
				report(view, name, ISC_TRUE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&rootrrset);
		}
		result = dns_rdataset_first(&hintrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&hintrrset, &rdata);
			if (!inrrset(&rootrrset, &rdata))
				report(view, name, ISC_FALSE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&hintrrset);
		}
	}
	if (hresult == ISC_R_NOTFOUND &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			report(view, name, ISC_TRUE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&rootrrset);
		}
	}
	if (dns_rdataset_isassociated(&rootrrset))
		dns_rdataset_disassociate(&rootrrset);
	if (dns_rdataset_isassociated(&hintrrset))
		dns_rdataset_disassociate(&hintrrset);
}
Example #29
0
static void
query(void) {
	char buf[1024];
	dns_fixedname_t name;
	dns_fixedname_t found;
	dns_db_t *db;
	char *s;
	isc_buffer_t buffer;
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_rdataset_t sigset;
	fd_set rfdset;

	db = NULL;
	result = dns_zone_getdb(zone, &db);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "%s() returned %s\n", "dns_zone_getdb",
			dns_result_totext(result));
		return;
	}

	dns_fixedname_init(&found);
	dns_rdataset_init(&rdataset);
	dns_rdataset_init(&sigset);

	do {

		fprintf(stdout, "zone_test ");
		fflush(stdout);
		FD_ZERO(&rfdset);
		FD_SET(0, &rfdset);
		select(1, &rfdset, NULL, NULL, NULL);
		if (fgets(buf, sizeof(buf), stdin) == NULL) {
			fprintf(stdout, "\n");
			break;
		}
		buf[sizeof(buf) - 1] = '\0';

		s = strchr(buf, '\n');
		if (s != NULL)
			*s = '\0';
		s = strchr(buf, '\r');
		if (s != NULL)
			*s = '\0';
		if (strcmp(buf, "dump") == 0) {
			dns_zone_dumptostream(zone, stdout);
			continue;
		}
		if (strlen(buf) == 0U)
			continue;
		dns_fixedname_init(&name);
		isc_buffer_init(&buffer, buf, strlen(buf));
		isc_buffer_add(&buffer, strlen(buf));
		result = dns_name_fromtext(dns_fixedname_name(&name),
				  &buffer, dns_rootname, 0, NULL);
		ERRCONT(result, "dns_name_fromtext");

		result = dns_db_find(db, dns_fixedname_name(&name),
				     NULL /*vesion*/,
				     dns_rdatatype_a,
				     0 /*options*/,
				     0 /*time*/,
				     NULL /*nodep*/,
				     dns_fixedname_name(&found),
				     &rdataset, &sigset);
		fprintf(stderr, "%s() returned %s\n", "dns_db_find",
			dns_result_totext(result));
		switch (result) {
		case DNS_R_DELEGATION:
			print_rdataset(dns_fixedname_name(&found), &rdataset);
			break;
		case ISC_R_SUCCESS:
			print_rdataset(dns_fixedname_name(&name), &rdataset);
			break;
		default:
			break;
		}

		if (dns_rdataset_isassociated(&rdataset))
			dns_rdataset_disassociate(&rdataset);
		if (dns_rdataset_isassociated(&sigset))
			dns_rdataset_disassociate(&sigset);
	} while (1);
	dns_rdataset_invalidate(&rdataset);
	dns_db_detach(&db);
}
Example #30
0
int
main(int argc, char *argv[]) {
	dns_db_t *db;
	dns_dbnode_t *node;
	isc_result_t result;
	dns_name_t name;
	dns_offsets_t offsets;
	size_t len;
	isc_buffer_t source, target;
	char s[1000];
	char b[255];
	dns_rdataset_t rdataset, sigrdataset;
	int ch;
	dns_rdatatype_t type = 1;
	isc_boolean_t printnode = ISC_FALSE;
	isc_boolean_t addmode = ISC_FALSE;
	isc_boolean_t delmode = ISC_FALSE;
	isc_boolean_t holdmode = ISC_FALSE;
	isc_boolean_t verbose = ISC_FALSE;
	isc_boolean_t done = ISC_FALSE;
	isc_boolean_t quiet = ISC_FALSE;
	isc_boolean_t time_lookups = ISC_FALSE;
	isc_boolean_t found_as;
	isc_boolean_t find_zonecut = ISC_FALSE;
	isc_boolean_t noexact_zonecut = ISC_FALSE;
	int i, v;
	dns_rdatasetiter_t *rdsiter;
	char t1[256];
	char t2[256];
	isc_buffer_t tb1, tb2;
	isc_region_t r1, r2;
	dns_fixedname_t foundname;
	dns_name_t *fname;
	unsigned int options = 0, zcoptions;
	isc_time_t start, finish;
	char *origintext;
	dbinfo *dbi;
	dns_dbversion_t *version;
	dns_name_t *origin;
	size_t memory_quota = 0;
	dns_trust_t trust = 0;
	unsigned int addopts;
	isc_log_t *lctx = NULL;
	size_t n;

	dns_result_register();

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) ==
		      ISC_R_SUCCESS);



	strcpy(dbtype, "rbt");
	while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT"))
	       != -1) {
		switch (ch) {
		case 'c':
			result = load(isc_commandline_argument, ".", ISC_TRUE);
			if (result != ISC_R_SUCCESS)
				printf("cache load(%s) %08x: %s\n",
				       isc_commandline_argument, result,
				       isc_result_totext(result));
			break;
		case 'd':
			n = strlcpy(dbtype, isc_commandline_argument,
				    sizeof(dbtype));
			if (n >= sizeof(dbtype)) {
				fprintf(stderr, "bad db type '%s'\n",
					isc_commandline_argument);
				exit(1);
			}
			break;
		case 'g':
			options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE);
			break;
		case 'l':
			RUNTIME_CHECK(isc_log_create(mctx, &lctx,
						     NULL) == ISC_R_SUCCESS);
			isc_log_setcontext(lctx);
			dns_log_init(lctx);
			dns_log_setcontext(lctx);
			break;
		case 'q':
			quiet = ISC_TRUE;
			verbose = ISC_FALSE;
			break;
		case 'p':
			printnode = ISC_TRUE;
			break;
		case 'P':
			pause_every = atoi(isc_commandline_argument);
			break;
		case 'Q':
			memory_quota = atoi(isc_commandline_argument);
			isc_mem_setquota(mctx, memory_quota);
			break;
		case 't':
			type = atoi(isc_commandline_argument);
			break;
		case 'T':
			time_lookups = ISC_TRUE;
			break;
		case 'v':
			verbose = ISC_TRUE;
			break;
		case 'z':
			origintext = strrchr(isc_commandline_argument, '/');
			if (origintext == NULL)
				origintext = isc_commandline_argument;
			else
				origintext++;	/* Skip '/'. */
			result = load(isc_commandline_argument, origintext,
				      ISC_FALSE);
			if (result != ISC_R_SUCCESS)
				printf("zone load(%s) %08x: %s\n",
				       isc_commandline_argument, result,
				       isc_result_totext(result));
			break;
		}
	}

	argc -= isc_commandline_index;
	argv += isc_commandline_index;
	POST(argv);

	if (argc != 0)
		printf("ignoring trailing arguments\n");

	/*
	 * Some final initialization...
	 */
	dns_fixedname_init(&foundname);
	fname = dns_fixedname_name(&foundname);
	dbi = NULL;
	origin = dns_rootname;
	version = NULL;

	if (time_lookups) {
		TIME_NOW(&start);
	}

	while (!done) {
		if (!quiet)
			printf("\n");
		if (fgets(s, sizeof(s), stdin) == NULL) {
			done = ISC_TRUE;
			continue;
		}
		len = strlen(s);
		if (len > 0U && s[len - 1] == '\n') {
			s[len - 1] = '\0';
			len--;
		}
		if (verbose && dbi != NULL) {
			if (dbi->wversion != NULL)
				printf("future version (%p)\n", dbi->wversion);
			for (i = 0; i < dbi->rcount; i++)
				if (dbi->rversions[i] != NULL)
					printf("open version %d (%p)\n", i,
					       dbi->rversions[i]);
		}
		dns_name_init(&name, offsets);
		if (strcmp(s, "!R") == 0) {
			DBI_CHECK(dbi);
			if (dbi->rcount == MAXVERSIONS) {
				printf("too many open versions\n");
				continue;
			}
			dns_db_currentversion(dbi->db,
					      &dbi->rversions[dbi->rcount]);
			printf("opened version %d\n", dbi->rcount);
			dbi->version = dbi->rversions[dbi->rcount];
			version = dbi->version;
			dbi->rcount++;
			continue;
		} else if (strcmp(s, "!W") == 0) {
			DBI_CHECK(dbi);
			if (dbi->wversion != NULL) {
				printf("using existing future version\n");
				dbi->version = dbi->wversion;
				version = dbi->version;
				continue;
			}
			result = dns_db_newversion(dbi->db, &dbi->wversion);
			if (result != ISC_R_SUCCESS)
				print_result("", result);
			else
				printf("newversion\n");
			dbi->version = dbi->wversion;
			version = dbi->version;
			continue;
		} else if (strcmp(s, "!C") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			delmode = ISC_FALSE;
			if (dbi->version == NULL)
				continue;
			if (dbi->version == dbi->wversion) {
				printf("closing future version\n");
				dbi->wversion = NULL;
			} else {
				for (i = 0; i < dbi->rcount; i++) {
					if (dbi->version ==
					    dbi->rversions[i]) {
						dbi->rversions[i] = NULL;
					  printf("closing open version %d\n",
						 i);
						break;
					}
				}
			}
			dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE);
			version = NULL;
			continue;
		} else if (strcmp(s, "!X") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			delmode = ISC_FALSE;
			if (dbi->version == NULL)
				continue;
			if (dbi->version == dbi->wversion) {
				printf("aborting future version\n");
				dbi->wversion = NULL;
			} else {
				for (i = 0; i < dbi->rcount; i++) {
					if (dbi->version ==
					    dbi->rversions[i]) {
						dbi->rversions[i] = NULL;
					  printf("closing open version %d\n",
						 i);
						break;
					}
				}
			}
			dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE);
			version = NULL;
			continue;
		} else if (strcmp(s, "!A") == 0) {
			DBI_CHECK(dbi);
			delmode = ISC_FALSE;
			if (addmode)
				addmode = ISC_FALSE;
			else
				addmode = ISC_TRUE;
			printf("addmode = %s\n", addmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!D") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			if (delmode)
				delmode = ISC_FALSE;
			else
				delmode = ISC_TRUE;
			printf("delmode = %s\n", delmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!H") == 0) {
			DBI_CHECK(dbi);
			if (holdmode)
				holdmode = ISC_FALSE;
			else
				holdmode = ISC_TRUE;
			printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!HR") == 0) {
			DBI_CHECK(dbi);
			for (i = 0; i < dbi->hold_count; i++)
				dns_db_detachnode(dbi->db,
						  &dbi->hold_nodes[i]);
			dbi->hold_count = 0;
			holdmode = ISC_FALSE;
			printf("held nodes have been detached\n");
			continue;
		} else if (strcmp(s, "!VC") == 0) {
			DBI_CHECK(dbi);
			printf("switching to current version\n");
			dbi->version = NULL;
			version = NULL;
			continue;
		} else if (strstr(s, "!V") == s) {
			DBI_CHECK(dbi);
			v = atoi(&s[2]);
			if (v >= dbi->rcount || v < 0) {
				printf("unknown open version %d\n", v);
				continue;
			}
			if (dbi->rversions[v] == NULL) {
				printf("version %d is not open\n", v);
				continue;
			}
			printf("switching to open version %d\n", v);
			dbi->version = dbi->rversions[v];
			version = dbi->version;
			continue;
		} else if (strstr(s, "!TR") == s) {
			trust = (unsigned int)atoi(&s[3]);
			printf("trust level is now %u\n", (unsigned int)trust);
			continue;
		} else if (strstr(s, "!T") == s) {
			type = (unsigned int)atoi(&s[2]);
			printf("now searching for type %u\n", type);
			continue;
		} else if (strcmp(s, "!G") == 0) {
			if ((options & DNS_DBFIND_GLUEOK) != 0)
				options &= ~DNS_DBFIND_GLUEOK;
			else
				options |= DNS_DBFIND_GLUEOK;
			printf("glue ok = %s\n",
			       ((options & DNS_DBFIND_GLUEOK) != 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!GV") == 0) {
			if ((options & DNS_DBFIND_VALIDATEGLUE) != 0)
				options &= ~DNS_DBFIND_VALIDATEGLUE;
			else
				options |= DNS_DBFIND_VALIDATEGLUE;
			printf("validate glue = %s\n",
			       ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!WC") == 0) {
			if ((options & DNS_DBFIND_NOWILD) != 0)
				options &= ~DNS_DBFIND_NOWILD;
			else
				options |= DNS_DBFIND_NOWILD;
			printf("wildcard matching = %s\n",
			       ((options & DNS_DBFIND_NOWILD) == 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strstr(s, "!LS ") == s) {
			DBI_CHECK(dbi);
			list(dbi, &s[4]);
			continue;
		} else if (strcmp(s, "!LS") == 0) {
			DBI_CHECK(dbi);
			list(dbi, NULL);
			continue;
		} else if (strstr(s, "!DU ") == s) {
			DBI_CHECK(dbi);
			result = dns_db_dump(dbi->db, dbi->version, s+4);
			if (result != ISC_R_SUCCESS) {
				printf("\n");
				print_result("", result);
			}
			continue;
		} else if (strcmp(s, "!PN") == 0) {
			if (printnode)
				printnode = ISC_FALSE;
			else
				printnode = ISC_TRUE;
			printf("printnode = %s\n",
			       printnode ? "TRUE" : "FALSE");
			continue;
		} else if (strstr(s, "!P") == s) {
			DBI_CHECK(dbi);
			v = atoi(&s[2]);
			dbi->pause_every = v;
			continue;
		} else if (strcmp(s, "!+") == 0) {
			DBI_CHECK(dbi);
			dbi->ascending = ISC_TRUE;
			continue;
		} else if (strcmp(s, "!-") == 0) {
			DBI_CHECK(dbi);
			dbi->ascending = ISC_FALSE;
			continue;
		} else if (strcmp(s, "!DB") == 0) {
			dbi = NULL;
			origin = dns_rootname;
			version = NULL;
			printf("now searching all databases\n");
			continue;
		} else if (strncmp(s, "!DB ", 4) == 0) {
			dbi = select_db(s+4);
			if (dbi != NULL) {
				db = dbi->db;
				origin = dns_db_origin(dbi->db);
				version = dbi->version;
				addmode = ISC_FALSE;
				delmode = ISC_FALSE;
				holdmode = ISC_FALSE;
			} else {
				db = NULL;
				version = NULL;
				origin = dns_rootname;
				printf("database not found; "
				       "now searching all databases\n");
			}
			continue;
		} else if (strcmp(s, "!ZC") == 0) {
			if (find_zonecut)
				find_zonecut = ISC_FALSE;
			else
				find_zonecut = ISC_TRUE;
			printf("find_zonecut = %s\n",
			       find_zonecut ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!NZ") == 0) {
			if (noexact_zonecut)
				noexact_zonecut = ISC_FALSE;
			else
				noexact_zonecut = ISC_TRUE;
			printf("noexact_zonecut = %s\n",
			       noexact_zonecut ? "TRUE" : "FALSE");
			continue;
		}

		isc_buffer_init(&source, s, len);
		isc_buffer_add(&source, len);
		isc_buffer_init(&target, b, sizeof(b));
		result = dns_name_fromtext(&name, &source, origin, 0, &target);
		if (result != ISC_R_SUCCESS) {
			print_result("bad name: ", result);
			continue;
		}

		if (dbi == NULL) {
			zcoptions = 0;
			if (noexact_zonecut)
				zcoptions |= DNS_DBTABLEFIND_NOEXACT;
			db = NULL;
			result = dns_dbtable_find(dbtable, &name, zcoptions,
						  &db);
			if (result != ISC_R_SUCCESS &&
			    result != DNS_R_PARTIALMATCH) {
				if (!quiet) {
					printf("\n");
					print_result("", result);
				}
				continue;
			}
			isc_buffer_init(&tb1, t1, sizeof(t1));
			result = dns_name_totext(dns_db_origin(db), ISC_FALSE,
						 &tb1);
			if (result != ISC_R_SUCCESS) {
				printf("\n");
				print_result("", result);
				dns_db_detach(&db);
				continue;
			}
			isc_buffer_usedregion(&tb1, &r1);
			printf("\ndatabase = %.*s (%s)\n",
			       (int)r1.length, r1.base,
			       (dns_db_iszone(db)) ? "zone" : "cache");
		}
		node = NULL;
		dns_rdataset_init(&rdataset);
		dns_rdataset_init(&sigrdataset);

		if (find_zonecut && dns_db_iscache(db)) {
			zcoptions = options;
			if (noexact_zonecut)
				zcoptions |= DNS_DBFIND_NOEXACT;
			result = dns_db_findzonecut(db, &name, zcoptions,
						    0, &node, fname,
						    &rdataset, &sigrdataset);
		} else {
			result = dns_db_find(db, &name, version, type,
					     options, 0, &node, fname,
					     &rdataset, &sigrdataset);
		}

		if (!quiet) {
			if (dbi != NULL)
				printf("\n");
			print_result("", result);
		}

		found_as = ISC_FALSE;
		switch (result) {
		case ISC_R_SUCCESS:
		case DNS_R_GLUE:
		case DNS_R_CNAME:
		case DNS_R_ZONECUT:
			break;
		case DNS_R_DNAME:
		case DNS_R_DELEGATION:
			found_as = ISC_TRUE;
			break;
		case DNS_R_NXRRSET:
			if (dns_rdataset_isassociated(&rdataset))
				break;
			if (dbi != NULL) {
				if (holdmode) {
					RUNTIME_CHECK(dbi->hold_count <
						      MAXHOLD);
					dbi->hold_nodes[dbi->hold_count++] =
						node;
					node = NULL;
				} else
					dns_db_detachnode(db, &node);
			} else {
				dns_db_detachnode(db, &node);
				dns_db_detach(&db);
			}
			continue;
		case DNS_R_NXDOMAIN:
			if (dns_rdataset_isassociated(&rdataset))
				break;
			/* FALLTHROUGH */
		default:
			if (dbi == NULL)
				dns_db_detach(&db);
			if (quiet)
				print_result("", result);
			continue;
		}
		if (found_as && !quiet) {
			isc_buffer_init(&tb1, t1, sizeof(t1));
			isc_buffer_init(&tb2, t2, sizeof(t2));
			result = dns_name_totext(&name, ISC_FALSE, &tb1);
			if (result != ISC_R_SUCCESS) {
				print_result("", result);
				dns_db_detachnode(db, &node);
				if (dbi == NULL)
					dns_db_detach(&db);
				continue;
			}
			result = dns_name_totext(fname, ISC_FALSE, &tb2);
			if (result != ISC_R_SUCCESS) {
				print_result("", result);
				dns_db_detachnode(db, &node);
				if (dbi == NULL)
					dns_db_detach(&db);
				continue;
			}
			isc_buffer_usedregion(&tb1, &r1);
			isc_buffer_usedregion(&tb2, &r2);
			printf("found %.*s as %.*s\n",
			       (int)r1.length, r1.base,
			       (int)r2.length, r2.base);
		}

		if (printnode)
			dns_db_printnode(db, node, stdout);

		if (!found_as && type == dns_rdatatype_any) {
			rdsiter = NULL;
			result = dns_db_allrdatasets(db, node, version, 0,
						     &rdsiter);
			if (result == ISC_R_SUCCESS) {
				if (!quiet)
					print_rdatasets(fname, rdsiter);
				dns_rdatasetiter_destroy(&rdsiter);
			} else
				print_result("", result);
		} else {
			if (!quiet)
				print_rdataset(fname, &rdataset);
			if (dns_rdataset_isassociated(&sigrdataset)) {
				if (!quiet)
					print_rdataset(fname, &sigrdataset);
				dns_rdataset_disassociate(&sigrdataset);
			}
			if (dbi != NULL && addmode && !found_as) {
				rdataset.ttl++;
				rdataset.trust = trust;
				if (dns_db_iszone(db))
					addopts = DNS_DBADD_MERGE;
				else
					addopts = 0;
				result = dns_db_addrdataset(db, node, version,
							    0, &rdataset,
							    addopts, NULL);
				if (result != ISC_R_SUCCESS)
					print_result("", result);
				if (printnode)
					dns_db_printnode(db, node, stdout);
			} else if (dbi != NULL && delmode && !found_as) {
				result = dns_db_deleterdataset(db, node,
							       version, type,
							       0);
				if (result != ISC_R_SUCCESS)
					print_result("", result);
				if (printnode)
					dns_db_printnode(db, node, stdout);
			}
			dns_rdataset_disassociate(&rdataset);
		}

		if (dbi != NULL) {
			if (holdmode) {
				RUNTIME_CHECK(dbi->hold_count < MAXHOLD);
				dbi->hold_nodes[dbi->hold_count++] = node;
				node = NULL;
			} else
				dns_db_detachnode(db, &node);
		} else {
			dns_db_detachnode(db, &node);
			dns_db_detach(&db);
		}
	}

	if (time_lookups) {
		isc_uint64_t usec;

		TIME_NOW(&finish);

		usec = isc_time_microdiff(&finish, &start);

		printf("elapsed time: %lu.%06lu seconds\n",
		       (unsigned long)(usec / 1000000),
		       (unsigned long)(usec % 1000000));
	}

	unload_all();

	dns_dbtable_detach(&dbtable);

	if (lctx != NULL)
		isc_log_destroy(&lctx);

	if (!quiet)
		isc_mem_stats(mctx, stdout);

	return (0);
}