From f2855cb6643bee0255ff99e9f832322162b1023c Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 13 Mar 2023 14:13:39 -0700 Subject: [PATCH] allow configuration of dnsrps library path for testing purposes, we need to be able to specify a library path from which to load the dnsrps implementation. this can now be done with the "dnsrps-library" option. DNSRPS can now be enabled in configure regardless of whether librpz.so is currently installed on the system. --- bin/named/config.c | 3 +++ bin/named/include/named/server.h | 15 ++++++------ bin/named/server.c | 41 +++++++++++++++++++++++++------- configure.ac | 10 ++++---- doc/arm/reference.rst | 11 ++++++++- doc/misc/options | 1 + lib/dns/dnsrps.c | 20 +++++++--------- lib/dns/include/dns/dnsrps.h | 2 +- lib/dns/include/dns/librpz.h | 8 +++---- lib/isccfg/namedconf.c | 5 ++++ 10 files changed, 76 insertions(+), 40 deletions(-) diff --git a/bin/named/config.c b/bin/named/config.c index be9724ec71..b470486df4 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -149,6 +149,9 @@ options {\n\ clients-per-query 10;\n\ dnssec-accept-expired no;\n\ dnssec-validation " VALIDATION_DEFAULT "; \n" +#ifdef USE_DNSRPS + " dnsrps-library \"" DNSRPS_LIBRPZ_PATH "\";\n" +#endif /* ifdef USE_DNSRPS */ #ifdef HAVE_DNSTAP " dnstap-identity hostname;\n" #endif /* ifdef HAVE_DNSTAP */ diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 764bd2b77d..ecaf6ca82b 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -50,16 +50,15 @@ struct named_server { char *statsfile; /*%< Statistics file name */ char *dumpfile; /*%< Dump file name */ char *secrootsfile; /*%< Secroots file name */ - char *bindkeysfile; /*%< bind.keys file name - * */ + char *bindkeysfile; /*%< bind.keys file name */ char *recfile; /*%< Recursive file name */ - bool version_set; /*%< User has set version - * */ + bool version_set; /*%< User has set version */ char *version; /*%< User-specified version */ - bool hostname_set; /*%< User has set hostname - * */ - char *hostname; /*%< User-specified hostname - * */ + bool hostname_set; /*%< User has set hostname */ + char *hostname; /*%< User-specified hostname */ +#ifdef USE_DNSRPS + char *dnsrpslib; +#endif /* ifdef USE_DNSRPS */ /* Server data structures. */ dns_loadmgr_t *loadmgr; diff --git a/bin/named/server.c b/bin/named/server.c index 67b8e1c4a9..2fdf3db112 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -2025,7 +2025,7 @@ conf_dnsrps_sadd(conf_dnsrps_ctx_t *ctx, const char *p, ...) { } /* - * Get an DNSRPS configuration value using the global and view options + * Get a DNSRPS configuration value using the global and view options * for the default. Return false upon failure. */ static bool @@ -9079,6 +9079,35 @@ load_configuration(const char *filename, named_server_t *server, server->kasplist = kasplist; kasplist = tmpkasplist; +#ifdef USE_DNSRPS + /* + * Find the path to the DNSRPS implementation library. + */ + obj = NULL; + if (named_config_get(maps, "dnsrps-library", &obj) == ISC_R_SUCCESS) { + if (server->dnsrpslib != NULL) { + dns_dnsrps_server_destroy(); + isc_mem_free(server->mctx, server->dnsrpslib); + server->dnsrpslib = NULL; + } + setstring(server, &server->dnsrpslib, cfg_obj_asstring(obj)); + result = dns_dnsrps_server_create(server->dnsrpslib); + isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, + NAMED_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), + "initializing DNSRPS RPZ provider '%s': %s", + server->dnsrpslib, isc_result_totext(result)); + /* + * It's okay if librpz isn't available. We'll complain + * later if it turns out to be needed for a view with + * "dnsrps-enable yes". + */ + if (result == ISC_R_FILENOTFOUND) { + result = ISC_R_SUCCESS; + } + CHECKFATAL(result, "initializing RPZ service interface"); + } +#endif /* ifdef USE_DNSRPS */ + /* * Configure the views. */ @@ -10135,18 +10164,13 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) { .recfile = isc_mem_strdup(mctx, "named.recursing"), }; -#ifdef USE_DNSRPS - CHECKFATAL(dns_dnsrps_server_create(), "initializing RPZ service " - "interface"); -#endif /* ifdef USE_DNSRPS */ - /* Initialize server data structures. */ ISC_LIST_INIT(server->kasplist); ISC_LIST_INIT(server->viewlist); /* Must be first. */ - CHECKFATAL(dst_lib_init(named_g_mctx, named_g_engine), "initializing " - "DST"); + CHECKFATAL(dst_lib_init(named_g_mctx, named_g_engine), + "initializing DST"); CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, &server->in_roothints), @@ -10218,6 +10242,7 @@ named_server_destroy(named_server_t **serverp) { #ifdef USE_DNSRPS dns_dnsrps_server_destroy(); + isc_mem_free(server->mctx, server->dnsrpslib); #endif /* ifdef USE_DNSRPS */ named_controls_destroy(&server->controls); diff --git a/configure.ac b/configure.ac index e0e893b50b..7ebbb0d2c5 100644 --- a/configure.ac +++ b/configure.ac @@ -1478,10 +1478,10 @@ AC_COMPILE_IFELSE( AC_ARG_ENABLE([dnsrps-dl], [AS_HELP_STRING([--enable-dnsrps-dl], [DNS Response Policy Service delayed link - [default=$librpz_dl]])], - [enable_librpz_dl="$enableval"], [enable_librpz_dl="$with_dlopen"]) + [default=yes]])], + [enable_dnsprs_dl="$enableval"], [enable_dnsrps_dl="yes"]) -AS_IF([test "$enable_librpz_dl" = "yes" -a "$with_dlopen" = "no"], +AS_IF([test "$enable_dnsprs_dl" = "yes" -a "$with_dlopen" = "no"], [AC_MSG_ERROR([DNS Response Policy Service delayed link requires dlopen to be enabled])]) # [pairwise: skip] @@ -1497,7 +1497,7 @@ AC_ARG_WITH([dnsrps-dir], [librpz_path="$withval/$librpz_name"], [librpz_path="$librpz_name"]) AC_DEFINE_UNQUOTED([DNSRPS_LIBRPZ_PATH], ["$librpz_path"], [dnsrps $librpz_name]) -AS_IF([test "$enable_librpz_dl" = "yes"], +AS_IF([test "$enable_dnsrps_dl" = "yes"], [ dnsrps_lib_open=2 ],[ @@ -1517,8 +1517,6 @@ AC_ARG_ENABLE([dnsrps], [enable_dnsrps=$enableval], [enable_dnsrps=no]) AS_IF([test "$enable_dnsrps" != "no"],[ - AS_IF([test "$dnsrps_avail" != "yes"], - [AC_MSG_ERROR([dlopen and librpz.so needed for DNSRPS])]) AS_IF([test "$dnsrps_lib_open" = "0"], [AC_MSG_ERROR([dlopen and librpz.so needed for DNSRPS])]) AC_DEFINE([USE_DNSRPS], [1], [Enable DNS Response Policy Service API]) diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index d3effe04a8..2604b6e71d 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -5110,6 +5110,15 @@ done to discover problems at the authoritative server. (DNSRPS) interface, if it has been compiled in :iscman:`named` using ``configure --enable-dnsrps``. +.. namedconf:statement:: dnsrps-library + :tags: server, security + :short: Turns on the DNS Response Policy Service (DNSRPS) interface. + + This option specifies the path to the DNSRPS provider library. Typically + this library is detected when building with ``configure --enable-dnsrps`` + and does not need to be specified in ``named.conf``; the option exists + to override the default library for testing purposes. + .. namedconf:statement:: dnsrps-options :tags: server, security :short: Provides additional RPZ configuration settings, which are passed to the DNS Response Policy Service (DNSRPS) provider library. @@ -5117,7 +5126,7 @@ done to discover problems at the authoritative server. The block provides additional RPZ configuration settings, which are passed through to the DNSRPS provider library. Multiple DNSRPS settings in an :any:`dnsrps-options` string should be - separated with semi-colons (;). The DNSRPS provider, librpz, is passed a + separated with semi-colons (;). The DNSRPS provider library is passed a configuration string consisting of the :any:`dnsrps-options` text, concatenated with settings derived from the :any:`response-policy` statement. diff --git a/doc/misc/options b/doc/misc/options index 58298adacb..e55cbdd077 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -112,6 +112,7 @@ options { dns64-server ; dnskey-sig-validity ; dnsrps-enable ; // not configured + dnsrps-library ; // not configured dnsrps-options { }; // not configured dnssec-accept-expired ; dnssec-dnskey-kskonly ; diff --git a/lib/dns/dnsrps.c b/lib/dns/dnsrps.c index c93dc1c874..a322c9900b 100644 --- a/lib/dns/dnsrps.c +++ b/lib/dns/dnsrps.c @@ -33,9 +33,9 @@ #include #include -librpz_t *librpz; +librpz_t *librpz = NULL; librpz_emsg_t librpz_lib_open_emsg; -static void *librpz_handle; +static void *librpz_handle = NULL; #define RPSDB_MAGIC ISC_MAGIC('R', 'P', 'Z', 'F') #define VALID_RPSDB(rpsdb) ((rpsdb)->common.impmagic == RPSDB_MAGIC) @@ -129,7 +129,7 @@ dnsrps_log_fnc(librpz_log_level_t level, void *ctxt, const char *buf) { * This is not thread safe, but it is called by a single thread. */ isc_result_t -dns_dnsrps_server_create(void) { +dns_dnsrps_server_create(const char *librpz_path) { librpz_emsg_t emsg; INSIST(clist == NULL); @@ -140,14 +140,9 @@ dns_dnsrps_server_create(void) { * Notice if librpz is available. */ librpz = librpz_lib_open(&librpz_lib_open_emsg, &librpz_handle, - DNSRPS_LIBRPZ_PATH); - /* - * Stop now without complaining if librpz is not available. - * Complain later if and when librpz is needed for a view with - * "dnsrps-enable yes" (including the default view). - */ + librpz_path); if (librpz == NULL) { - return (ISC_R_SUCCESS); + return (ISC_R_FILENOTFOUND); } isc_mutex_init(&dnsrps_mutex); @@ -176,7 +171,7 @@ dns_dnsrps_server_destroy(void) { librpz->clist_detach(&clist); } -#ifdef LIBRPZ_USE_DLOPEN +#if DNSRPS_LIB_OPEN == 2 if (librpz != NULL) { INSIST(librpz_handle != NULL); if (dlclose(librpz_handle) != 0) { @@ -185,8 +180,9 @@ dns_dnsrps_server_destroy(void) { "dnsrps: dlclose(): %s", dlerror()); } librpz_handle = NULL; + librpz = NULL; } -#endif /* ifdef LIBRPZ_USE_DLOPEN */ +#endif } /* diff --git a/lib/dns/include/dns/dnsrps.h b/lib/dns/include/dns/dnsrps.h index 15066f0fcb..ed297ddcc3 100644 --- a/lib/dns/include/dns/dnsrps.h +++ b/lib/dns/include/dns/dnsrps.h @@ -79,7 +79,7 @@ dns_dnsrps_type2trig(dns_rpz_type_t type); * Start dnsrps for the entire server. */ isc_result_t -dns_dnsrps_server_create(void); +dns_dnsrps_server_create(const char *librpz_path); /* * Stop dnsrps for the entire server. diff --git a/lib/dns/include/dns/librpz.h b/lib/dns/include/dns/librpz.h index c99920cb77..60496be8ee 100644 --- a/lib/dns/include/dns/librpz.h +++ b/lib/dns/include/dns/librpz.h @@ -845,7 +845,7 @@ extern librpz_0_t librpz_def_0; typedef librpz_0_t librpz_t; extern librpz_t *librpz; -#if LIBRPZ_LIB_OPEN == 2 +#if DNSRPS_LIB_OPEN == 2 #include /** @@ -932,13 +932,13 @@ librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path) { *dl_handle = NULL; } -#if LIBRPZ_LIB_OPEN == 1 +#if DNSRPS_LIB_OPEN == 1 emsg->c[0] = '\0'; return (&LIBRPZ_DEF); -#else /* if LIBRPZ_LIB_OPEN == 1 */ +#else /* if DNSRPS_LIB_OPEN == 1 */ snprintf(emsg->c, sizeof(librpz_emsg_t), "librpz not available via ./configure"); return (NULL); -#endif /* LIBRPZ_LIB_OPEN */ +#endif /* DNSRPS_LIB_OPEN */ } #endif /* LIBRPZ_LIB_OPEN */ diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index a6accd8ffd..2f0363a3a3 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1206,6 +1206,11 @@ static cfg_clausedef_t options_clauses[] = { { "datasize", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT }, { "deallocate-on-exit", NULL, CFG_CLAUSEFLAG_ANCIENT }, { "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK }, +#ifdef USE_DNSRPS + { "dnsrps-library", &cfg_type_qstring, 0 }, +#else /* ifdef USE_DNSRPS */ + { "dnsrps-library", &cfg_type_qstring, CFG_CLAUSEFLAG_NOTCONFIGURED }, +#endif /* ifdef USE_DNSRPS */ #ifdef HAVE_DNSTAP { "dnstap-output", &cfg_type_dnstapoutput, 0 }, { "dnstap-identity", &cfg_type_serverid, 0 },