Esempio n. 1
0
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);
}
Esempio n. 2
0
/*
 * 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;
		}
	}
}
Esempio n. 3
0
File: zt.c Progetto: 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);
}
Esempio n. 4
0
ATF_TC_BODY(rbtnode_get_distance, tc) {
	isc_result_t result;
	test_context_t *ctx;
	const char *name_str = "a";
	dns_fixedname_t fname;
	dns_name_t *name;
	dns_rbtnode_t *node = NULL;
	dns_rbtnodechain_t chain;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	ctx = test_context_setup();

	build_name_from_str(name_str, &fname);
	name = dns_fixedname_name(&fname);

	dns_rbtnodechain_init(&chain, mctx);

	result = dns_rbt_findnode(ctx->rbt_distances, name, NULL,
				  &node, &chain, 0, NULL, NULL);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	while (node != NULL) {
		const size_t *distance = (const size_t *) node->data;
		if (distance != NULL)
			ATF_CHECK_EQ(*distance,
				     dns__rbtnode_getdistance(node));
		result = dns_rbtnodechain_next(&chain, NULL, NULL);
		if (result == ISC_R_NOMORE)
		      break;
		dns_rbtnodechain_current(&chain, NULL, NULL, &node);
	}

	ATF_CHECK_EQ(result, ISC_R_NOMORE);

	dns_rbtnodechain_invalidate(&chain);

	test_context_teardown(ctx);

	dns_test_end();
}
Esempio n. 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);
}
Esempio n. 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);
}
Esempio n. 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);
}
Esempio n. 8
0
static void
detail(dns_rbt_t *rbt, dns_name_t *name) {
	dns_name_t *foundname, *origin, *fullname;
	dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
	dns_rbtnode_t *node1, *node2;
	dns_rbtnodechain_t chain;
	isc_result_t result;
	isc_boolean_t nodes_should_match = ISC_FALSE;

	dns_rbtnodechain_init(&chain, mctx);

	dns_fixedname_init(&fixedorigin);
	dns_fixedname_init(&fixedfullname);
	dns_fixedname_init(&fixedfoundname);

	origin = dns_fixedname_name(&fixedorigin);
	fullname = dns_fixedname_name(&fixedfullname);
	foundname = dns_fixedname_name(&fixedfoundname);

	node1 = node2 = NULL;

	printf("checking chain information for ");
	print_name(name);
	printf("\n");

	result = dns_rbt_findnode(rbt, name, foundname, &node1, &chain,
				  DNS_RBTFIND_EMPTYDATA, NULL, NULL);

	switch (result) {
	case ISC_R_SUCCESS:
		printf("  found exact.");
		nodes_should_match = ISC_TRUE;
		break;
	case DNS_R_PARTIALMATCH:
		printf("  found parent.");
		break;
	case ISC_R_NOTFOUND:
		printf("  name not found.");
		break;
	default:
		printf("  unexpected result: %s\n", dns_result_totext(result));
		return;
	}

	if (node1 != NULL && node1->data != NULL) {
		printf("  data at node: ");
		print_name(node1->data);
	} else
		printf("  no data at node.");

	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
		printf("\n  name from dns_rbt_findnode: ");
		print_name(foundname);
	}

	result = dns_rbtnodechain_current(&chain, foundname, origin, &node2);

	if (result == ISC_R_SUCCESS) {
		printf("\n  name from dns_rbtnodechain_current: ");

		result = dns_name_concatenate(foundname, origin,
					      fullname, NULL);
		if (result == ISC_R_SUCCESS)
			print_name(fullname);
		else
			printf("%s\n", dns_result_totext(result));
		printf("\n      (foundname = ");
		print_name(foundname);
		printf(", origin = ");
		print_name(origin);
		printf(")\n");
		if (nodes_should_match && node1 != node2)
			printf("  nodes returned from each function "
			       "DO NOT match!\n");

	} else
		printf("\n  result from dns_rbtnodechain_current: %s\n",
		       dns_result_totext(result));

	printf("  level_matches = %d, level_count = %d\n",
	       chain.level_matches, chain.level_count);
}
Esempio n. 9
0
ATF_TC_BODY(rbt_remove, tc) {
	/*
	 * This testcase checks that after node removal, the
	 * binary-search tree is valid and all nodes that are supposed
	 * to exist are present in the correct order. It mainly tests
	 * DomainTree as a BST, and not particularly as a red-black
	 * tree. This test checks node deletion when upper nodes have
	 * data.
	 */
	isc_result_t result;
	size_t j;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

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

	/*
	 * Delete single nodes and check if the rest of the nodes exist.
	 */
	for (j = 0; j < ordered_names_count; j++) {
		dns_rbt_t *mytree = NULL;
		dns_rbtnode_t *node;
		size_t i;
		size_t *n;
		isc_boolean_t tree_ok;
		dns_rbtnodechain_t chain;
		size_t start_node;

		/* Create a tree. */
		result = dns_rbt_create(mctx, delete_data, NULL, &mytree);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

		/* Insert test data into the tree. */
		for (i = 0; i < domain_names_count; i++) {
			node = NULL;
			result = insert_helper(mytree, domain_names[i], &node);
			ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
		}

		/* Check that all names exist in order. */
		for (i = 0; i < ordered_names_count; i++) {
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[i], &fname);

			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, NULL,
						  DNS_RBTFIND_EMPTYDATA,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);

			/* Add node data */
			ATF_REQUIRE(node != NULL);
			ATF_REQUIRE_EQ(node->data, NULL);

			n = isc_mem_get(mctx, sizeof(size_t));
			*n = i;

			node->data = n;
		}

		/* Now, delete the j'th node from the tree. */
		{
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[j], &fname);

			name = dns_fixedname_name(&fname);

			result = dns_rbt_deletename(mytree, name, ISC_FALSE);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
		}

		/* Check RB tree properties. */
		tree_ok = dns__rbt_checkproperties(mytree);
		ATF_CHECK_EQ(tree_ok, ISC_TRUE);

		dns_rbtnodechain_init(&chain, mctx);

		/* Now, walk through nodes in order. */
		if (j == 0) {
			/*
			 * Node for ordered_names[0] was already deleted
			 * above. We start from node 1.
			 */
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[0], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, NULL,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_NOTFOUND);

			build_name_from_str(ordered_names[1], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, &chain,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
			start_node = 1;
		} else {
			/* Start from node 0. */
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[0], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, &chain,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
			start_node = 0;
		}

		/*
		 * node and chain have been set by the code above at
		 * this point.
		 */
		for (i = start_node; i < ordered_names_count; i++) {
			dns_fixedname_t fname_j, fname_i;
			dns_name_t *name_j, *name_i;

			build_name_from_str(ordered_names[j], &fname_j);
			name_j = dns_fixedname_name(&fname_j);
			build_name_from_str(ordered_names[i], &fname_i);
			name_i = dns_fixedname_name(&fname_i);

			if (dns_name_equal(name_i, name_j)) {
				/*
				 * This may be true for the last node if
				 * we seek ahead in the loop using
				 * dns_rbtnodechain_next() below.
				 */
				if (node == NULL) {
					break;
				}

				/* All ordered nodes have data
				 * initially. If any node is empty, it
				 * means it was removed, but an empty
				 * node exists because it is a
				 * super-domain. Just skip it.
				 */
				if (node->data == NULL) {
					result = dns_rbtnodechain_next(&chain,
								       NULL,
								       NULL);
					if (result == ISC_R_NOMORE) {
						node = NULL;
					} else {
						dns_rbtnodechain_current(&chain,
									 NULL,
									 NULL,
									 &node);
					}
				}
				continue;
			}

			ATF_REQUIRE(node != NULL);

			n = (size_t *) node->data;
			if (n != NULL) {
				/* printf("n=%zu, i=%zu\n", *n, i); */
				ATF_CHECK_EQ(*n, i);
			}

			result = dns_rbtnodechain_next(&chain, NULL, NULL);
			if (result == ISC_R_NOMORE) {
				node = NULL;
			} else {
				dns_rbtnodechain_current(&chain, NULL, NULL,
							 &node);
			}
		}

		/* We should have reached the end of the tree. */
		ATF_REQUIRE_EQ(node, NULL);

		dns_rbt_destroy(&mytree);
	}

	dns_test_end();
}