Commit graph

1127 commits

Author SHA1 Message Date
Evan Hunt
fb6939b1c5 further shrink cfg_obj_t by using a pointer for duration
not storing the isccfg_duration object inside cfg_obj reduces
its size from 80 to 72 bytes.
2025-10-30 15:17:21 -07:00
Evan Hunt
714f73d786 reduce the size of cfg_obj by using pointers for addresses
instead of having sockaddr and netaddr members in the cfg_obj->value
union, we now just keep pointers, and allocate memory when parsing
these types. this reduces the size of cfg_obj_t from 112 to 80 bytes.
2025-10-30 15:17:21 -07:00
Evan Hunt
3d618684de refactor newzones configuration
instead of using an opaque ns_cfgctx pointer to store the configuration
data to be used by addzone and modzone, there are now fields in the
dns_view object to store the view configuration and LMDB database
environment. the global configuration is now stored in the named_server
object, along with the ACL context.
2025-10-29 23:49:49 +01:00
Colin Vidal
10eb99731c parser: add VALID_CFGOBJ macro
In order to harden `cfg_obj_t` usage now the configuration tree is
manipulated in various ways (cloned, merged, etc.), this introduce the
VALID_CFGOBJ macro to check the validity of a `cfg_obj_t` node.
2025-10-29 13:55:47 -07:00
Colin Vidal
a7080db211 fix delv when using the builtin trust-anchors
Since the builtin trust-anchors are now called `builtin-trust-anchors`,
delv needs specific handling in order to be able to parse those when
they are used.

Before, delv was simply parsing a single clause (either in the case of
an overriden trust-anchors value from bindkeys file or by simply reading
the builtin value). But since the name changed, the same code can't be
shared and the builtin version is expected to be in a map.
2025-10-29 13:55:47 -07:00
Colin Vidal
7ff1b7ef21 introduce default config builtin-root-anchors
Since the effective configuration tree is a "merged" configuration tree
from the user and the default configurations, the effective configuration
provides a unique configuration tree used by apply_confiuration() to
configure the server.

However, there is one specific case where the configuration code needs
to differentiate whether the configuration originally came from the
default or the user configuration: the trust-anchors. This is because
the default trust-anchors _have_ to be those for the root zone, and the
one provided by the user can be for any zone. A check enforces this.

In order to keep this difference visible from the configuration code,
with a unique configuration tree, we now introduce a default-only
`builtin-trust-anchors` statement which holds the builtin root
trust-anchors. It can't be used from the user configuration (this would
raise an error), hence it is not documented.
2025-10-29 13:55:47 -07:00
Colin Vidal
5b7445f507 effective config: specific check-names case
There are multiple check-names options provided in the default
configuration, and they must "complete" those provided by the user.
This is now handled when building the effective tree.
2025-10-29 13:55:04 -07:00
Colin Vidal
6643345a5b effective config: specific prefetch/trigger case
The prefetch statement can be overriden by the user, but the user might
specify the prefetch without the trigger value, which needs to be
pulled from the default configuration. Handle this case by directly
getting the default value if needed from the default configuration when
building the effective configuration tree.

Also take care of keeping the values inside their bounds, and simplify
the server configuration code which then just have to read effective
configuration values.
2025-10-29 13:55:04 -07:00
Colin Vidal
1f54a9107d effective config: specific dnssec-policy case
Default dnssec-policies are not overridden by user-provided ones. Add
this specific case to make sure those are kept, and also ensure that the
default dnssec-policy is always in the first position (which is an
implicit requirement in the existing implementation).

Also simplify the server configuration code, as it only needs to build
the list of dnssec-policy based on the effective config list.
2025-10-29 13:55:04 -07:00
Colin Vidal
27c4f68dcc effective config: specific view cases
User specified views don't override default views. In particular, the
_bind/CH view is still active. However, the order is important: if the
user defines a foo/CH view, it must be able to override _bind/CH by
matching clients first (this is how the view is documented).

The server configuration code is now simpler; it only has to build the
views based on the effective view list, and only creates the _default
view if there are no explicit views created by the user.
2025-10-29 13:55:04 -07:00
Colin Vidal
a99573d648 effective config: specific options/acl cases
Implement the specific rules of ACL inheritance when buiding the
effective configuration. As those rules are directly implemented in the
configuration tree, they are removed from `apply_configuation`.
2025-10-29 13:55:04 -07:00
Colin Vidal
9d477aa3d4 add cfg_effective_config() API
Add the entry point of the logic to merge the user and the default
configuration, called cfg_effective_config(). This function takes a user
configuration and a default configuration. It internally clones the user
configuration tree, then walks through the clauses recursively applying
default values if they are missing.

The newly built configuration tree, called the effective configuration
tree, is then returned.

Currently this is just the basic mechanism which is implemented (i.e.
enable to walk from clause to clause, goes into a nested clause, and so
on). The next commits will introduce the implementation of
clause-specific merge functions in order to preserve the existing
named.conf semantics.
2025-10-29 13:55:04 -07:00
Colin Vidal
a9a0af4359 add an optional merge method on cfg_clausedef_t
In order to handle specific cases when merging configurations (i.e.
some specific clauses which require specific handling, not just
overriding values for instance), the cfg_clausedef_t includes an
optional merge method.

The merge function is NULL by default. If it is defined for a given
clause, and this clause is defined in both the user and default
configurations, the merge function is then called with both the user and
default clause instances. It's up the the implementation of that function
do to anything needed to keep the correct named.conf semantic.
2025-10-29 13:55:04 -07:00
Colin Vidal
473bbeb54b add helper API calls to manipulate maps and lists
cfg_map_addclone() is a variant of cfg_map_add which internally clones
an object and adds it to a map. It ensures that the object is an
implicit list if the map clause has the CFG_CLAUSEFLAG_MULTI set

cfg_list_addclone() clones a list (internally cloning each individual
element) and appends or preprends it to an existing target list.

Both of these will be needed to merge the default configuration
with the user configuration.
2025-10-29 13:55:04 -07:00
Colin Vidal
35c8768fde parser firstclause/nextclause API changes
In order to make upcoming configuration tree changes easier, the
cfg_map_firstclause() and _nextclause() functions have been changed
to return the clause itself rather than only the clause name.
2025-10-29 13:55:04 -07:00
Evan Hunt
cd921cc7ef fix a "max-cache-size" configuration bug
"max-cache-size default;" is allowed, according to the documentation
and the parser, but when it's configured, named crashes due to an
INSIST that the only legal string value is "unlimited". this has
been fied.

the configuration has also been simplified. previously, we checked for
max-cache-size in view and options, then determined whether to look in
the global default options based on whether the view had recursion set.
the default value set there was only applicable to views with recursion.
now, the default is an explicit "default", which affects views with
and without recursion in different ways.

the cfg type for "max-cache-size" has been changed from
cfg_type_sizeorpercent to cfg_type_maxcachesize.
2025-10-29 18:28:12 +00:00
Colin Vidal
cc91a5d1ec introduce cfg_obj_clone to clone a config tree
Introduce `cfg_obj_clone` which takes a `cfg_obj_t` node and clones it.
it allocates a new node, copies its scalar values and recursively
allocates child nodes, copying their scalar values as well and so on.

Internally, a new method `cfg_copyfunc_t` copy is added in `cfg_rep_t`,
which enables implementing a copy function specific for each
representation type a node can hold.
2025-10-27 21:33:18 +01:00
Mark Andrews
3594ad04e5 Remove unnecessary NULL checks in parser.c
In cfg_parse_buffer and cfg_parse_file 'pctx' was being checked
for being non-NULL when it was guarenteed to be non-NULL.  This
raised Coverity issues ID 637688 and ID 637689.
2025-10-28 06:28:52 +11:00
Evan Hunt
2877b57735 restore the former change_directory logging
change_directory() now lives in libisccfg. when it was moved,
the logging behavior changed: previously it had been logged
by named only, in the general logging category, and without the
named.conf filename and line number. it was not logged by
named-checkconf. this behavior has now been restored.
2025-10-23 13:01:31 -07:00
Colin Vidal
6b5246b3d2 ensure parser/cfg_obj log includes the line number
Since the `file` property of cfg_obj_t can now be null (instead of
"none"), cfg_obj_t would take a fallback flow where the line was not
logged. This fixes it.

Also, add the log line when parser_complain is called and `file` is null
(which might happend when parsing buffer only) to also include the line
number.
2025-10-23 13:01:11 -07:00
Evan Hunt
0db377da57 simplify and regularize cfg_* functions
- several functions that can no longer fail have been changed to
  type void, and unnecessary 'cleanup' sections were removed
- renamed cfg_create_obj() to cfg_obj_create(), and cfg_create_tuple()
  to cfg_tuple_create(), to match typical nomenclature.
- fixed a memory leak bug, in which an element could be removed
  from a list in delete_zoneconf() without being freed. this has
  been addressed by adding a cfg_list_unlink() function.
  list elements are now allocated based on the list they will
  be stored in, using the same mctx.
2025-10-23 13:01:10 -07:00
Evan Hunt
4f7f2dae59 simplify cfg_parser API
- the cfg_parser_create() and cfg_parser_destroy() calls are no
  longer used outside parser.c, so they are now static functions
- cfg_parser_attach(), cfg_parser_reset(), and cfg_parser_setflags()
  are no longer used at all, and have been removed.
- cfg_parser_mapadd() has been renamed for clarity to cfg_map_add().
2025-10-23 13:01:09 -07:00
Colin Vidal
d03f6e6fd4 cfg_parse_ functions internally handle the parser
Instead of (1) allocating a parser, (2) parsing a file/buffer then (3)
freeing the parser, the parser is now internally created/destroyed from
within the `cfg_parse_*` functions. This simplifies a lot the use cases,
especially around the error cases where the parser needs to be freed in
a cleanup goto.

The only trick was the parser callback mechanism, which would previously
have been set up between steps 1 and 2.  Since it's never been used for
any purpose other than the "directory" option, the chdir call has now
been moved inside the parser and the generic callback mechanism has been
removed, replacing CFG_CLAUSEFLAG_CALLBACK with CFG_CLAUSEFLAG_CHDIR.
2025-10-23 13:01:08 -07:00
Evan Hunt
6de1d0dbc4 update cfg_obj_attach/destroy
now that cfg_obj_destroy() has been simplified, we can use the
ISC_REFCOUNT macros to declare cfg_obj_attach() and _detach().
2025-10-23 13:01:02 -07:00
Colin Vidal
7706f5acec remove parser context field from cfg_obj_t
cfg_obj_t doesn't store a pointer to its a parser context anymore,
and does not depend on the parser's lifecycle. Instead, it stores a
reference to its own memory context (and in principle, each node
could have different memory context). This also slightly simplifies
the _destroy API as there is no need to pass a context through it
anymore.
2025-10-23 12:59:58 -07:00
Colin Vidal
0d8c4044ab cfg_obj_t file is now a refcounted string
In order to reduce the lifecycle dependency of a `cfg_obj_t` on its
parser, the `file` field needs its own reference count, so it isn't
deleted when the parser is.  It is now stored as a subsidiary
`cfg_obj_t` object of type string.
2025-10-23 10:57:45 -07:00
Aram Sargsyan
49b7ce9a54 Fix dnssec-keygen key collision checking for KEY rrtype keys
When generating a new key, dnssec-keygen checks for possible
key ID collisions with existing keys. The dnssec.c:findmatchingkeys()
function, which is supposed to get the list of the existing keys,
fails to do that for the existing KEY rrtype keys (i.e. generated
using 'dnssec-keygen -T KEY') because it doesn't pass down to the
dst_key_fromnamedfile() -> dst_key_read_public() functions the type
of the keys it's interested in. Fix the issue by introducing a new
function parameter which tells in which type of keys the caller is
currently interested in.
2025-10-22 09:42:43 +11:00
Evan Hunt
a373671f5e remove "bindkeys-file" option
The bindkeys-file option was only used for testing purposes, and
has now been replaced with a "-T bindkeys=<filename>" option for
named.
2025-10-12 23:37:49 -07:00
Ondřej Surý
94b4d105e8
Apply the changes from updated set_if_not_null semantic patch 2025-10-08 17:44:50 +02:00
Michał Kępień
5d8aa1673a
Remove "tkey-domain"
Since the "tkey-domain" statement has been previously obsoleted, mark it
as ancient to make any attempts to use it a fatal error.
2025-10-06 14:14:33 +02:00
Michał Kępień
84b96df153
Remove "tkey-gssapi-credential" and related code
Since the "tkey-gssapi-credential" statement has been previously
deprecated, mark it as ancient and remove all code related to it:

  - The code processing the "tkey-gssapi-credential" statement in the
    configuration is the only user of the dst_gssapi_acquirecred() and
    dst_gssapi_releasecred() functions, so remove them along with their
    static helper functions and a backup definition of the
    GSS_KRB5_MECHANISM macro.

  - When calling gss_accept_sec_context(), pass GSS_C_NO_CREDENTIAL
    instead of the credential acquired by gss_acquire_cred().
    (Previously, NULL was passed when "tkey-gssapi-credential" was not
    specified.  Kerberos headers define GSS_C_NO_CREDENTIAL as
    (gss_cred_id_t) 0, so the logic was effectively the same, but using
    the GSS_C_NO_CREDENTIAL macro is more appropriate.)  This renders
    the 'cred' parameter for dst_gssapi_acceptctx() redundant, so remove
    it from the prototype of the latter.  (Contrary to what the
    documentation for dst_gssapi_acceptctx() claims,
    dst_gssapi_releasecred() does not need to subsequently be called to
    free the GSS-API context; a dst_gssapi_deletectx() call in
    gssapi_destroy() takes care of that when the dynamically generated
    TSIG key is destroyed.)

  - Remove the 'gsscred' member from struct dns_tkeyctx, along with its
    related dns_gss_cred_id_t typedef.

Update the relevant sections of the ARM and code comments accordingly.

This makes the "tkey-gssapi-keytab" statement the only way to set up
GSS-TSIG in named.

Remove redundant code from bin/named/tkeyconf.c while at it.
2025-10-06 13:19:50 +02:00
Colin Vidal
62002cfa9c rename ns_pluginregister_ctx_t into ns_pluginctx_t
The type `ns_pluginregister_ctx_t` was initially added to pass plugin
contextual data when the plugin is registered, but this is also now
passed into `plugin_check`. Furthermore, those various data are not
specific to the registration in particular. Rename the type into
`ns_pluginctx_t` for clarity.
2025-10-01 20:20:48 +02:00
Colin Vidal
25e258fb0b provide a context structure for plugin_register()
This commit introduces a new type, ns_pluginregister_ctx_t,
which is passed to plugin_check() and plugin_register() in place of the
'source' parameter. The source value is now just part of the structure,
which also holds a pointer to the zone origin if the plugin is loaded at
a zone level.

This provides more contextual information, enabling the plugin to make
specific configuration decisions based on the name of the zone for which
it is loaded.

It's also flexible if more contextual data are needed in the future:
add a new field to ns_pluginregister_ctx_t, and new plugins can use
it without affecting compatibility with existing plugins.
2025-10-01 11:11:00 +02:00
Evan Hunt
92cefc52bc check plugin config before registering
In named_config_parsefile(), when checking the validity of
named.conf, the checking of plugin correctness was deliberately
postponed until the plugin is loaded and registered. However,
when the plugin was registered, the checking was never actually
done: the plugin_register() implementation was called, but
plugin_check() was not.

This made it necessary to duplicate the correctness checking in both
functions, so that both named-checkconf and named could catch errors.
That should not be required.

ns_plugin_register() now calls the check function before the register
function, and aborts if either one fails.  ns_plugin_check() calls only
the check function.  ns_plugin_check() is used by named-checkconf, and
ns_plugin_register() is used by named. (Note: this design has a
side effect that a call to ns_plugin_register() will result in the
plugin parameters being parsed twice at registration time.)

ns_plugin_check() now takes an additional argument for the hook
source: zone or view.
2025-09-30 15:42:26 -07:00
Colin Vidal
36a05c81b4 rename cfg_aclconfctx_t variables to aclctx
ACL configuration context variables are inconsistently named as `actx`,
`ac`, or `aclconfctx`, which caused confusion during code reviews. This
commit renames all `cfg_aclconfctx_t` variables to `aclctx`, which is
short, consistent, and unambiguous.
2025-09-24 20:14:49 +02:00
Matthijs Mekking
dcd49f2ead Change checkconf to include built-in dnssec-policy
The configuration should also take into account the built-in
DNSSEC policies when verifying the keys in the key-directory match the
given policy. Update the code accordingly and add some good and
failure test cases.
2025-09-24 17:03:06 +02:00
Matthijs Mekking
9fe520ece9 Implement named-checkconf -k (check keys)
With named-checkconf -k you can check your configuration including
checking the dnssec-policy keys against the configured keystores. If
there is a mismatch in the key files versus the policy, named-checkconf
will fail. This is useful for running before migrating to dnssec-policy.

For logging purposes, introduce a function that writes the identifying
information about a policy key into a string.

Allow a dnssec key to be initialized outside the keymgr code.

Add 'log_errors' to 'cfg_kasp_fromconfig' to avoid duplicate error
logs.
2025-09-24 17:03:06 +02:00
Colin Vidal
201f62d9ef cfg_aclconfctx_t object is part of named_server
`named_g_actconfctx` is a global variable holding the ACL configuration
context alive (in particular, to dynamically load zones). However, this
object is build once per configuration (early) and is used only inside
server.c `apply_configuration` flow. (Two exceptions: the shutdown flow,
still in server.c and plugin check flow, which doesn't need it, so it's
NULL in such case).

Instead of leaving this global publicly exposed, it is now part of the
`named_server_t` object. This allows us to clearly see that, when
reconfigureing the server, the new instance of the ACL context is known
only by the newly built object and not currently used by "production"
object; and will help to move move logic before the exclusive mode is
taken.

The other advantage is that the ACL configuration context can now be
built before the exclusive lock as well.
2025-09-24 10:54:50 +02:00
Colin Vidal
7ea70b4e19 add namedconf support for plugin inside a zone
The named.conf parser now accepts the plugin clause inside a zone
definition.  This enables us to add (in later commits) support for
zone plugins.
2025-09-09 09:42:34 +02:00
Michał Kępień
805f1c0f65
Obsolete the "tkey-domain" statement
The "tkey-domain" statement has effectively been a no-op since commit
bd4576b3ce, which removed the only bit of
code using it: the logic implementing TKEY Mode 2 (Diffie-Hellman).

A subsequent cleanup commit, 885c132f4a,
also missed the opportunity to remove the "tkey-domain" statement
altogether.

Mark the "tkey-domain" statement as obsolete and remove all code and
documentation related to it.
2025-09-01 21:35:33 +02:00
Michał Kępień
6de435c528
Deprecate the "tkey-gssapi-credential" statement
The "tkey-gssapi-keytab" statement enables GSS-TSIG to be set up in a
simpler and more reliable way than using the "tkey-gssapi-credential"
statement and setting environment variables (e.g. KRB5_KTNAME).

Mark the "tkey-gssapi-credential" statement as deprecated to eventually
only have one method for setting up GSS-TSIG in named.  Do not mention
"tkey-gssapi-credential" in the section of the ARM on dynamic updates.
2025-09-01 21:23:30 +02:00
Aram Sargsyan
41387b8d30 Add a new 'servfail-until-ready' configuration option for RPZ
By default, when named is started it may start answering to
queries before the response policy zones are completely loaded
and processed. This new feature gives an option to the users to
tell named that incoming requests should result in SERVFAIL anwser
until all the response policy zones are procesed and ready.
2025-08-22 16:31:17 +00:00
Matthijs Mekking
63c5b453e0 Add manual-mode config option
Add a new option 'manual-mode' to 'dnssec-policy'. The intended
use is that if it is enabled, it will not automatically move to the
next state transition (RUMOURED, UNRETENTIVE), only after manual
confirmation. The intended state transition should be logged.
2025-08-21 16:00:19 +02:00
Ondřej Surý
42496f3f4a
Use ControlStatementsExceptControlMacros for SpaceBeforeParens
> Put a space before opening parentheses only after control statement
> keywords (for/if/while...) except this option doesn’t apply to ForEach
> and If macros. This is useful in projects where ForEach/If macros are
> treated as function calls instead of control statements.
2025-08-19 07:58:33 +02:00
Mark Andrews
cb6903c55e Warn about deprecated DNSKEY and DS algorithms / digest types
DNSKEY algorithms RSASHA1 and RSASHA-NSEC3-SHA1 and DS digest type
SHA1 are deprecated.  Log when these are present in primary zone
files and when generating new DNSKEYs, DS and CDS records.
2025-07-15 23:53:57 +10:00
Mark Andrews
422b9118e8 Use clang-format-20 to update formatting 2025-06-25 12:44:22 +10:00
Mark Andrews
e687710dc7 Add PRIVATEOIDs for RSASHA256 and RSASHA512
Use the existing RSASHA256 and RSASHA512 implementation to provide
working PRIVATEOID example implementations.  We are using the OID
values normally associated with RSASHA256 (1.2.840.113549.1.1.11)
and RSASHA512 (1.2.840.113549.1.1.13).
2025-06-19 07:15:20 +10:00
Mark Andrews
71801ab123 Use DST algorithm values instead of dns_secalg where needed
DST algorithm and DNSSEC algorithm values are not necessarily the same
anymore: if the DNSSEC algorithm value is PRIVATEOID or PRIVATEDNS, then
the DST algorithm will be mapped to something else. The conversion is
now done correctly where necessary.
2025-06-19 07:00:53 +10:00
Mark Andrews
6fe09d85ab Support for DST_ALG_PRIVATEDNS and DST_ALG_PRIVATEOID
The algorithm values PRIVATEDNS and PRIVATEOID are placeholders,
signifying that the actual algorithm identifier is encoded into the
key data. Keys using this mechanism are now supported.

- The algorithm values PRIVATEDNS and PRIVATEOID cannot be used to
  build a key file name; dst_key_buildfilename() will assert if
  they are used.

- The DST key values for private algorithms are higher than 255.
  Since DST_ALG_MAXALG now exceeds 256, algorithm arrays that were
  previously hardcoded to size 256 have been resized.

- New mnemonic/text conversion functions have been added.
  dst_algorithm_{fromtext,totext,format} can handle algorithm
  identifiers encoded in PRIVATEDNS and PRIVATEOID keys, as well
  as the traditional algorithm identifiers. (Note: The existing
  dns_secalg_{fromtext,totext,format} functions are similar, but
  do *not* support PRIVATEDNS and PRIVATEOID. In most cases, the
  new functions have taken the place of the old ones, but in a few
  cases the old version is still appropriate.)

- dns_private{oid,dns}_{fromtext,totext,format} converts between
  DST algorithm values and the mnemonic strings for algorithms
  implemented using PRIVATEDNS or PRIVATEOID. (E.g., "RSASHA256OID").

- dst_algorithm_tosecalg() returns the DNSSEC algorithm identifier
  that applies for a given DST algorithm.  For PRIVATEDNS- or
  PRIVATEOID- based algorithms, the result will be PRIVATEDNS or
  PRIVATEOID, respectively.

- dst_algorithm_fromprivatedns() and dst_algorithm_fromprivateoid()
  return the DST algorithm identifier for an encoded algorithm in
  wire format, represented as in DNS name or an object identifier,
  respectively.

- dst_algorithm_fromdata() is a front-end for the above; it extracts
  the private algorithm identifier encoded at the begining of a
  block of key or signature data, and returns the matching DST
  algorithm number.

- dst_key_fromdns() and dst_key_frombuffer() now work with keys
  that have PRIVATEDNS and PRIVATEOID algorithm identifiers at the
  beginning.
2025-06-19 07:00:53 +10:00
Evan Hunt
1a24dfcddf Clean up CFG_ZONE_DELEGATION
"type delegation-only" has been obsolete for some time
(see #3953) but the zone type flag for it was still defined
in libisccfg. It has now been removed.
2025-06-12 17:46:14 -07:00