Example #1
0
void
dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db) {
	dns_db_t *stored_data = NULL;
	isc_result_t result;
	dns_name_t *name;

	REQUIRE(VALID_DBTABLE(dbtable));

	name = dns_db_origin(db);

	/*
	 * There is a requirement that the association of name with db
	 * be verified.  With the current rbt.c this is expensive to do,
	 * because effectively two find operations are being done, but
	 * deletion is relatively infrequent.
	 * XXXDCL ... this could be cheaper now with dns_rbt_deletenode.
	 */

	RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);

	result = dns_rbt_findname(dbtable->rbt, name, 0, NULL,
				  (void **) (void *)&stored_data);

	if (result == ISC_R_SUCCESS) {
		INSIST(stored_data == db);

		(void)dns_rbt_deletename(dbtable->rbt, name, ISC_FALSE);
	}

	RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
}
Example #2
0
static int
t1_search(char *name, dns_rbt_t *rbt, isc_mem_t *mctx,
	  isc_result_t *dns_result)
{
	int		nprobs;
	dns_name_t	*dns_searchname;
	dns_name_t	*dns_foundname;
	dns_fixedname_t	dns_fixedname;
	void		*data;

	nprobs = 0;
	if (name && dns_result) {
		if (create_name(name, mctx, &dns_searchname) == 0) {
			dns_fixedname_init(&dns_fixedname);
			dns_foundname = dns_fixedname_name(&dns_fixedname);
			data = NULL;
			*dns_result = dns_rbt_findname(rbt, dns_searchname, 0,
						dns_foundname, &data);
			delete_name(dns_searchname, mctx);
		} else {
			++nprobs;
		}
	} else {
		++nprobs;
	}
	return(nprobs);
}
Example #3
0
isc_result_t
dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name,
		 unsigned int options, dns_db_t **dbp)
{
	dns_db_t *stored_data = NULL;
	isc_result_t result;
	unsigned int rbtoptions = 0;

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

	if ((options & DNS_DBTABLEFIND_NOEXACT) != 0)
		rbtoptions |= DNS_RBTFIND_NOEXACT;

	RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read);

	result = dns_rbt_findname(dbtable->rbt, name, rbtoptions, NULL,
				  (void **) (void *)&stored_data);

	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
		dns_db_attach(stored_data, dbp);
	else if (dbtable->default_db != NULL) {
		dns_db_attach(dbtable->default_db, dbp);
		result = DNS_R_PARTIALMATCH;
	} else
		result = ISC_R_NOTFOUND;

	RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read);

	return (result);
}
isc_result_t
dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
			      dns_name_t *foundname)
{
	isc_result_t result;
	void *data;

	/*
	 * Search for the deepest match in 'keytable'.
	 */

	REQUIRE(VALID_KEYTABLE(keytable));
	REQUIRE(dns_name_isabsolute(name));
	REQUIRE(foundname != NULL);

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);

	data = NULL;
	result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);

	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
		result = ISC_R_SUCCESS;

	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);

	return (result);
}
isc_result_t
dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
			    isc_boolean_t *wantdnssecp)
{
	isc_result_t result;
	void *data;

	/*
	 * Is 'name' at or beneath a trusted key?
	 */

	REQUIRE(VALID_KEYTABLE(keytable));
	REQUIRE(dns_name_isabsolute(name));
	REQUIRE(wantdnssecp != NULL);

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);

	data = NULL;
	result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);

	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
		INSIST(data != NULL);
		*wantdnssecp = ISC_TRUE;
		result = ISC_R_SUCCESS;
	} else if (result == ISC_R_NOTFOUND) {
		*wantdnssecp = ISC_FALSE;
		result = ISC_R_SUCCESS;
	}

	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);

	return (result);
}
Example #6
0
/*
 * Walk the tree and ensure that all the test nodes are present.
 */
static void
check_test_data(dns_rbt_t *rbt) {
	dns_fixedname_t fixed;
	isc_result_t result;
	dns_name_t *foundname;
	size_t i;

	dns_fixedname_init(&fixed);
	foundname = dns_fixedname_name(&fixed);

	for (i = 0; i < domain_names_count; i++) {
		dns_fixedname_t fname;
		dns_name_t *name;
		size_t *n;

		build_name_from_str(domain_names[i], &fname);

		name = dns_fixedname_name(&fname);
		n = NULL;
		result = dns_rbt_findname(rbt, name, 0, foundname,
					  (void *) &n);
		ATF_CHECK_EQ(result, ISC_R_SUCCESS);
		ATF_CHECK_EQ(*n, i + 1);
	}
}
Example #7
0
isc_result_t
dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
		 dns_name_t *algorithm, dns_tsig_keyring_t *ring)
{
	dns_tsigkey_t *key;
	isc_stdtime_t now;
	isc_result_t result;

	REQUIRE(tsigkey != NULL);
	REQUIRE(*tsigkey == NULL);
	REQUIRE(name != NULL);
	REQUIRE(ring != NULL);

	RWLOCK(&ring->lock, isc_rwlocktype_write);
	cleanup_ring(ring);
	RWUNLOCK(&ring->lock, isc_rwlocktype_write);

	isc_stdtime_get(&now);
	RWLOCK(&ring->lock, isc_rwlocktype_read);
	key = NULL;
	result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
	if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
		/*
		 * The key has expired.
		 */
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		RWLOCK(&ring->lock, isc_rwlocktype_write);
		remove_fromring(key);
		RWUNLOCK(&ring->lock, isc_rwlocktype_write);
		return (ISC_R_NOTFOUND);
	}
#if 0
	/*
	 * MPAXXX We really should look at the inception time.
	 */
	if (key->inception != key->expire &&
	    isc_serial_lt(key->inception, now)) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		adjust_lru(key);
		return (ISC_R_NOTFOUND);
	}
#endif
	isc_refcount_increment(&key->refs, NULL);
	RWUNLOCK(&ring->lock, isc_rwlocktype_read);
	adjust_lru(key);
	*tsigkey = key;
	return (ISC_R_SUCCESS);
}
isc_result_t
dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
			 dns_secalg_t algorithm, dns_keytag_t tag,
			 dns_keynode_t **keynodep)
{
	isc_result_t result;
	dns_keynode_t *knode;
	void *data;

	/*
	 * Search for a key named 'name', matching 'algorithm' and 'tag' in
	 * 'keytable'.
	 */

	REQUIRE(VALID_KEYTABLE(keytable));
	REQUIRE(dns_name_isabsolute(name));
	REQUIRE(keynodep != NULL && *keynodep == NULL);

	RWLOCK(&keytable->rwlock, isc_rwlocktype_read);

	/*
	 * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname()
	 * as that indicates that 'name' was not found.
	 *
	 * DNS_R_PARTIALMATCH indicates that the name was found but we
	 * didn't get a match on algorithm and key id arguments.
	 */
	knode = NULL;
	data = NULL;
	result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);

	if (result == ISC_R_SUCCESS) {
		INSIST(data != NULL);
		for (knode = data; knode != NULL; knode = knode->next) {
			if (knode->key == NULL) {
				knode = NULL;
				break;
			}
			if (algorithm == dst_key_alg(knode->key)
			    && tag == dst_key_id(knode->key))
				break;
		}
		if (knode != NULL) {
			LOCK(&keytable->lock);
			keytable->active_nodes++;
			UNLOCK(&keytable->lock);
			dns_keynode_attach(knode, keynodep);
		} else
			result = DNS_R_PARTIALMATCH;
	} else if (result == DNS_R_PARTIALMATCH)
		result = ISC_R_NOTFOUND;

	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);

	return (result);
}
Example #9
0
isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name,
		  dns_forwarders_t **forwardersp)
{
	isc_result_t result;

	REQUIRE(VALID_FWDTABLE(fwdtable));

	RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read);

	result = dns_rbt_findname(fwdtable->table, name, 0, NULL,
				  (void **)forwardersp);
	if (result == DNS_R_PARTIALMATCH)
		result = ISC_R_SUCCESS;

	RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read);

	return (result);
}
Example #10
0
isc_result_t
dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
		 dns_name_t *algorithm, dns_tsig_keyring_t *ring)
{
	dns_tsigkey_t *key;
	isc_stdtime_t now;
	isc_result_t result;

	REQUIRE(tsigkey != NULL);
	REQUIRE(*tsigkey == NULL);
	REQUIRE(name != NULL);
	REQUIRE(ring != NULL);

	isc_stdtime_get(&now);
	RWLOCK(&ring->lock, isc_rwlocktype_read);
	key = NULL;
	result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
	if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (key->inception != key->expire && key->expire < now) {
		/*
		 * The key has expired.
		 */
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		RWLOCK(&ring->lock, isc_rwlocktype_write);
		(void) dns_rbt_deletename(ring->keys, name, ISC_FALSE);
		RWUNLOCK(&ring->lock, isc_rwlocktype_write);
		return (ISC_R_NOTFOUND);
	}

	isc_refcount_increment(&key->refs, NULL);
	RWUNLOCK(&ring->lock, isc_rwlocktype_read);
	*tsigkey = key;
	return (ISC_R_SUCCESS);
}
Example #11
0
/*
 * Walk the tree and ensure that all the test nodes are present.
 */
static void
check_test_data(dns_rbt_t *rbt) {
	char buffer[1024];
	char *arg;
	dns_fixedname_t fname;
	dns_fixedname_t fixed;
	dns_name_t *name;
	isc_buffer_t b;
	data_holder_t *data;
	isc_result_t result;
	dns_name_t *foundname;
	rbt_testdata_t *testdatap = testdata;

	dns_fixedname_init(&fixed);
	foundname = dns_fixedname_name(&fixed);

	while (testdatap->name != NULL && testdatap->data.data != NULL) {
		memmove(buffer, testdatap->name, testdatap->name_len + 1);
		arg = buffer;

		isc_buffer_init(&b, arg, testdatap->name_len);
		isc_buffer_add(&b, testdatap->name_len);
		dns_fixedname_init(&fname);
		name = dns_fixedname_name(&fname);
		result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
		if (result != ISC_R_SUCCESS) {
			testdatap++;
			continue;
		}

		data = NULL;
		result = dns_rbt_findname(rbt, name, 0, foundname,
					  (void *) &data);
		ATF_CHECK_STREQ(dns_result_totext(result), "success");

		testdatap++;
	}
}
Example #12
0
isc_result_t
dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
	    dns_name_t *foundname, dns_zone_t **zonep)
{
	isc_result_t result;
	dns_zone_t *dummy = NULL;
	unsigned int rbtoptions = 0;

	REQUIRE(VALID_ZT(zt));

	if ((options & DNS_ZTFIND_NOEXACT) != 0)
		rbtoptions |= DNS_RBTFIND_NOEXACT;

	RWLOCK(&zt->rwlock, isc_rwlocktype_read);

	result = dns_rbt_findname(zt->table, name, rbtoptions, foundname,
				  (void **) (void*)&dummy);
	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
		dns_zone_attach(dummy, zonep);

	RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);

	return (result);
}
Example #13
0
int
main(int argc, char **argv) {
	char *command, *arg, buffer[1024];
	const char *whitespace;
	dns_name_t *name, *foundname;
	dns_fixedname_t fixedname;
	dns_rbt_t *rbt = NULL;
	int length, ch;
	isc_boolean_t show_final_mem = ISC_FALSE;
	isc_result_t result;
	void *data;

	progname = strrchr(*argv, '/');
	if (progname != NULL)
		progname++;
	else
		progname = *argv;

	while ((ch = isc_commandline_parse(argc, argv, "m")) != -1) {
		switch (ch) {
		case 'm':
			show_final_mem = ISC_TRUE;
			break;
		}
	}

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

	if (argc > 1) {
		printf("Usage: %s [-m]\n", progname);
		exit(1);
	}

	setbuf(stdout, NULL);

	/*
	 * So isc_mem_stats() can report any allocation leaks.
	 */
	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = isc_mem_create(0, 0, &mctx);
	if (result != ISC_R_SUCCESS) {
		printf("isc_mem_create: %s: exiting\n",
		       dns_result_totext(result));
		exit(1);
	}

	result = dns_rbt_create(mctx, delete_name, NULL, &rbt);
	if (result != ISC_R_SUCCESS) {
		printf("dns_rbt_create: %s: exiting\n",
		       dns_result_totext(result));
		exit(1);
	}

	whitespace = " \t";

	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
		length = strlen(buffer);

		if (buffer[length - 1] != '\n') {
			printf("line to long (%lu max), ignored\n",
			       (unsigned long)sizeof(buffer) - 2);
			continue;
		}

		buffer[length - 1] = '\0';

		command = buffer + strspn(buffer, whitespace);

		if (*command == '#')
			continue;

		arg = strpbrk(command, whitespace);
		if (arg != NULL) {
			*arg++ = '\0';
			arg += strspn(arg, whitespace);
		}

		length = strlen(command);
		if (*command != '\0') {
			if (CMDCHECK("add")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("adding name %s\n", arg);
					result = dns_rbt_addname(rbt,
								 name, name);
					PRINTERR(result);
				}

			} else if (CMDCHECK("delete")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("deleting name %s\n", arg);
					result = dns_rbt_deletename(rbt, name,
								    ISC_FALSE);
					PRINTERR(result);
					delete_name(name, NULL);
				}

			} else if (CMDCHECK("nuke")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("nuking name %s "
					       "and its descendants\n", arg);
					result = dns_rbt_deletename(rbt, name,
								    ISC_TRUE);
					PRINTERR(result);
					delete_name(name, NULL);
				}

			} else if (CMDCHECK("search")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("searching for name %s ... ",
					       arg);

					dns_fixedname_init(&fixedname);
					foundname =
						dns_fixedname_name(&fixedname);
					data = NULL;

					result = dns_rbt_findname(rbt, name, 0,
								  foundname,
								  &data);
					switch (result) {
					case ISC_R_SUCCESS:
						printf("found exact: ");
						print_name(data);
						putchar('\n');
						break;
					case DNS_R_PARTIALMATCH:
						printf("found parent: ");
						print_name(data);
						printf("\n\t(foundname: ");
						print_name(foundname);
						printf(")\n");
						break;
					case ISC_R_NOTFOUND:
						printf("NOT FOUND!\n");
						break;
					case ISC_R_NOMEMORY:
						printf("OUT OF MEMORY!\n");
						break;
					default:
						printf("UNEXPECTED RESULT\n");
					}

					delete_name(name, NULL);
				}

			} else if (CMDCHECK("check")) {
				/*
				 * Or "chain".  I know, I know.  Lame name.
				 * I was having a hard time thinking of a
				 * name (especially one that did not have
				 * a conflicting first letter with another
				 * command) that would differentiate this
				 * from the search command.
				 *
				 * But it is just a test program, eh?
				 */
				name = create_name(arg);
				if (name != NULL) {
					detail(rbt, name);

					delete_name(name, NULL);
				}

			} else if (CMDCHECK("forward")) {
				iterate(rbt, ISC_TRUE);

			} else if (CMDCHECK("backward")) {
				iterate(rbt, ISC_FALSE);

			} else if (CMDCHECK("print")) {
				if (arg == NULL || *arg == '\0')
					dns_rbt_printall(rbt, NULL);
				else
					printf("usage: print\n");

			} else if (CMDCHECK("quit")) {
				if (arg == NULL || *arg == '\0')
					break;
				else
					printf("usage: quit\n");
			} else {
				printf("a(dd) NAME, d(elete) NAME, "
				       "s(earch) NAME, p(rint), or q(uit)\n");

			}
		}

	}

	dns_rbt_destroy(&rbt);

	if (show_final_mem)
		isc_mem_stats(mctx, stderr);

	return (0);
}
Example #14
0
isc_result_t
cached_ldap_rdatalist_get(isc_mem_t *mctx, ldap_cache_t *cache,
			  ldap_db_t *ldap_db, dns_name_t *name,
			  dns_name_t *origin, ldapdb_rdatalist_t *rdatalist)
{
	isc_result_t result;
	ldapdb_rdatalist_t rdlist;
	cache_node_t *node = NULL;
	int in_cache = 0;
	int is_locked = 0;

	REQUIRE(cache != NULL);

	if (cache->rbt == NULL)
		return ldapdb_rdatalist_get(mctx, ldap_db, name, origin,
					    rdatalist);

	CONTROLED_LOCK(&cache->mutex);
	result = dns_rbt_findname(cache->rbt, name, 0, NULL, (void *)&node);
	if (result == ISC_R_SUCCESS) {
		isc_time_t now;

		CHECK(isc_time_now(&now));

		/* Check if the record is still valid. */
		if (isc_time_compare(&now, &node->valid_until) > 0) {
			CHECK(dns_rbt_deletename(cache->rbt, name, ISC_FALSE));
			in_cache = 0;
		} else {
			rdlist = node->rdatalist;
			in_cache = 1;
		}
	} else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) {
		goto cleanup;
	}
	CONTROLED_UNLOCK(&cache->mutex);

	if (!in_cache) {
		INIT_LIST(rdlist);
		result = ldapdb_rdatalist_get(mctx, ldap_db, name, origin,
					      &rdlist);
		/* TODO: Cache entries that are not found. */
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		CONTROLED_LOCK(&cache->mutex);
		/* Check again to make sure. */
		node = NULL;
		result = dns_rbt_findname(cache->rbt, name, 0, NULL,
					  (void *)&node);
		if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
			node = NULL;
			CHECK(cache_node_create(cache, rdlist, &node));
			CHECK(dns_rbt_addname(cache->rbt, name, (void *)node));
		}
		CONTROLED_UNLOCK(&cache->mutex);
	}

	CHECK(ldap_rdatalist_copy(mctx, rdlist, rdatalist));

	if (EMPTY(*rdatalist))
		result = ISC_R_NOTFOUND;

cleanup:
	CONTROLED_UNLOCK(&cache->mutex);
	return result;
}