docs-v4: remove duplicate dictionary info from the dictionary tutorial. `xrefs` used in tutorial to guide user to reference files including the relevant configuration files.
The RDN is expanded at request time and joined to the front of every profile DN, selecting a child object of each profile. An expansion producing nothing leaves the profile DNs unmodified.
fr_ldap_map_getvalue now drains a value iterator instead of a duplicated berval array, and the map, check and valuepair readers iterate values straight out of the result message. The map proc's synthetic dn result is replaced by the exported fr_ldap_map_getdn callback, removing fr_ldap_result_t.
lib/ldap: add fr_ldap_value_iter_t for in place value iteration
The iterator is now the single implementation of the entry walk, with fr_ldap_result_values_len, fr_ldap_str_list_afrom_result and fr_ldap_entry_value_find rewritten on top of it. Group memberships are also iterated in place, removing the duplication of every membership value during collection.
rlm_ldap: merge profile DN sources into one pooled allocation
fr_ldap_str_list_afrom_result gains leading slots the caller fills with borrowed strings, so the default, group and user profile DNs merge into a single pooled array with the user values read in place from the result message. The now unused fr_ldap_berval_to_string_list is removed.
lib/ldap: add fr_ldap_entry_value_find for in place value access
Returns the first value of an attribute referenced in place from the result message, replacing ldap_get_values_len at call sites which only read a single value. Each converted site loses several allocations and a duplicate of the value bytes.
rlm_ldap: read profile references from user and group objects
Group object DNs are collected during membership resolution, then the profile bearing groups are fetched in one search with the profile attribute presence asserted in the filter, and their profiles apply between the default and the user object's. The profile attributes are now configured per object type as user { profile_attribute } and group { profile_attribute }, applied independently, and the profile { attribute } pair is deprecated.
lib/ldap: add functions for copying result values into a string list
fr_ldap_result_values_len sums an attribute's values across every entry of a result, so fr_ldap_str_list_afrom_result can build an exactly sized string list from one pooled allocation. Values are referenced in place from the result message, the only copies made are the strings in the list.
The list tracks an append cursor and the slot reserved for the NULL terminator, so appends cost no scans and batches cost at most one reallocation. Where talloc_pooled_object is available the list, its pointer array and every appended string come from a single talloc pool.
%ldap.whoami() runs the RFC 4532 Who am I? extended operation on the module's admin connections and returns the resolved authorization identity, stripping any dn: prefix.
lib/ldap: run directory discovery during connection establishment
The rootDSE query previously ran as an ordinary trunk request, so the first requests on a fresh trunk could run before discovery results were parsed. Connections now perform discovery in a new DISCOVER state before signalling connected, and trunks always start at least one connection so referral trunk watches still fire.
rlm_ldap: add tests covering the profile search_mode matrix
Fixture profiles carry priorities running opposite to their list order so seq and bulk application order differ observably. Zero result and default-only paths are covered for both modes.
seq keeps one search per profile DN, applied in list order with the default profile first. bulk retrieves every profile with a single sorted search matching objects by DN, requiring base scope and sort_by, and auto picks bulk when both hold, otherwise seq.
lib/ldap: add helpers for retrieving sets of objects by DN
fr_ldap_directory_common_base_find resolves DNs to a covering naming context using a hash table built when the rootDSE is parsed, and fr_ldap_filter_afrom_dn_list builds the matching filter using the directory's dn_attr, which fr_ldap_directory_alloc now defaults to entryDN before discovery completes. fr_ldap_berval_to_string_list converts berval values to a NULL terminated string list carved from a single talloc pool.
Names the attribute used to match an entry's own DN in a search filter, defaulting per detected directory type (distinguishedName on Active Directory and Samba, RFC 5020 entryDN elsewhere).
lib/ldap: expose connection state machine callbacks
Callers now pass fr_ldap_connection_init, fr_ldap_trunk_connection_init and fr_ldap_connection_close directly to connection_alloc(), replacing fr_ldap_connection_state_alloc(). Trunk connections share the ttrunk's fr_ldap_directory_t, which is now allocated with the trunk so the pointer is valid when the initial connections spawn.
rlm_krb5: assume thread-safety when cross-compiling (#5903)
When cross-compiling, the autoconf test program for krb5_is_thread_safe()
cannot be run on the host. Previously this left krb5threadsafe empty,
which is incorrect for all modern krb5 builds.
Fix by defaulting to thread-safety when the test cannot be performed.
Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
cf_section_dup: descend into child sections when copying (#5904)
The iterative rewrite in 013911166c allocated a copy of each nested
section but never walked into it, so pairs and subsections inside a
duplicated section were silently dropped. Add the missing descent,
and a regression test that duplicates a section with a nested
subsection containing multiple pairs.
eap_aka_sim: fix SIM-SQN check that rejected every value (#5905)
vector_umts_from_quintuplets() validated control.SIM-SQN by comparing
vp_length against MILENAGE_SQN_SIZE. SIM-SQN is FR_TYPE_UINT64, and
vp_length is only meaningful for variable length types -- it is 0 for
numeric boxes -- so the comparison could never succeed:
Every request supplying control.SIM-SQN alongside quintuplets was
rejected. Nothing else treats the attribute as octets:
vector_umts_from_ki() reads it as vp_uint64 with no length check, and the
SQN/AK derivations further down vector_umts_from_quintuplets() read
vp_uint64 as well.
Replace the length check with a range check. SQN is 48 bits and
uint48_to_buff() silently truncates anything wider, so reject those
values rather than derive AK from a mangled SQN.
The path is reachable when the server has no local Ki and takes
quintuplets from an external source, such as vectors fetched from a 3GPP
HSS over SWx. That is also the only way to satisfy the control.SIM-SQN
requirement RESUME(recv_aka_synchronization_failure) imposes after a
peer sends AKA-Synchronization-Failure, so SQN resync could not complete.
json: skip json_object_put leak assert on json-c >= 0.19
json-c 0.19 returns 0 from json_object_put() for freed scalars and empty containers, so the return value can't identify leaked references. Fix proposed upstream in json-c/json-c#945.
Alan T. DeKok [Fri, 10 Jul 2026 13:19:14 +0000 (09:19 -0400)]
tweak doc.raddb rules
add "clean" rule, add rule for radrelay.conf
change rules so that for modules, their example configuration
is placed at the bottom of the converted file. So that the
documentation is a bit clearer.
For everything else, the example configuration is inline with the
documentation. For virtual servers, the docs say things like
"this next policy", which is confusing when the policy is at the
bottom of the file instead of in-line
eap_aka_sim: allow externally-derived CK'/IK' for EAP-AKA' (#5894)
* eap_aka_sim: allow externally-derived CK'/IK' for EAP-AKA'
In a 3GPP SWx deployment the HSS performs the EAP-AKA' key transform
itself (TS 33.402 Annex A) and returns CK'/IK' already bound to the
Access Network Identity. The server must then not derive CK'/IK' a
second time from CK/IK, or the MSK will not match the peer.
Add a per-instance config item derive_ck_ik_prime (default yes,
unchanged behavior) to the eap-aka-prime process module. When set to
no, the module reads CK'/IK' from the new control.CK-Prime /
control.IK-Prime attributes and fr_aka_sim_crypto_umts_kdf_1() skips
its local derivation.
- dictionary: add CK-Prime (284) and IK-Prime (285)
- keys: add ck_ik_prime_provided flag
- vector: add fr_aka_sim_vector_umts_ck_ik_prime_from_attrs()
- crypto: guard ck_ik_prime_derive() on the flag; add unit test
- process/eap_aka_prime: add derive_ck_ik_prime config item
* eap_aka_sim: gate external CK'/IK' on attribute presence
Per arr2036 review on #5894: drop the derive_ck_ik_prime config knob
and route the external CK'/IK' path purely on the presence of
control.CK-Prime / control.IK-Prime in the request control list.
If the operator's quintuplet source (e.g. a 3GPP HSS over SWx that
performs the RFC 5448 / TS 33.402 Annex A transform itself) populates
control.CK-Prime, the AKA' KDF reads it from there. If the attributes
are absent the module falls back to the local derivation against
control.CK / control.IK as before.
Removes:
- submodule_config entry for derive_ck_ik_prime in eap_aka_prime/base.c
- derive_ck_ik_prime field on eap_aka_sim_process_conf_t
- branch in state_machine.c that read inst->derive_ck_ik_prime
Functionally equivalent for the existing use case (eap-aka-prime site
with control.CK-Prime / control.IK-Prime populated by the quintuplet
fetch); plain EAP-AKA and EAP-AKA' without external keys are
unaffected.
* eap_aka_sim: distinguish absent vs invalid CK-Prime/IK-Prime
fr_aka_sim_vector_umts_ck_ik_prime_from_attrs() now returns three
states so the caller can tell a normal "fall back to local Annex A
derivation" path apart from a real configuration error:
0 control.CK-Prime / control.IK-Prime both present and valid;
keys->ck_ik_prime_provided is set and kdf_1 skips the local
transform.
1 Neither attribute is supplied. Logged at RDEBUG3 only (the
default AKA' path that derives CK'/IK' locally is the normal
case for most callers); the caller falls through to kdf_1 which
performs the Annex A derivation.
-1 One of the two attributes is present but the other is missing,
or either attribute has the wrong octet length. Logged at
REDEBUG (real configuration error); the state machine routes to
common_failure_notification.
Updates the eap-aka-prime state-machine branch added in the previous
commit to use the new contract (goto failure only on -1). Default
EAP-AKA' deployments that do not set CK-Prime/IK-Prime see no log
noise on a production debug level, matching pre-arr2036 behaviour
where the helper was never invoked unless derive_ck_ik_prime=no.
* eap_aka_sim: avoid duplicate control_pairs lookup for CK-Prime/IK-Prime
Per arr2036 review on #5894: pair lookups walk the request control
list, so doing them twice (once in the eap-aka-prime state machine, once
inside fr_aka_sim_vector_umts_ck_ik_prime_from_attrs) is wasteful.
The state machine now looks up control.CK-Prime and control.IK-Prime
once and passes the resulting fr_pair_t * values into the derivation
function. The helper no longer touches the control list directly; it
just classifies the two pointers (neither / one / both) and validates
the octet length when both are supplied.
Signature change in base.h matches the new contract. No behavioural
change for callers that previously got 0 / 1 / -1 returns.
* eap_aka_sim: drop unused inst declaration in send_aka_challenge_request
The only reference to inst in this RESUME was the old check on
inst->derive_ck_ik_prime, which was removed when the config knob was
dropped. -Werror=unused-variable now flags the declaration.
Alan T. DeKok [Thu, 9 Jul 2026 15:14:33 +0000 (11:14 -0400)]
We don't support DHCPv6 Reconfigure messages.
Because (a) most clients don't support it, and (b) we still need
to write the code to handle the Auth option. Which includes a
bunch of additional requirements about storing keys and replay
counters.