Exemplo n.º 1
0
/*
 * Test that a ticket obtained for the DNS service will be accepted on the Samba DLZ side
 *
 */
static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech)
{
	NTSTATUS status;

	struct gensec_security *gensec_client_context;

	DATA_BLOB client_to_server, server_to_client;

	void *dbdata;
	const char *argv[] = {
		"samba_dlz",
		"-H",
		lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
		NULL
	};
	tctx_static = tctx;
	torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata,
						  "log", dlz_bind9_log_wrapper,
						  "writeable_zone", dlz_bind9_writeable_zone_hook, NULL),
				 ISC_R_SUCCESS,
				 "Failed to create samba_dlz");

	torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
						     ISC_R_SUCCESS,
				 "Failed to configure samba_dlz");

	status = gensec_client_start(tctx, &gensec_client_context,
				     lpcfg_gensec_settings(tctx, tctx->lp_ctx));
	torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");

	status = gensec_set_target_hostname(gensec_client_context, torture_setting_string(tctx, "host", NULL));
	torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");

	status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
	torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");

	status = gensec_start_mech_by_sasl_name(gensec_client_context, mech);
	torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");

	server_to_client = data_blob(NULL, 0);

	/* Do one step of the client-server update dance */
	status = gensec_update(gensec_client_context, tctx, tctx->ev, server_to_client, &client_to_server);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
		torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
	}

	torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials),
						    lpcfg_dnsdomain(tctx->lp_ctx),
						    "127.0.0.1", "type", "key",
						    client_to_server.length,
						    client_to_server.data,
						    dbdata),
				 ISC_R_SUCCESS,
				 "Failed to check key for update rights samba_dlz");

	dlz_destroy(dbdata);

	return true;
}
Exemplo n.º 2
0
/*
 * Called to initialize the driver
 */
isc_result_t
dlz_create(const char *dlzname, unsigned int argc, char *argv[],
	   void **dbdata, ...)
{
	struct dlz_example_data *state;
	const char *helper_name;
	va_list ap;
	char soa_data[200];

	UNUSED(dlzname);

	state = calloc(1, sizeof(struct dlz_example_data));
	if (state == NULL)
		return (ISC_R_NOMEMORY);

	/* Fill in the helper functions */
	va_start(ap, dbdata);
	while ((helper_name = va_arg(ap, const char *)) != NULL) {
		b9_add_helper(state, helper_name, va_arg(ap, void*));
	}
	va_end(ap);

	if (argc < 2) {
		state->log(ISC_LOG_ERROR,
			   "dlz_example: please specify a zone name");
		dlz_destroy(state);
		return (ISC_R_FAILURE);
	}

	state->zone_name = strdup(argv[1]);

	sprintf(soa_data, "%s hostmaster.%s 123 900 600 86400 3600",
		state->zone_name, state->zone_name);

	add_name(state, &state->current[0], state->zone_name,
		 "soa", 3600, soa_data);
	add_name(state, &state->current[0], state->zone_name,
		 "ns", 3600, state->zone_name);
	add_name(state, &state->current[0], state->zone_name,
		 "a", 1800, "10.53.0.1");

	state->log(ISC_LOG_INFO,
		   "dlz_example: started for zone %s",
		   state->zone_name);

	*dbdata = state;
	return (ISC_R_SUCCESS);
}
Exemplo n.º 3
0
static bool test_dlz_bind9_create(struct torture_context *tctx)
{
	void *dbdata;
	const char *argv[] = {
		"samba_dlz",
		"-H",
		lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
		NULL
	};
	tctx_static = tctx;
	torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
						  "log", dlz_bind9_log_wrapper, NULL), ISC_R_SUCCESS,
		"Failed to create samba_dlz");

	dlz_destroy(dbdata);

	return true;
}
Exemplo n.º 4
0
/*
 * Test some updates
 */
static bool test_dlz_bind9_update01(struct torture_context *tctx)
{
	NTSTATUS status;
	struct gensec_security *gensec_client_context;
	DATA_BLOB client_to_server, server_to_client;
	void *dbdata;
	void *version = NULL;
	const char *argv[] = {
		"samba_dlz",
		"-H",
		lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
		NULL
	};
	struct test_expected_rr *expected1 = NULL;
	char *name = NULL;
	char *data0 = NULL;
	char *data1 = NULL;
	char *data2 = NULL;
	bool ret = false;

	tctx_static = tctx;
	torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
						  "log", dlz_bind9_log_wrapper,
						  "writeable_zone", dlz_bind9_writeable_zone_hook,
						  "putrr", dlz_bind9_putrr_hook,
						  "putnamedrr", dlz_bind9_putnamedrr_hook,
						  NULL),
				 ISC_R_SUCCESS,
				 "Failed to create samba_dlz");

	torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
						     ISC_R_SUCCESS,
				 "Failed to configure samba_dlz");

	expected1 = talloc_zero(tctx, struct test_expected_rr);
	torture_assert(tctx, expected1 != NULL, "talloc failed");
	expected1->tctx = tctx;

	expected1->query_name = __func__;

	name = talloc_asprintf(expected1, "%s.%s",
				expected1->query_name,
				lpcfg_dnsdomain(tctx->lp_ctx));
	torture_assert(tctx, name != NULL, "talloc failed");

	expected1->num_records = 2;
	expected1->records = talloc_zero_array(expected1,
					       struct test_expected_record,
					       expected1->num_records);
	torture_assert(tctx, expected1->records != NULL, "talloc failed");

	expected1->records[0].name = expected1->query_name;
	expected1->records[0].type = "a";
	expected1->records[0].ttl = 3600;
	expected1->records[0].data = "127.1.2.3";
	expected1->records[0].printed = false;

	data0 = talloc_asprintf(expected1,
				"%s.\t" "%u\t" "%s\t" "%s\t" "%s",
				name,
				(unsigned)expected1->records[0].ttl,
				"in",
				expected1->records[0].type,
				expected1->records[0].data);
	torture_assert(tctx, data0 != NULL, "talloc failed");

	expected1->records[1].name = expected1->query_name;
	expected1->records[1].type = "a";
	expected1->records[1].ttl = 3600;
	expected1->records[1].data = "127.3.2.1";
	expected1->records[1].printed = false;

	data1 = talloc_asprintf(expected1,
				"%s.\t" "%u\t" "%s\t" "%s\t" "%s",
				name,
				(unsigned)expected1->records[1].ttl,
				"in",
				expected1->records[1].type,
				expected1->records[1].data);
	torture_assert(tctx, data1 != NULL, "talloc failed");

	data2 = talloc_asprintf(expected1,
				"%s.\t" "0\t" "in\t" "a\t" "127.3.3.3",
				name);
	torture_assert(tctx, data2 != NULL, "talloc failed");

	/*
	 * Prepare session info
	 */
	status = gensec_client_start(tctx, &gensec_client_context,
				     lpcfg_gensec_settings(tctx, tctx->lp_ctx));
	torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");

	/*
	 * dlz_bind9 use the special dns/host.domain account
	 */
	status = gensec_set_target_hostname(gensec_client_context,
					    talloc_asprintf(tctx,
				"%s.%s",
				torture_setting_string(tctx, "host", NULL),
				lpcfg_dnsdomain(tctx->lp_ctx)));
	torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");

	status = gensec_set_target_service(gensec_client_context, "dns");
	torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed");

	status = gensec_set_credentials(gensec_client_context, cmdline_credentials);
	torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");

	status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSS-SPNEGO");
	torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");

	server_to_client = data_blob(NULL, 0);

	/* Do one step of the client-server update dance */
	status = gensec_update(gensec_client_context, tctx, tctx->ev, server_to_client, &client_to_server);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
		torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
	}

	torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials),
						    name,
						    "127.0.0.1",
						    expected1->records[0].type,
						    "key",
						    client_to_server.length,
						    client_to_server.data,
						    dbdata),
				 ISC_TRUE,
				 "Failed to check key for update rights samba_dlz");

	/*
	 * We test the following:
	 *
	 *  1. lookup the records => NOT_FOUND
	 *  2. delete all records => NOT_FOUND
	 *  3. delete 1st record => NOT_FOUND
	 *  4. create 1st record => SUCCESS
	 *  5. lookup the records => found 1st
	 *  6. create 2nd record => SUCCESS
	 *  7. lookup the records => found 1st and 2nd
	 *  8. delete unknown record => NOT_FOUND
	 *  9. lookup the records => found 1st and 2nd
	 * 10. delete 1st record => SUCCESS
	 * 11. lookup the records => found 2nd
	 * 12. delete 2nd record => SUCCESS
	 * 13. lookup the records => NOT_FOUND
	 * 14. create 1st record => SUCCESS
	 * 15. lookup the records => found 1st
	 * 16. create 2nd record => SUCCESS
	 * 17. lookup the records => found 1st and 2nd
	 * 18. update 1st record => SUCCESS
	 * 19. lookup the records => found 1st and 2nd
	 * 20. delete all unknown type records => NOT_FOUND
	 * 21. lookup the records => found 1st and 2nd
	 * 22. delete all records => SUCCESS
	 * 23. lookup the records => NOT_FOUND
	 */

	/* Step 1. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_NOTFOUND,
				 "Found hostname");
	torture_assert_int_equal(tctx, expected1->num_rr, 0,
				 "Got wrong record count");

	/* Step 2. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_delrdataset(name,
					expected1->records[0].type,
					dbdata, version),
			ISC_R_NOTFOUND, ret, cancel_version,
			talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
			name, expected1->records[0].type));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);

	/* Step 3. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_subrdataset(name, data0, dbdata, version),
			ISC_R_NOTFOUND, ret, cancel_version,
			talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
			name, data0));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);

	/* Step 4. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_addrdataset(name, data0, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
			name, data0));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 5. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 1,
				 "Got wrong record count");

	/* Step 6. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_addrdataset(name, data1, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
			name, data1));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 7. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 2,
				 "Got wrong record count");

	/* Step 8. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_subrdataset(name, data2, dbdata, version),
			ISC_R_NOTFOUND, ret, cancel_version,
			talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n",
			name, data2));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 9. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 2,
				 "Got wrong record count");

	/* Step 10. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_subrdataset(name, data0, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
			name, data0));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 11. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 1,
				 "Got wrong record count");

	/* Step 12. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_subrdataset(name, data1, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n",
			name, data1));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 13. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_NOTFOUND,
				 "Found hostname");
	torture_assert_int_equal(tctx, expected1->num_rr, 0,
				 "Got wrong record count");

	/* Step 14. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_addrdataset(name, data0, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
			name, data0));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 15. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 1,
				 "Got wrong record count");

	/* Step 16. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_addrdataset(name, data1, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n",
			name, data1));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 17. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 2,
				 "Got wrong record count");

	/* Step 18. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_addrdataset(name, data0, dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to update name[%s] data[%s]\n",
			name, data0));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 19. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 2,
				 "Got wrong record count");

	/* Step 20. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_delrdataset(name, "txt", dbdata, version),
			ISC_R_FAILURE, ret, cancel_version,
			talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n",
			name, "txt"));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);

	/* Step 21. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_SUCCESS,
				 "Not found hostname");
	torture_assert(tctx, expected1->records[0].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[0].name,
		       expected1->records[0].type));
	torture_assert(tctx, expected1->records[1].printed,
		       talloc_asprintf(tctx,
		       "Failed to have putrr callback run name[%s] for type %s",
		       expected1->records[1].name,
		       expected1->records[1].type));
	torture_assert_int_equal(tctx, expected1->num_rr, 2,
				 "Got wrong record count");

	/* Step 22. */
	torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx),
						      dbdata, &version),
				 ISC_R_SUCCESS,
				 "Failed to start transaction");
	torture_assert_int_equal_goto(tctx,
			dlz_delrdataset(name,
					expected1->records[0].type,
					dbdata, version),
			ISC_R_SUCCESS, ret, cancel_version,
			talloc_asprintf(tctx, "Failed to delete name[%s] type[%s]\n",
			name, expected1->records[0].type));
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version);

	/* Step 23. */
	expected1->num_rr = 0;
	expected1->records[0].printed = false;
	expected1->records[1].printed = false;
	torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx),
						  expected1->query_name, dbdata,
						  (dns_sdlzlookup_t *)expected1),
				 ISC_R_NOTFOUND,
				 "Found hostname");
	torture_assert_int_equal(tctx, expected1->num_rr, 0,
				 "Got wrong record count");

	dlz_destroy(dbdata);

	return true;

cancel_version:
	dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version);
	return ret;
}
Exemplo n.º 5
0
/*
 * Test some zone dumps
 */
static bool test_dlz_bind9_zonedump(struct torture_context *tctx)
{
	size_t i;
	void *dbdata;
	const char *argv[] = {
		"samba_dlz",
		"-H",
		lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"),
		NULL
	};
	struct test_expected_rr *expected1 = NULL;

	tctx_static = tctx;
	torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata,
						  "log", dlz_bind9_log_wrapper,
						  "writeable_zone", dlz_bind9_writeable_zone_hook,
						  "putrr", dlz_bind9_putrr_hook,
						  "putnamedrr", dlz_bind9_putnamedrr_hook,
						  NULL),
				 ISC_R_SUCCESS,
				 "Failed to create samba_dlz");

	torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata),
						     ISC_R_SUCCESS,
				 "Failed to configure samba_dlz");

	expected1 = talloc_zero(tctx, struct test_expected_rr);
	torture_assert(tctx, expected1 != NULL, "talloc failed");
	expected1->tctx = tctx;

	expected1->num_records = 7;
	expected1->records = talloc_zero_array(expected1,
					       struct test_expected_record,
					       expected1->num_records);
	torture_assert(tctx, expected1->records != NULL, "talloc failed");

	expected1->records[0].name = talloc_asprintf(expected1->records,
				"%s.", lpcfg_dnsdomain(tctx->lp_ctx));
	expected1->records[0].type = "soa";
	expected1->records[0].ttl = 3600;
	expected1->records[0].data = talloc_asprintf(expected1->records,
				"%s.%s. hostmaster.%s. 1 900 600 86400 3600",
				torture_setting_string(tctx, "host", NULL),
				lpcfg_dnsdomain(tctx->lp_ctx),
				lpcfg_dnsdomain(tctx->lp_ctx));
	torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed");

	expected1->records[1].name = talloc_asprintf(expected1->records,
				"%s.", lpcfg_dnsdomain(tctx->lp_ctx));
	expected1->records[1].type = "ns";
	expected1->records[1].ttl = 900;
	expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s.",
				torture_setting_string(tctx, "host", NULL),
				lpcfg_dnsdomain(tctx->lp_ctx));
	torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed");

	expected1->records[2].name = talloc_asprintf(expected1->records,
				"%s.", lpcfg_dnsdomain(tctx->lp_ctx));
	expected1->records[2].type = "aaaa";
	expected1->records[2].ttl = 900;

	expected1->records[3].name = talloc_asprintf(expected1->records,
				"%s.", lpcfg_dnsdomain(tctx->lp_ctx));
	expected1->records[3].type = "a";
	expected1->records[3].ttl = 900;

	expected1->records[4].name = talloc_asprintf(expected1->records, "%s.%s.",
				torture_setting_string(tctx, "host", NULL),
				lpcfg_dnsdomain(tctx->lp_ctx));
	torture_assert(tctx, expected1->records[4].name != NULL, "unknown host");
	expected1->records[4].type = "aaaa";
	expected1->records[4].ttl = 900;

	expected1->records[5].name = talloc_asprintf(expected1->records, "%s.%s.",
				torture_setting_string(tctx, "host", NULL),
				lpcfg_dnsdomain(tctx->lp_ctx));
	torture_assert(tctx, expected1->records[5].name != NULL, "unknown host");
	expected1->records[5].type = "a";
	expected1->records[5].ttl = 900;

	/*
	 * We expect multiple srv records
	 */
	expected1->records[6].name = NULL;
	expected1->records[6].type = "srv";
	expected1->records[6].ttl = 900;

	torture_assert_int_equal(tctx, dlz_allnodes(lpcfg_dnsdomain(tctx->lp_ctx),
						    dbdata, (dns_sdlzallnodes_t *)expected1),
				 ISC_R_SUCCESS,
				 "Failed to configure samba_dlz");
	for (i = 0; i < expected1->num_records; i++) {
		torture_assert(tctx, expected1->records[i].printed,
			       talloc_asprintf(tctx,
			       "Failed to have putrr callback run name[%s] for type %s",
			       expected1->records[i].name,
			       expected1->records[i].type));
	}
	torture_assert_int_equal(tctx, expected1->num_rr, 24,
				 "Got wrong record count");

	dlz_destroy(dbdata);

	return true;
}
Exemplo n.º 6
0
/*%
 * Create an instance of the module.
 */
isc_result_t
dlz_create(const char *dlzname, unsigned int argc, char *argv[],
	   void **dbdata, ...)
{
	isc_result_t result = ISC_R_FAILURE;
	mysql_instance_t *mysql = NULL;
	dbinstance_t *dbi = NULL;
	MYSQL *dbc;
	char *tmp = NULL;
	char *endp;
	int j;
	const char *helper_name;
#if MYSQL_VERSION_ID >= 50000
        my_bool auto_reconnect = 1;
#endif
#if PTHREADS
	int dbcount;
	int i;
#endif /* PTHREADS */
	va_list ap;

	UNUSED(dlzname);

	/* allocate memory for MySQL instance */
	mysql = calloc(1, sizeof(mysql_instance_t));
	if (mysql == NULL)
		return (ISC_R_NOMEMORY);
	memset(mysql, 0, sizeof(mysql_instance_t));

	/* Fill in the helper functions */
	va_start(ap, dbdata);
	while ((helper_name = va_arg(ap, const char*)) != NULL)
		b9_add_helper(mysql, helper_name, va_arg(ap, void*));
	va_end(ap);

#if PTHREADS
	/* if debugging, let user know we are multithreaded. */
	mysql->log(ISC_LOG_DEBUG(1), "MySQL module running multithreaded");
#else /* PTHREADS */
	/* if debugging, let user know we are single threaded. */
	mysql->log(ISC_LOG_DEBUG(1), "MySQL module running single threaded");
#endif /* PTHREADS */

	/* verify we have at least 4 arg's passed to the module */
	if (argc < 4) {
		mysql->log(ISC_LOG_ERROR,
			   "MySQL module requires "
			   "at least 4 command line args.");
		return (ISC_R_FAILURE);
	}

	/* no more than 8 arg's should be passed to the module */
	if (argc > 8) {
		mysql->log(ISC_LOG_ERROR,
			   "MySQL module cannot accept "
			   "more than 7 command line args.");
		return (ISC_R_FAILURE);
	}

	/* get db name - required */
	mysql->dbname = get_parameter_value(argv[1], "dbname=");
	if (mysql->dbname == NULL) {
		mysql->log(ISC_LOG_ERROR,
			   "MySQL module requires a dbname parameter.");
		result = ISC_R_FAILURE;
		goto cleanup;
	}

	/* get db port.  Not required, but must be > 0 if specified */
	tmp = get_parameter_value(argv[1], "port=");
	if (tmp == NULL)
		mysql->port = 0;
	else {
		mysql->port = strtol(tmp, &endp, 10);
		if (*endp != '\0' || mysql->port < 0) {
			mysql->log(ISC_LOG_ERROR,
				   "Mysql module: port "
				   "must be a positive number.");
			free(tmp);
			result = ISC_R_FAILURE;
			goto cleanup;
		}
		free(tmp);
	}

	mysql->host = get_parameter_value(argv[1], "host=");
	mysql->user = get_parameter_value(argv[1], "user="******"pass="******"socket=");

	mysql->flags = CLIENT_REMEMBER_OPTIONS;

	tmp = get_parameter_value(argv[1], "compress=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "true") == 0)
			mysql->flags |= CLIENT_COMPRESS;
		free(tmp);
	}

	tmp = get_parameter_value(argv[1], "ssl=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "true") == 0)
			mysql->flags |= CLIENT_SSL;
		free(tmp);
	}

	tmp = get_parameter_value(argv[1], "space=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "ignore") == 0)
			mysql->flags |= CLIENT_IGNORE_SPACE;
		free(tmp);
	}

#if PTHREADS
	/* multithreaded build can have multiple DB connections */
	tmp = get_parameter_value(argv[1], "threads=");
	if (tmp == NULL)
		dbcount = 1;
	else {
		dbcount = strtol(tmp, &endp, 10);
		if (*endp != '\0' || dbcount < 1) {
			mysql->log(ISC_LOG_ERROR,
				   "MySQL database connection count "
				   "must be positive.");
			free(tmp);
			result = ISC_R_FAILURE;
			goto cleanup;
		}
		free(tmp);
	}

	/* allocate memory for database connection list */
	mysql->db = calloc(1, sizeof(db_list_t));
	if (mysql->db == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup;
	}

	/* initialize DB connection list */
	DLZ_LIST_INIT(*(mysql->db));

	/*
	 * create the appropriate number of database instances (DBI)
	 * append each new DBI to the end of the list
	 */
	for (i = 0; i < dbcount; i++) {
#endif /* PTHREADS */
		switch(argc) {
		case 4:
			result = build_dbinstance(NULL, NULL, NULL,
						  argv[2], argv[3], NULL,
						  &dbi, mysql->log);
			break;
		case 5:
			result = build_dbinstance(NULL, NULL, argv[4],
						  argv[2], argv[3], NULL,
						  &dbi, mysql->log);
			break;
		case 6:
			result = build_dbinstance(argv[5], NULL, argv[4],
						  argv[2], argv[3], NULL,
						  &dbi, mysql->log);
			break;
		case 7:
			result = build_dbinstance(argv[5], argv[6], argv[4],
						  argv[2], argv[3], NULL,
						  &dbi, mysql->log);
			break;
		case 8:
			result = build_dbinstance(argv[5], argv[6], argv[4],
						  argv[2], argv[3], argv[7],
						  &dbi, mysql->log);
			break;
		default:
			result = ISC_R_FAILURE;
		}


		if (result != ISC_R_SUCCESS) {
			mysql->log(ISC_LOG_ERROR,
				   "MySQL module could not create "
				   "database instance object.");
			result = ISC_R_FAILURE;
			goto cleanup;
		}

#if PTHREADS
		/* when multithreaded, build a list of DBI's */
		DLZ_LINK_INIT(dbi, link);
		DLZ_LIST_APPEND(*(mysql->db), dbi, link);
#else
		/*
		 * when single threaded, hold onto the one connection
		 * instance.
		 */
		mysql->db = dbi;
#endif

		/* create and set db connection */
		dbi->dbconn = mysql_init(NULL);
		if (dbi->dbconn == NULL) {
			mysql->log(ISC_LOG_ERROR,
				   "MySQL module could not allocate "
				   "memory for database connection");
			result = ISC_R_FAILURE;
			goto cleanup;
		}

		dbc = NULL;

#if MYSQL_VERSION_ID >= 50000
		/* enable automatic reconnection. */
		if (mysql_options((MYSQL *) dbi->dbconn, MYSQL_OPT_RECONNECT,
				  &auto_reconnect) != 0) {
			mysql->log(ISC_LOG_WARNING,
				   "MySQL module failed to set "
				   "MYSQL_OPT_RECONNECT option, continuing");
		}
#endif

		for (j = 0; dbc == NULL && j < 4; j++) {
			dbc = mysql_real_connect((MYSQL *) dbi->dbconn,
						 mysql->host, mysql->user,
						 mysql->pass, mysql->dbname,
						 mysql->port, mysql->socket,
						 mysql->flags);
			if (dbc == NULL)
				mysql->log(ISC_LOG_ERROR,
					   "MySQL connection failed: %s",
					   mysql_error((MYSQL *) dbi->dbconn));
		}

		if (dbc == NULL) {
			mysql->log(ISC_LOG_ERROR,
				   "MySQL module failed to create "
				   "database connection after 4 attempts");
			result = ISC_R_FAILURE;
			goto cleanup;
		}

#if PTHREADS
		/* set DBI = null for next loop through. */
		dbi = NULL;
	}
#endif /* PTHREADS */

	*dbdata = mysql;

	return (ISC_R_SUCCESS);

 cleanup:
	dlz_destroy(mysql);

	return (result);
}
Exemplo n.º 7
0
isc_result_t
dlz_create(const char *dlzname, unsigned int argc, char *argv[],
	   void **dbdata, ...)
{
	isc_result_t result = ISC_R_FAILURE;
	ldap_instance_t *ldap = NULL;
	dbinstance_t *dbi = NULL;
	const char *helper_name;
	int protocol;
	int method;
#if PTHREADS
	int dbcount;
	char *endp;
	int i;
#endif /* PTHREADS */
	va_list ap;

	UNUSED(dlzname);

	/* allocate memory for LDAP instance */
	ldap = calloc(1, sizeof(ldap_instance_t));
	if (ldap == NULL)
		return (ISC_R_NOMEMORY);
	memset(ldap, 0, sizeof(ldap_instance_t));

	/* Fill in the helper functions */
	va_start(ap, dbdata);
	while ((helper_name = va_arg(ap, const char*)) != NULL)
		b9_add_helper(ldap, helper_name, va_arg(ap, void*));
	va_end(ap);

#if PTHREADS
	/* if debugging, let user know we are multithreaded. */
	ldap->log(ISC_LOG_DEBUG(1), "LDAP driver running multithreaded");
#else /* PTHREADS */
	/* if debugging, let user know we are single threaded. */
	ldap->log(ISC_LOG_DEBUG(1), "LDAP driver running single threaded");
#endif /* PTHREADS */

	if (argc < 9) {
		ldap->log(ISC_LOG_ERROR,
			  "LDAP driver requires at least "
			  "8 command line args.");
		goto cleanup;
	}

	/* no more than 13 arg's should be passed to the driver */
	if (argc > 12) {
		ldap->log(ISC_LOG_ERROR,
			  "LDAP driver cannot accept more than "
			  "11 command line args.");
		goto cleanup;
	}

	/* determine protocol version. */
	if (strncasecmp(argv[2], V2, strlen(V2)) == 0)
		protocol = 2;
	else if (strncasecmp(argv[2], V3, strlen(V3)) == 0)
		protocol = 3;
	else {
		ldap->log(ISC_LOG_ERROR,
			  "LDAP driver protocol must be either %s or %s",
			  V2, V3);
		goto cleanup;
	}

	/* determine connection method. */
	if (strncasecmp(argv[3], SIMPLE, strlen(SIMPLE)) == 0)
		method = LDAP_AUTH_SIMPLE;
	else if (strncasecmp(argv[3], KRB41, strlen(KRB41)) == 0)
		method = LDAP_AUTH_KRBV41;
	else if (strncasecmp(argv[3], KRB42, strlen(KRB42)) == 0)
		method = LDAP_AUTH_KRBV42;
	else {
		ldap->log(ISC_LOG_ERROR,
			  "LDAP driver authentication method must be "
			  "one of %s, %s or %s", SIMPLE, KRB41, KRB42);
		goto cleanup;
	}

	/* multithreaded build can have multiple DB connections */
#if PTHREADS
	/* check how many db connections we should create */
	dbcount = strtol(argv[1], &endp, 10);
	if (*endp != '\0' || dbcount < 0) {
		ldap->log(ISC_LOG_ERROR,
			  "LDAP driver database connection count "
			  "must be positive.");
		goto cleanup;
	}
#endif

	/* check that LDAP URL parameters make sense */
	switch (argc) {
	case 12:
		result = ldap_checkURL(ldap, argv[11], 0,
				       "allow zone transfer");
		if (result != ISC_R_SUCCESS)
			goto cleanup;
	case 11:
		result = ldap_checkURL(ldap, argv[10], 3, "all nodes");
		if (result != ISC_R_SUCCESS)
			goto cleanup;
	case 10:
		if (strlen(argv[9]) > 0) {
			result = ldap_checkURL(ldap, argv[9], 3, "authority");
			if (result != ISC_R_SUCCESS)
				goto cleanup;
		}
	case 9:
		result = ldap_checkURL(ldap, argv[8], 3, "lookup");
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		result = ldap_checkURL(ldap, argv[7], 0, "find zone");
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		break;
	default:
		/* not really needed, should shut up compiler. */
		result = ISC_R_FAILURE;
	}

	/* store info needed to automatically re-connect. */
	ldap->protocol = protocol;
	ldap->method = method;
	ldap->hosts = strdup(argv[6]);
	if (ldap->hosts == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup;
	}
	ldap->user = strdup(argv[4]);
	if (ldap->user == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup;
	}
	ldap->cred = strdup(argv[5]);
	if (ldap->cred == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup;
	}

#if PTHREADS
	/* allocate memory for database connection list */
	ldap->db = calloc(1, sizeof(db_list_t));
	if (ldap->db == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup;
	}

	/* initialize DB connection list */
	DLZ_LIST_INIT(*(ldap->db));

	/*
	 * create the appropriate number of database instances (DBI)
	 * append each new DBI to the end of the list
	 */
	for (i = 0; i < dbcount; i++) {
#endif /* PTHREADS */
		/* how many queries were passed in from config file? */
		switch (argc) {
		case 9:
			result = build_dbinstance(NULL, NULL, NULL, argv[7],
						  argv[8], NULL, &dbi,
						  ldap->log);
			break;
		case 10:
			result = build_dbinstance(NULL, NULL, argv[9],
						  argv[7], argv[8],
						  NULL, &dbi, ldap->log);
			break;
		case 11:
			result = build_dbinstance(argv[10], NULL, argv[9],
						  argv[7], argv[8],
						  NULL, &dbi, ldap->log);
			break;
		case 12:
			result = build_dbinstance(argv[10], argv[11],
						  argv[9], argv[7],
						  argv[8], NULL, &dbi,
						  ldap->log);
			break;
		default:
			/* not really needed, should shut up compiler. */
			result = ISC_R_FAILURE;
		}

		if (result == ISC_R_SUCCESS) {
			ldap->log(ISC_LOG_DEBUG(2),
				  "LDAP driver created "
				  "database instance object.");
		} else { /* unsuccessful?, log err msg and cleanup. */
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not create "
				  "database instance object.");
			goto cleanup;
		}

#if PTHREADS
		/* when multithreaded, build a list of DBI's */
		DLZ_LINK_INIT(dbi, link);
		DLZ_LIST_APPEND(*(ldap->db), dbi, link);
#else
		/*
		 * when single threaded, hold onto the one connection
		 * instance.
		 */
		ldap->db = dbi;
#endif
		/* attempt to connect */
		result = ldap_connect(ldap, dbi);

		/*
		 * if db connection cannot be created, log err msg and
		 * cleanup.
		 */
		switch (result) {
			/* success, do nothing */
		case ISC_R_SUCCESS:
			break;
			/*
			 * no memory means ldap_init could not
			 * allocate memory
			 */
		case ISC_R_NOMEMORY:
#if PTHREADS
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not allocate memory "
				  "for connection number %u", i + 1);
#else
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not allocate memory "
				  "for connection");
#endif
			goto cleanup;
			/*
			 * no perm means ldap_set_option could not set
			 * protocol version
			 */
		case ISC_R_NOPERM:
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not "
				  "set protocol version.");
			result = ISC_R_FAILURE;
			goto cleanup;
			/* failure means couldn't connect to ldap server */
		case ISC_R_FAILURE:
#if PTHREADS
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not bind "
				  "connection number %u to server.", i + 1);
#else
			ldap->log(ISC_LOG_ERROR,
				  "LDAP driver could not "
				  "bind connection to server.");
#endif
			goto cleanup;
			/*
			 * default should never happen.  If it does,
			 * major errors.
			 */
		default:
			ldap->log(ISC_LOG_ERROR,
				  "dlz_create() failed (%d)", result);
			result = ISC_R_UNEXPECTED;
			goto cleanup;
		}

#if PTHREADS
		/* set DBI = null for next loop through. */
		dbi = NULL;
	}
#endif /* PTHREADS */

	/* set dbdata to the ldap_instance we created. */
	*dbdata = ldap;

	return (ISC_R_SUCCESS);

 cleanup:
	dlz_destroy(ldap);

	return (result);
}
Exemplo n.º 8
0
/*
 * Called to initialize the driver
 */
isc_result_t
dlz_create(const char *dlzname, unsigned int argc, char *argv[],
           void **dbdata, ...)
{
    struct dlz_example_data *state;
    const char *helper_name;
    va_list ap;
    char soa_data[1024];
    const char *extra;
    isc_result_t result;
    int n;

    UNUSED(dlzname);

    state = calloc(1, sizeof(struct dlz_example_data));
    if (state == NULL)
        return (ISC_R_NOMEMORY);

    /* Fill in the helper functions */
    va_start(ap, dbdata);
    while ((helper_name = va_arg(ap, const char *)) != NULL) {
        b9_add_helper(state, helper_name, va_arg(ap, void *));
    }
    va_end(ap);

    if (argc < 2) {
        if (state->log != NULL)
            state->log(ISC_LOG_ERROR,
                       "dlz_example: please specify a zone name");
        dlz_destroy(state);
        return (ISC_R_FAILURE);
    }

    state->zone_name = strdup(argv[1]);
    if (state->zone_name == NULL) {
        free(state);
        return (ISC_R_NOMEMORY);
    }

    if (strcmp(state->zone_name, ".") == 0)
        extra = ".root";
    else
        extra = ".";

    n = sprintf(soa_data, "%s hostmaster%s%s 123 900 600 86400 3600",
                state->zone_name, extra, state->zone_name);

    if (n < 0)
        CHECK(ISC_R_FAILURE);
    if ((unsigned)n >= sizeof(soa_data))
        CHECK(ISC_R_NOSPACE);

    add_name(state, &state->current[0], state->zone_name,
             "soa", 3600, soa_data);
    add_name(state, &state->current[0], state->zone_name,
             "ns", 3600, state->zone_name);
    add_name(state, &state->current[0], state->zone_name,
             "a", 1800, "10.53.0.1");

    if (state->log != NULL)
        state->log(ISC_LOG_INFO, "dlz_example: started for zone %s",
                   state->zone_name);

    *dbdata = state;
    return (ISC_R_SUCCESS);

failure:
    free(state);
    return (result);

}