Exemplo n.º 1
0
void
dns_dlzdestroy(dns_dlzdb_t **dbp) {
	isc_mem_t *mctx;
	dns_dlzdestroy_t destroy;

	/* Write debugging message to log */
	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
		      "Unloading DLZ driver.");

	/*
	 * Perform checks to make sure data is as we expect it to be.
	 */
	REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));

#ifdef BIND9
	if ((*dbp)->ssutable != NULL) {
		dns_ssutable_detach(&(*dbp)->ssutable);
	}
#endif

	/* call the drivers destroy method */
	if ((*dbp) != NULL) {
		mctx = (*dbp)->mctx;
		destroy = (*dbp)->implementation->methods->destroy;
		(*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata);
		/* return memory */
		isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
		isc_mem_detach(&mctx);
	}

	*dbp = NULL;
}
Exemplo n.º 2
0
isc_result_t
dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
		    isc_sockaddr_t *clientaddr, dns_db_t **dbp)
{
	isc_result_t result;
	dns_dlzallowzonexfr_t allowzonexfr;
	dns_dlzdb_t *dlzdatabase;

	/*
	 * Performs checks to make sure data is as we expect it to be.
	 */
	REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
	REQUIRE(name != NULL);
	REQUIRE(dbp != NULL && *dbp == NULL);

	/* ask driver if the zone is supported */
	dlzdatabase = view->dlzdatabase;
	allowzonexfr = dlzdatabase->implementation->methods->allowzonexfr;
	result = (*allowzonexfr)(dlzdatabase->implementation->driverarg,
				 dlzdatabase->dbdata, dlzdatabase->mctx,
				 view->rdclass, name, clientaddr, dbp);

	if (result == ISC_R_NOTIMPLEMENTED)
		return (ISC_R_NOTFOUND);
	return (result);
}
Exemplo n.º 3
0
void
dns_dlzdestroy(dns_dlzdb_t **dbp) {
	dns_dlzdestroy_t destroy;
	dns_dlzdb_t *db;

	/* Write debugging message to log */
	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
		      "Unloading DLZ driver.");

	/*
	 * Perform checks to make sure data is as we expect it to be.
	 */
	REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));

	db = *dbp;
	*dbp = NULL;

	if (db->ssutable != NULL)
		dns_ssutable_detach(&db->ssutable);

	/* call the drivers destroy method */
	if (db->dlzname != NULL)
		isc_mem_free(db->mctx, db->dlzname);
	destroy = db->implementation->methods->destroy;
	(*destroy)(db->implementation->driverarg, db->dbdata);
	/* return memory and detach */
	isc_mem_putanddetach(&db->mctx, db, sizeof(dns_dlzdb_t));
}
Exemplo n.º 4
0
isc_result_t
dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
		dns_db_t **dbp)
{
	dns_fixedname_t fname;
	dns_name_t *zonename;
	unsigned int namelabels;
	unsigned int i;
	isc_result_t result;
	dns_dlzfindzone_t findzone;
	dns_dlzdb_t *dlzdatabase;

	/*
	 * Performs checks to make sure data is as we expect it to be.
	 */
	REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
	REQUIRE(name != NULL);
	REQUIRE(dbp != NULL && *dbp == NULL);

	/* setup a "fixed" dns name */
	dns_fixedname_init(&fname);
	zonename = dns_fixedname_name(&fname);

	/* count the number of labels in the name */
	namelabels = dns_name_countlabels(name);

	/*
	 * loop through starting with the longest domain name and
	 * trying shorter names portions of the name until we find a
	 * match, have an error, or are below the 'minlabels'
	 * threshold.  minlabels is 0, if the standard database didn't
	 * have a zone name match.  Otherwise minlabels is the number
	 * of labels in that name.  We need to beat that for a
	 * "better" match for the DLZ database to be authoritative
	 * instead of the standard database.
	 */
	for (i = namelabels; i > minlabels && i > 1; i--) {
		if (i == namelabels) {
			result = dns_name_copy(name, zonename, NULL);
			if (result != ISC_R_SUCCESS)
				return (result);
		} else
			dns_name_split(name, i, NULL, zonename);

		/* ask SDLZ driver if the zone is supported */
		dlzdatabase = view->dlzdatabase;
		findzone = dlzdatabase->implementation->methods->findzone;
		result = (*findzone)(dlzdatabase->implementation->driverarg,
				     dlzdatabase->dbdata, dlzdatabase->mctx,
				     view->rdclass, zonename, dbp);
		if (result != ISC_R_NOTFOUND)
			return (result);
	}
	return (ISC_R_NOTFOUND);
}
Exemplo n.º 5
0
isc_result_t
dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
		    isc_sockaddr_t *clientaddr, dns_db_t **dbp)
{
	isc_result_t result = ISC_R_NOTFOUND;
	dns_dlzallowzonexfr_t allowzonexfr;
	dns_dlzdb_t *dlzdb;

	/*
	 * Performs checks to make sure data is as we expect it to be.
	 */
	REQUIRE(name != NULL);
	REQUIRE(dbp != NULL && *dbp == NULL);

	/*
	 * Find a driver in which the zone exists and transfer is supported
	 */
	for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
	     dlzdb != NULL;
	     dlzdb = ISC_LIST_NEXT(dlzdb, link))
	{
		REQUIRE(DNS_DLZ_VALID(dlzdb));

		allowzonexfr = dlzdb->implementation->methods->allowzonexfr;
		result = (*allowzonexfr)(dlzdb->implementation->driverarg,
					 dlzdb->dbdata, dlzdb->mctx,
					 view->rdclass, name, clientaddr, dbp);

		/*
		 * if ISC_R_NOPERM, we found the right database but
		 * the zone may not transfer.
		 */
		if (result == ISC_R_SUCCESS || result == ISC_R_NOPERM)
			return (result);
	}

	if (result == ISC_R_NOTIMPLEMENTED)
		result = ISC_R_NOTFOUND;

	return (result);
}
Exemplo n.º 6
0
/*%
 * Configure a DLZ driver. This is optional, and if supplied gives
 * the backend an opportunity to configure parameters related to DLZ.
 */
isc_result_t
dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb,
		 dlzconfigure_callback_t callback)
{
	dns_dlzimplementation_t *impl;
	isc_result_t result;

	REQUIRE(DNS_DLZ_VALID(dlzdb));
	REQUIRE(dlzdb->implementation != NULL);

	impl = dlzdb->implementation;

	if (impl->methods->configure == NULL)
		return (ISC_R_SUCCESS);

	dlzdb->configure_callback = callback;

	result = impl->methods->configure(impl->driverarg, dlzdb->dbdata,
					  view, dlzdb);
	return (result);
}
Exemplo n.º 7
0
/*%
 * Configure a DLZ driver. This is optional, and if supplied gives
 * the backend an opportunity to configure parameters related to DLZ.
 */
isc_result_t
dns_dlzconfigure(dns_view_t *view, isc_result_t (*callback)(dns_view_t *,
		 dns_zone_t *))
{
	dns_dlzimplementation_t *impl;
	dns_dlzdb_t *dlzdatabase;
	isc_result_t result;

	REQUIRE(view != NULL);
	REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
	REQUIRE(view->dlzdatabase->implementation != NULL);

	dlzdatabase = view->dlzdatabase;
	impl = dlzdatabase->implementation;

	if (impl->methods->configure == NULL)
		return (ISC_R_SUCCESS);

	dlzdatabase->configure_callback = callback;

	result = impl->methods->configure(impl->driverarg,
					  dlzdatabase->dbdata, view);
	return (result);
}
Exemplo n.º 8
0
/*
 * Create a writeable DLZ zone. This can be called by DLZ drivers
 * during configure() to create a zone that can be updated. The zone
 * type is set to dns_zone_dlz, which is equivalent to a master zone
 *
 * This function uses a callback setup in dns_dlzconfigure() to call
 * into the server zone code to setup the remaining pieces of server
 * specific functionality on the zone
 */
isc_result_t
dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) {
	dns_zone_t *zone = NULL;
	dns_zone_t *dupzone = NULL;
	isc_result_t result;
	isc_buffer_t buffer;
	dns_fixedname_t fixorigin;
	dns_name_t *origin;
	dns_dlzdb_t *dlzdatabase;

	REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));

	dlzdatabase = view->dlzdatabase;

	REQUIRE(dlzdatabase->configure_callback != NULL);

	isc_buffer_init(&buffer, zone_name, strlen(zone_name));
	isc_buffer_add(&buffer, strlen(zone_name));
	dns_fixedname_init(&fixorigin);
	result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
				   &buffer, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	origin = dns_fixedname_name(&fixorigin);

	/* See if the zone already exists */
	result = dns_view_findzone(view, origin, &dupzone);
	if (result == ISC_R_SUCCESS) {
		dns_zone_detach(&dupzone);
		result = ISC_R_EXISTS;
		goto cleanup;
	}
	INSIST(dupzone == NULL);

	/* Create it */
	result = dns_zone_create(&zone, view->mctx);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = dns_zone_setorigin(zone, origin);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	dns_zone_setview(zone, view);

	dns_zone_setadded(zone, ISC_TRUE);

	if (dlzdatabase->ssutable == NULL) {
		result = dns_ssutable_createdlz(dlzdatabase->mctx,
						&dlzdatabase->ssutable,
						view->dlzdatabase);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
	}
	dns_zone_setssutable(zone, dlzdatabase->ssutable);

	result = dlzdatabase->configure_callback(view, zone);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	/*
	 * Add the zone to its view in the new view list.
	 */
	result = dns_view_addzone(view, zone);

 cleanup:
	if (zone != NULL)
		dns_zone_detach(&zone);

	return (result);
}
Exemplo n.º 9
0
/*
 * Create a writeable DLZ zone. This can be called by DLZ drivers
 * during configure() to create a zone that can be updated. The zone
 * type is set to dns_zone_dlz, which is equivalent to a master zone
 *
 * This function uses a callback setup in dns_dlzconfigure() to call
 * into the server zone code to setup the remaining pieces of server
 * specific functionality on the zone
 */
isc_result_t
dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb,
		      const char *zone_name)
{
	dns_zone_t *zone = NULL;
	dns_zone_t *dupzone = NULL;
	isc_result_t result;
	isc_buffer_t buffer;
	dns_fixedname_t fixorigin;
	dns_name_t *origin;

	REQUIRE(DNS_DLZ_VALID(dlzdb));

	REQUIRE(dlzdb->configure_callback != NULL);

	isc_buffer_constinit(&buffer, zone_name, strlen(zone_name));
	isc_buffer_add(&buffer, strlen(zone_name));
	dns_fixedname_init(&fixorigin);
	result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
				   &buffer, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	origin = dns_fixedname_name(&fixorigin);

	if (!dlzdb->search) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_WARNING,
			      "DLZ %s has 'search no;', but attempted to "
			      "register writeable zone %s.",
			      dlzdb->dlzname, zone_name);
		result = ISC_R_SUCCESS;
		goto cleanup;
	}

	/* See if the zone already exists */
	result = dns_view_findzone(view, origin, &dupzone);
	if (result == ISC_R_SUCCESS) {
		dns_zone_detach(&dupzone);
		result = ISC_R_EXISTS;
		goto cleanup;
	}
	INSIST(dupzone == NULL);

	/* Create it */
	result = dns_zone_create(&zone, view->mctx);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = dns_zone_setorigin(zone, origin);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	dns_zone_setview(zone, view);

	dns_zone_setadded(zone, ISC_TRUE);

	if (dlzdb->ssutable == NULL) {
		result = dns_ssutable_createdlz(dlzdb->mctx,
						&dlzdb->ssutable, dlzdb);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
	}
	dns_zone_setssutable(zone, dlzdb->ssutable);

	result = dlzdb->configure_callback(view, dlzdb, zone);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	result = dns_view_addzone(view, zone);


 cleanup:
	if (zone != NULL)
		dns_zone_detach(&zone);

	return (result);
}