mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-25 02:28:53 -04:00
Update the existing test's syncplugin plugin with a new parameter indicating whether the plugin should be loaded in a view or a zone. If it doesn't match where the plugin is actually loaded, it fails the initialization. This covers the correctless of the `source` parameter of `plugin_register` API.
216 lines
5.1 KiB
C
216 lines
5.1 KiB
C
/*
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
*
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
* information regarding copyright ownership.
|
|
*/
|
|
|
|
#include <isccfg/aclconf.h>
|
|
#include <isccfg/cfg.h>
|
|
#include <isccfg/grammar.h>
|
|
|
|
#include <ns/hooks.h>
|
|
|
|
typedef struct {
|
|
isc_mem_t *mctx;
|
|
uint8_t rcode;
|
|
|
|
/*
|
|
* Plugin will bails out without altering the response if qname first
|
|
* label matches `firstlbl`.
|
|
*/
|
|
char *firstlbl;
|
|
} syncplugin_t;
|
|
|
|
#define CHECK(op) \
|
|
do { \
|
|
result = (op); \
|
|
if (result != ISC_R_SUCCESS) { \
|
|
goto cleanup; \
|
|
} \
|
|
} while (0)
|
|
|
|
static ns_hookresult_t
|
|
syncplugin__hook(void *arg, void *cbdata, isc_result_t *resp) {
|
|
query_ctx_t *qctx = (query_ctx_t *)arg;
|
|
syncplugin_t *inst = cbdata;
|
|
|
|
UNUSED(resp);
|
|
|
|
if (inst->firstlbl != NULL) {
|
|
const dns_name_t *qname = qctx->client->query.qname;
|
|
dns_label_t label;
|
|
|
|
dns_name_getlabel(qname, 0, &label);
|
|
|
|
/*
|
|
* +1 because the first label byte is the length of the label
|
|
* itself
|
|
*/
|
|
if (strncmp(inst->firstlbl, (char *)label.base + 1,
|
|
strlen(inst->firstlbl)) == 0)
|
|
{
|
|
return NS_HOOK_CONTINUE;
|
|
}
|
|
}
|
|
|
|
qctx->client->message->rcode = inst->rcode;
|
|
*resp = ns_query_done(qctx);
|
|
return NS_HOOK_RETURN;
|
|
}
|
|
|
|
static cfg_clausedef_t syncplugin__cfgclauses[] = {
|
|
{ "rcode", &cfg_type_astring, 0 },
|
|
{ "source", &cfg_type_astring, 0 },
|
|
{ "firstlbl", &cfg_type_qstring, CFG_CLAUSEFLAG_OPTIONAL }
|
|
};
|
|
|
|
static cfg_clausedef_t *syncplugin__cfgparamsclausesets[] = {
|
|
syncplugin__cfgclauses, NULL
|
|
};
|
|
|
|
static cfg_type_t syncplugin__cfgparams = {
|
|
"syncplugin-params", cfg_parse_mapbody, cfg_print_mapbody,
|
|
cfg_doc_mapbody, &cfg_rep_map, syncplugin__cfgparamsclausesets
|
|
};
|
|
|
|
static isc_result_t
|
|
syncplugin__parse_rcode(const cfg_obj_t *syncplugincfg, uint8_t *rcode) {
|
|
isc_result_t result;
|
|
const cfg_obj_t *obj = NULL;
|
|
const char *rcodestr = NULL;
|
|
|
|
result = cfg_map_get(syncplugincfg, "rcode", &obj);
|
|
if (result != ISC_R_SUCCESS) {
|
|
return result;
|
|
}
|
|
|
|
rcodestr = obj->value.string.base;
|
|
|
|
if (strcmp("servfail", rcodestr) == 0) {
|
|
*rcode = dns_rcode_servfail;
|
|
} else if (strcmp("notimp", rcodestr) == 0) {
|
|
*rcode = dns_rcode_notimp;
|
|
} else if (strcmp("noerror", rcodestr) == 0) {
|
|
*rcode = dns_rcode_noerror;
|
|
} else if (strcmp("notauth", rcodestr) == 0) {
|
|
*rcode = dns_rcode_notauth;
|
|
} else if (strcmp("notzone", rcodestr) == 0) {
|
|
*rcode = dns_rcode_notzone;
|
|
} else {
|
|
result = ISC_R_FAILURE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
isc_result_t
|
|
plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
|
|
unsigned long cfgline, isc_mem_t *mctx, void *actx,
|
|
ns_hooktable_t *hooktable, ns_hooksource_t source,
|
|
void **instp) {
|
|
isc_result_t result;
|
|
cfg_parser_t *parser = NULL;
|
|
cfg_obj_t *syncplugincfg = NULL;
|
|
const cfg_obj_t *obj = NULL;
|
|
isc_buffer_t b;
|
|
ns_hook_t hook;
|
|
syncplugin_t *inst = NULL;
|
|
char *sourcestr = NULL;
|
|
|
|
UNUSED(cfg);
|
|
UNUSED(actx);
|
|
UNUSED(source);
|
|
|
|
inst = isc_mem_get(mctx, sizeof(*inst));
|
|
*inst = (syncplugin_t){ .mctx = mctx };
|
|
*instp = inst;
|
|
|
|
CHECK(cfg_parser_create(mctx, &parser));
|
|
|
|
isc_buffer_constinit(&b, parameters, strlen(parameters));
|
|
isc_buffer_add(&b, strlen(parameters));
|
|
|
|
CHECK(cfg_parse_buffer(parser, &b, cfgfile, cfgline,
|
|
&syncplugin__cfgparams, 0, &syncplugincfg));
|
|
|
|
CHECK(syncplugin__parse_rcode(syncplugincfg, &inst->rcode));
|
|
|
|
if (cfg_map_get(syncplugincfg, "firstlbl", &obj) == ISC_R_SUCCESS) {
|
|
const char *firstlbl = cfg_obj_asstring(obj);
|
|
size_t len = strlen(firstlbl) + 1;
|
|
|
|
inst->firstlbl = isc_mem_allocate(mctx, len);
|
|
strncpy(inst->firstlbl, firstlbl, len);
|
|
}
|
|
|
|
obj = NULL;
|
|
CHECK(cfg_map_get(syncplugincfg, "source", &obj));
|
|
sourcestr = obj->value.string.base;
|
|
|
|
if (strcmp(sourcestr, "zone") == 0) {
|
|
if (source != NS_HOOKSOURCE_ZONE) {
|
|
result = ISC_R_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
} else if (strcmp(sourcestr, "view") == 0) {
|
|
if (source != NS_HOOKSOURCE_VIEW) {
|
|
result = ISC_R_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
} else {
|
|
result = ISC_R_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
hook = (ns_hook_t){ .action = syncplugin__hook, .action_data = inst };
|
|
ns_hook_add(hooktable, mctx, NS_QUERY_NXDOMAIN_BEGIN, &hook);
|
|
|
|
cleanup:
|
|
if (syncplugincfg != NULL) {
|
|
cfg_obj_destroy(parser, &syncplugincfg);
|
|
}
|
|
|
|
if (parser != NULL) {
|
|
cfg_parser_destroy(&parser);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
isc_result_t
|
|
plugin_check(const char *parameters, const void *cfg, const char *cfgfile,
|
|
unsigned long cfgline, isc_mem_t *mctx, void *actx) {
|
|
UNUSED(parameters);
|
|
UNUSED(cfg);
|
|
UNUSED(cfgfile);
|
|
UNUSED(cfgline);
|
|
UNUSED(mctx);
|
|
UNUSED(actx);
|
|
|
|
return ISC_R_SUCCESS;
|
|
}
|
|
|
|
void
|
|
plugin_destroy(void **instp) {
|
|
syncplugin_t *inst = *instp;
|
|
isc_mem_t *mctx = inst->mctx;
|
|
|
|
if (inst->firstlbl != NULL) {
|
|
isc_mem_free(mctx, inst->firstlbl);
|
|
}
|
|
|
|
isc_mem_put(mctx, inst, sizeof(*inst));
|
|
*instp = NULL;
|
|
}
|
|
|
|
int
|
|
plugin_version(void) {
|
|
return NS_PLUGIN_VERSION;
|
|
}
|