Follow-up of 38ce2906 as the size of the `cfg_obj_t` can actually goes
down to 40 bytes "for free", by using bitfields to only use 31 bits for
the `line` field, so the remaining bit can be use to hold the `cloned`
state without paying the extra 8 bytes padding.
Make all non-scalar properties of `cfg_obj_t` allocated values, which
ensures the union size is the width of one pointer. Also reorder the
fields inside `cfg_obj_t` to avoid alignment padding that would increase
the size. As a result, a `cfg_obj_t` instance is now 48 bytes on a
64-bit platform.
Add a static assertion to avoid increasing the size of the struct by
mistake.
The function `parse_sockaddrsub` was taking advantage of the fact that
both sockaddr and sockaddrtls were in the same position, and used to
initialize the sockaddr field independently if this was a -tls one or
not. This doesn't work anymore now that all fields are allocated,
so it has been slightly rewritten to take both cases into account
separately.
As the isccfg library now uses the global memory context, it is now
used directly instead of passing the parser context around to grab its
memory context.
Also remove the memory context from the parser, as well as from
`cfg_obj_t`, as it's now useless.
The parser has a static function `create_string()` used
internally. But there was duplicate code to create a string node
in `namedconf.c`. Instead of implementing the same logic twice,
`create_string()` is now publicly exposed as `cfg_string_create()`.
when merging view objects into the effective configuration, add
allow-query-cache, allow-recursion, allow-query-cache-on and
allow-recursion-on ACLs as needed to reflect the way those
options inherit from each other.
this means the effective configuration is now correct for each
view. ACLs no longer need to be corrected when applying the
configuration, and the actual effective ACL values will be
displayed in "rndc showconf" and "named-checkconf -pe".
the merging of options and defaults into the effective configuration
broke the mutual inheritance of the allow-recursion, allow-query, and
allow-query-cache ACLs, and of the allow-recursion-on and
allow-query-cache-on ACLs.
this has been corrected by adding a 'cloned' flag to the cfg_obj
structure to indicate whether it was configured explicitly or
cloned from the defaults during parsing. we can then adjust the
ACLs while configuring a view, favoring user-configured values
when they're available over cloned defaults.
currently the adjustments to the ACLs are done in configure_view();
later they'll be moved into the effective configuration and this
special handling can be removed.
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.
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.
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.
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.
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.
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.
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.
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.
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.
- 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.
- 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().
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.
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.
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.
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.
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.
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.
`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.
"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.
the function that checks zone syntax in libisccfg was previously
only called when loading named.conf, not when parsing an an
"rndc addzone" or "rndc modzone" command. this has been corrected.
note that some checks are still skipped: those that check for
duplication of filenames, key directories, etc. to fix this, we'd need
to export the symbol tables that are set up when loading named.conf and
preserve them so they could be reused later.
the isc_mem allocation functions can no longer fail; as a result,
ISC_R_NOMEMORY is now rarely used: only when an external library
such as libjson-c or libfstrm could return NULL. (even in
these cases, arguably we should assert rather than returning
ISC_R_NOMEMORY.)
code and comments that mentioned ISC_R_NOMEMORY have been
cleaned up, and the following functions have been changed to
type void, since (in most cases) the only value they could
return was ISC_R_SUCCESS:
- dns_dns64_create()
- dns_dyndb_create()
- dns_ipkeylist_resize()
- dns_kasp_create()
- dns_kasp_key_create()
- dns_keystore_create()
- dns_order_create()
- dns_order_add()
- dns_peerlist_new()
- dns_tkeyctx_create()
- dns_view_create()
- dns_zone_setorigin()
- dns_zone_setfile()
- dns_zone_setstream()
- dns_zone_getdbtype()
- dns_zone_setjournal()
- dns_zone_setkeydirectory()
- isc_lex_openstream()
- isc_portset_create()
- isc_symtab_create()
(the exception is dns_view_create(), which could have returned
other error codes in the event of a crypto library failure when
calling isc_file_sanitize(), but that should be a RUNTIME_CHECK
anyway.)
Since BIND 9 headers are not longer public, there's no reason to keep
the ISC_LANG_BEGINDECL and ISC_LANG_ENDDECL macros to support including
them from C++ projects.
the generated grammar for named.conf clauses that may or may not be
enabled at compile time will now print the same comment regardless of
whether or not they are.
previously, the grammar didn't print a comment if an option was enabled,
but printed "not configured" if it was disabled. now, in both cases,
it will say "optional (only available if configured)".
as an incidental fix, clarified the documentation for "named-checkconf -n".
The query-source option has the slight quirk of allowing the address to
be specified in two ways, either as every other source option, or as an
"address" key-value pair.
For this reason, it had a separate parsing function from other X-source
options, but it is possible to extend the parsing of other X-sources to
be generic and also handle query-source.
This commit just does that.
This commit nulls all type fields for the clausedef lists that are
declared ancient, and removes the corresponding cfg_type_t and parsing
functions when they are found to be unused after the change.
named-checkconf now takes "-n" to ignore "not configured" errors.
This allows named-checkconf to check the syntax of configurations
from other builds which have support for more options.
Remove the complicated mechanism that could be (in theory) used by
external libraries to register new categories and modules with
statically defined lists in <isc/log.h>. This is similar to what we
have done for <isc/result.h> result codes. All the libraries are now
internal to BIND 9, so we don't need to provide a mechanism to register
extra categories and modules.
As we now setup the logging very early, parsing the default config would
always print warnings about experimental (and possibly deprecated)
options in the default config. This would even mess with commands like
`named -V` and it is also wrong to warn users about using experimental
options in the default config, because they can't do anything about
this. Add CFG_PCTX_NODEPRECATED and CFG_PCTX_NOEXPERIMENTAL options
that we can pass to cfg parser and silence the early warnings caused by
using experimental options in the default config.
The OpenSSL 1.x Engines support has been deprecated in the OpenSSL 3.x
and is going to be removed. Remove the OpenSSL Engine support in favor
of OpenSSL Providers.
This is now the default way to implement attaching to/detaching from
a pointer.
Also update cfg_keystore_fromconfig() to allow NULL value for the
keystore pointer. In most cases we detach it immediately after the
function call.
If there is a keystore configured with a PKCS#11 URI, zones that
are using a dnssec-policy that uses such a keystore should create keys
via the PKCS#11 interface. Those keys are generally stored inside an
HSM.
Some changes to the code are required, to store the engine reference
into the keystore.
When creating the kasp structure, instead of storing the name of the
key store on keys, store a reference to the key store object instead.
This requires to build the keystore list prior to creating the kasp
structures, in the dnssec tools, the check code and the server code.
We will create a builtin keystore called "key-directory" which means
use the zone's key-directory as the key store.
The check code changes, because now the keystore is looked up before
creating the kasp structure (and if the keystore is not found, this
is an error). Instead of looking up the keystore after all
'dnssec-policy' clauses have been read.
Add code for configuring keystore objects. Add this to the "kaspconf"
code, as it is related to 'dnssec-policy' and it is too small to create
a separate file for it.
There are times where you want named-checkconf to check whether the
dnssec-policies should be constrained by the cryptographic algorithms
supported by the operation system or to just accept all possible
algorithms. This provides a mechanism to make that selection.