]> git.ipfire.org Git - thirdparty/freeradius-server.git/log
thirdparty/freeradius-server.git
40 hours agolisten: disarm the timers when closing a virtual listener developer/arr2036 master
Arran Cudbard-Bell [Tue, 28 Jul 2026 01:07:22 +0000 (19:07 -0600)] 
listen: disarm the timers when closing a virtual listener

proto_load_step and proto_cron_crontab drive themselves from timers rather than from their fd, and neither had a close callback, so nothing stopped them when the listener was closed. The load generator kept manufacturing packets and handing them to fr_network_send_request() after the network had signalled the workers to close, which the assert added there caught.

Both now close the fd and remove their timer.  Of the remaining app_io modules with timers, proto_detail_file, proto_detail_work and proto_ldap_sync_ldap have a close callback that does not obviously disarm anything, and are worth a look.

40 hours agoconfigure: fix the valgrind.h header check path
Arran Cudbard-Bell [Mon, 27 Jul 2026 14:57:45 +0000 (08:57 -0600)] 
configure: fix the valgrind.h header check path

53bfbf591b updated configure.ac from valgrind.h to valgrind/valgrind.h, but hand-edited the generated configure rather than regenerating it, and typo'd the path as "valgind/valgrind.h". The cache variable name is spelled correctly, so only the check itself was broken.

HAVE_VALGRIND_VALGRIND_H has therefore been undefined since, which means RUNNING_ON_VALGRIND falls back to the 0 stub: dl.c dlcloses modules even under valgrind, losing the symbols of unloaded code, and radiusd -Xxv reports runtime-valgrind as false while running under it.

40 hours agoio: stop queueing requests to workers once the close has been signalled
Arran Cudbard-Bell [Mon, 27 Jul 2026 06:59:28 +0000 (00:59 -0600)] 
io: stop queueing requests to workers once the close has been signalled

worker.c asserts that the network adds nothing to a channel after FR_CHANNEL_CLOSE, but nothing enforced it. A packet queued between the signal and the worker acking is discarded by the worker without a reply, so the network never decrements the socket's outstanding count for it, and the socket can then never be freed.

nr->exiting is now set before the workers are signalled rather than after, and fr_network_send_request() - the single funnel all three senders go through - asserts it is clear. The listeners are closed before the signal, so a socket read cannot reach there; anything that does is a path worth seeing a backtrace for, and release builds still just drop the packet.

40 hours agoio: hand back requests still queued when a responder closes its channel
Arran Cudbard-Bell [Mon, 27 Jul 2026 06:53:09 +0000 (00:53 -0600)] 
io: hand back requests still queued when a responder closes its channel

The worker cancelled the requests it had already popped, but anything still sitting in the channel's atomic queue was abandoned: after the ack the channel is gone, so those messages were never marked done, and the ring buffer they came from could not be reclaimed.

fr_channel_responder_discard() drains what is left and marks it done, called just before the ack. It is a safety net rather than a fix, and warns when it finds anything: the network is not supposed to enqueue once it has signalled the close, which is what worker.c's own "Network added messages to channel after sending FR_CHANNEL_CLOSE" assert claims, and a discarded request produces no reply, so the network never decrements its outstanding count for it and the socket cannot be freed regardless.

40 hours agoio: free the network sockets only once the workers have acked the close
Arran Cudbard-Bell [Mon, 27 Jul 2026 06:02:35 +0000 (00:02 -0600)] 
io: free the network sockets only once the workers have acked the close

A socket's message set backs every request queued to a worker, so freeing the socket while a worker still holds one leaves it reading poisoned memory: it faults in worker_request_bootstrap() on a cd->listen of 0x4242424242424242, which is non-canonical and so presents as a GPF rather than an ordinary SIGSEGV. fr_network_destroy() now closes the sockets and leaves them allocated, and fr_network() frees them after its loop, which already runs until every worker has acked for the same reason.

The reply drain stays where it was, before the workers are signalled, because that side of the ordering is the mirror image: replies live in the workers' message sets, which they free as they exit, so we have to be finished with those first.

40 hours agoio: separate closing a network socket from freeing it
Arran Cudbard-Bell [Mon, 27 Jul 2026 05:34:13 +0000 (23:34 -0600)] 
io: separate closing a network socket from freeing it

Freeing a socket frees s->ms, but the workers hold messages allocated from it until they ack the channel close, so the descriptor and the memory cannot share a lifetime. network_socket_close() takes the event removal and the close, the destructor asserts it has already run, and the socket keeps the handle fr_event_fd_insert() gave it rather than tracking whether it has one.

The event is now parented off the socket rather than the network, so it cannot outlive the socket that owns the handle even if a path forgets to close. fr_network_socket_dead() closes up front, since nothing writes to a dead socket, and the remaining free sites close immediately beforehand, so the descriptor is released no later than before. fr_network_destroy() is still wrong - it frees the sockets before signalling the workers at all - but it no longer zeroes s->outstanding to hide it.

40 hours agoci: gate the automatic merge on the DEB, RPM and sanitizer legs too
Arran Cudbard-Bell [Mon, 27 Jul 2026 00:10:21 +0000 (18:10 -0600)] 
ci: gate the automatic merge on the DEB, RPM and sanitizer legs too

The merge ran as a job at the end of CI with needs: ci, which only waited for CI itself because needs: cannot reach jobs in another workflow. A red DEB, RPM or sanitizer leg did not stop a developer branch reaching master.

Moved to its own workflow_run workflow instead. That fires once per gating workflow completion rather than once when they have all finished, so it runs several times per commit and does nothing until the last leg lands, which avoids a job sitting in a poll loop holding a runner. It now merges the commit the workflows ran on rather than the branch ref, so a branch that moved on since cannot put an unvalidated commit onto master.

47 hours agosupport CONF_FLAG_REF in radmod2json developer/alandekok
Alan T. DeKok [Mon, 27 Jul 2026 19:04:07 +0000 (15:04 -0400)] 
support CONF_FLAG_REF in radmod2json

47 hours agoallow for CF_IDENT_ANY in radmod2json
Alan T. DeKok [Mon, 27 Jul 2026 18:58:00 +0000 (14:58 -0400)] 
allow for CF_IDENT_ANY in radmod2json

2 days agoadd wrappers for rad*2json binaries
Alan T. DeKok [Mon, 27 Jul 2026 13:56:11 +0000 (09:56 -0400)] 
add wrappers for rad*2json binaries

2 days agocall unlang_global_init() to get the xlat tree registered
Alan T. DeKok [Mon, 27 Jul 2026 13:51:10 +0000 (09:51 -0400)] 
call unlang_global_init() to get the xlat tree registered

2 days agoignore fuzzer corpus directories
Alan T. DeKok [Mon, 27 Jul 2026 13:00:56 +0000 (09:00 -0400)] 
ignore fuzzer corpus directories

we track the tar files, not the directories

2 days agoignore auto-generated fuzzer files
Alan T. DeKok [Mon, 27 Jul 2026 12:58:47 +0000 (08:58 -0400)] 
ignore auto-generated fuzzer files

2 days agoignore editor tmp files and pycache, etc.
Alan T. DeKok [Mon, 27 Jul 2026 12:58:24 +0000 (08:58 -0400)] 
ignore editor tmp files and pycache, etc.

2 days agoconnection: expose is_closed so a closed connection's handle can't be used
Arran Cudbard-Bell [Sun, 26 Jul 2026 22:13:49 +0000 (16:13 -0600)] 
connection: expose is_closed so a closed connection's handle can't be used

The close callback frees the handle, but is_closed lived in the private struct so drivers had no way to tell a live connection from a dead one. A mysql connection dying mid-query aborted on talloc_get_type_abort() in sql_error(), reached from sql_get_map_list_resume() after the trunk had already closed the connection.

rlm_sql_print_error() is the only caller of driver->sql_error, and every driver reads the errors off the handle, so the check goes there once and reports "Connection closed" rather than in each driver.

2 days agoio: stop resignalling a channel end we have told to close
Arran Cudbard-Bell [Sun, 26 Jul 2026 16:31:41 +0000 (10:31 -0600)] 
io: stop resignalling a channel end we have told to close

3 days agotransition to new trunk state when a connection changes state
Alan T. DeKok [Sun, 26 Jul 2026 15:56:14 +0000 (11:56 -0400)] 
transition to new trunk state when a connection changes state

and add tests

3 days agoadd new trunk states FULL and FAILED.
Alan T. DeKok [Sun, 26 Jul 2026 15:29:30 +0000 (11:29 -0400)] 
add new trunk states FULL and FAILED.

for when the trunk can accept no more input, due to it being
either at capacity, or if all connections have failed

3 days agomove trunk state update code into common function
Alan T. DeKok [Sun, 26 Jul 2026 15:25:05 +0000 (11:25 -0400)] 
move trunk state update code into common function

so that it can be re-used when a connection state changes

3 days agoclarify comment
Alan T. DeKok [Sun, 26 Jul 2026 15:24:52 +0000 (11:24 -0400)] 
clarify comment

3 days agodetermine dictionary for virtual modules
Alan T. DeKok [Sun, 26 Jul 2026 15:06:38 +0000 (11:06 -0400)] 
determine dictionary for virtual modules

by walking through the entire block, not just the top-level ones.
this makes the function more robust for things like redundant
containing load-balance.

3 days agomove log iterator to header file
Alan T. DeKok [Sun, 26 Jul 2026 15:05:42 +0000 (11:05 -0400)] 
move log iterator to header file

3 days agocache load-balance children in an array, and use "power of two"
Alan T. DeKok [Sun, 26 Jul 2026 15:02:43 +0000 (11:02 -0400)] 
cache load-balance children in an array, and use "power of two"

so that we don't need to walk the array each time

3 days agoadd function to export internal thread-specific tracking information
Alan T. DeKok [Sun, 26 Jul 2026 15:01:53 +0000 (11:01 -0400)] 
add function to export internal thread-specific tracking information

3 days agouse macro instead of hand-rolled loop
Alan T. DeKok [Sun, 26 Jul 2026 14:27:40 +0000 (10:27 -0400)] 
use macro instead of hand-rolled loop

3 days agorename perf counters and tweak fields for instructions
Alan T. DeKok [Sun, 26 Jul 2026 10:31:11 +0000 (06:31 -0400)] 
rename perf counters and tweak fields for instructions

so that the number of "active" users of this instruction also
include yielded ones.

We need this functionality for better load balancing

3 days agomove extension checks to table for binary search
Alan T. DeKok [Sat, 25 Jul 2026 23:36:04 +0000 (19:36 -0400)] 
move extension checks to table for binary search

and add documentation files

3 days agomulti-server: never publish profiling results from an unclean valgrind exit
Arran Cudbard-Bell [Sun, 26 Jul 2026 02:00:56 +0000 (20:00 -0600)] 
multi-server: never publish profiling results from an unclean valgrind exit

Run 30180044334 published results from two suites where valgrind had killed
FreeRADIUS partway through. Callgrind output from a killed run is truncated at
whatever point it died, so the numbers are not comparable with a clean run, and
publishing them poisons the per-suite history the regression gate compares
against.

start_valgrind_profiling.sh now records valgrind's exit status in
valgrind-exit-status alongside the rest of a test's results, and says loudly
when the status means a signal. The status is written for clean runs too, so an
absent file means the wrapper never got that far rather than that the run was
fine.

publish-profiling-results.sh refuses to publish when any test's status is
non-zero, naming each suite and status, and exits non-zero so the leg goes red
rather than passing having uploaded nothing. Trees with no status file at all
publish as before.

The status file is small and travels with the results, so the store keeps the
provenance of every published run.

3 days agoci: collect core dumps as artifacts, keep them out of the profiling publish
Arran Cudbard-Bell [Sun, 26 Jul 2026 01:19:53 +0000 (19:19 -0600)] 
ci: collect core dumps as artifacts, keep them out of the profiling publish

Most suites run with allow_core_dumps = yes, but nothing in CI ever collected
a core, so the only record of a crash the logs cannot reconstruct was thrown
away with the runner.

scripts/ci/collect-core-dumps.sh stages cores into ci-core-dumps/, preserving
each path below the searched root so the suite that crashed stays identifiable.
The new .github/actions/collect-core-dumps composite action calls the script and
uploads the result, and ci, ci-sanitizers, ci-macos, ci-deb, ci-rpm and
ci-multi-server-tests all use it. Collection runs on success as well as failure:
FreeRADIUS crashing during shutdown does not necessarily fail the suite that
provoked the crash, which is how run 30180044334 reported success while dumping
two 1.5G cores.

publish-profiling-results.sh now drops cores from the store tarball. Those two
cores turned a 6M publish into 35M of mostly-zero pages, the store's synchronous
ingest then ran ~64s, and wproxy's 60s proxy_read_timeout returned a 504 for a
publish that had in fact landed. The multi-server leg passes move: true so a
core leaves prof-results/ and rides one artifact rather than inflating the
prof-results artifact too. Exclusions are always logged with their sizes; a
silently shrunk publish would be worse than a noisy one.

The shared name patterns live in scripts/ci/core-dump-names.inc so the script
that keeps cores and the script that drops them cannot disagree.

Not covered: ci-freebsd, whose VM syncs runner-to-vm only, and the fuzzing leg,
which has its own crash artifacts. Whether a core is written at all still
depends on the ambient RLIMIT_CORE and kernel.core_pattern, neither of which CI
sets; allow_core_dumps only restores the limit FreeRADIUS inherited.

3 days agobuild: categorise library targets via TGT_CATEGORY
Arran Cudbard-Bell [Sun, 26 Jul 2026 00:26:08 +0000 (18:26 -0600)] 
build: categorise library targets via TGT_CATEGORY

Library-producing makefile fragments declare a category next to
TARGET: lib-protocol for the wire codecs under src/protocols, and
lib-util for the other support libraries.  Modules, listeners and
binaries stay uncategorised for now.

One declaration per fragment, placed after the last TARGET
assignment or probe include and outside any conditional, so the
fragment's own value wins over one dragged in by textually including
another fragment (the configure-probe pattern used by rlm_json and
friends).  Fragments which probe but aren't libraries keep a bare
'TGT_CATEGORY :=' reset for the same reason.  Configure-generated
fragments carry the declaration in their all.mk.in template.

boiler.mk only gains generic plumbing: the TGT_CATEGORY passthrough
and a CATEGORY_TARGETS macro which expands to all targets in the
given categories.

'make library.list' prints '<category> <name>' pairs - the first
authoritative list of the libraries the build produces, usable to
keep the debian/redhat packaging manifests honest.  Census:
14 lib-protocol, 18 lib-util.

src/stats/all.mk now derives the radict chain-load dependencies from
CATEGORY_TARGETS instead of name-prefix filtering ALL_TGTS.

3 days agoCorrectly record dl errors
Arran Cudbard-Bell [Sun, 26 Jul 2026 00:10:43 +0000 (18:10 -0600)] 
Correctly record dl errors

3 days agobuild: stats generation depends on the dhcpv4/dhcpv6 libraries
Arran Cudbard-Bell [Sat, 25 Jul 2026 23:47:50 +0000 (17:47 -0600)] 
build: stats generation depends on the dhcpv4/dhcpv6 libraries

radict chain-loads the DHCPv4 and DHCPv6 dictionary validation
libraries while parsing the RADIUS dictionaries (dictionary.rfc9445
has ref=@DHCPv4 / ref=@DHCPv6), but the DICT_STATS rules only
depended on libfreeradius-radius and radict itself, so a parallel
build could run radict before those libraries were linked and fail
with "cannot open shared object file", as seen intermittently on the
rocky10 service image build.

3 days agoradiusd: only SIGTERM the process group when we lead it
Arran Cudbard-Bell [Sat, 25 Jul 2026 22:40:48 +0000 (16:40 -0600)] 
radiusd: only SIGTERM the process group when we lead it

The shutdown group-wide SIGTERM exists to reap children left over
from exec calls and triggers.  When radiusd is daemonized (setsid),
or given its own group by systemd or a container runtime, the group
contains only radiusd and its children and the signal is safe.  Run
in the foreground from a shell, the group belongs to the shell, and
the signal killed the shell and its terminal too.

3 days agomulti-server: drive proto_load with max_requests / on_complete
Arran Cudbard-Bell [Sat, 25 Jul 2026 22:40:48 +0000 (16:40 -0600)] 
multi-server: drive proto_load with max_requests / on_complete

The listen configs previously set 'num_messages' inside step { },
which nothing parsed, and relied on the wall-clock ramp to produce
the expected packet count - a few skipped timer slots on a loaded CI
runner meant fewer packets than the consumers expected, and flaky
kafka-produce failures.

Point the new max_requests knob at the per-test count and rename the
env var TEST_LOADGEN_NUM_MESSAGES to TEST_LOADGEN_MAX_REQUESTS to
match.  on_complete = stop keeps the servers running for the rest of
each test.

3 days agoproto_load: replace 'repeat' with 'on_complete', add 'max_requests'
Arran Cudbard-Bell [Sat, 25 Jul 2026 22:40:35 +0000 (16:40 -0600)] 
proto_load: replace 'repeat' with 'on_complete', add 'max_requests'

The load test is now complete when the PPS ramp has passed max_pps,
max_requests packets (if set) have been sent, and every reply has
arrived.  With max_requests set the generator holds the rate at
max_pps after the ramp instead of stopping, so tests get an exact,
predictable packet count even when a busy machine makes the timer
skip send slots.

on_complete = (exit|repeat|stop|continue) replaces the undocumented
'repeat' knob and controls what happens on completion.  The default
'exit' terminates the server.  'continue' holds at max_pps forever
and cannot be combined with max_requests.

Completion is also now signalled when the final reply arrives before
the generator stops sending - previously that race left the listener
waiting forever.

3 days agoscripts/docker: snapshot dnf mirrorlists at image build time
Arran Cudbard-Bell [Sat, 25 Jul 2026 22:27:59 +0000 (16:27 -0600)] 
scripts/docker: snapshot dnf mirrorlists at image build time

The mirrors.rockylinux.org / mirrors.fedoraproject.org redirectors
occasionally answer with an empty mirror set, which dnf reports as "No
URLs in mirrorlist" and treats as fatal rather than retryable, so each
mirror list is now fetched once at image build time into
/etc/dnf/mirrorlists/<repo> and the enabled repos point at the
snapshot with mirrorlist=file:// (explicitly supported by librepo,
mirrors tried in file order). The origin CDN leads each snapshot so
the fetched mirrors are failover only, minor-versioned paths are
rewritten to the major-version symlink form so a snapshot survives
point releases, and the unused metalink-only epel-cisco-openh264 repo
is disabled.

3 days agopolicy: filter_username rejects User-Names containing an xlat opener
Arran Cudbard-Bell [Sat, 25 Jul 2026 18:37:59 +0000 (12:37 -0600)] 
policy: filter_username rejects User-Names containing an xlat opener

Reject the '%{' and '%name(' expansion openers in User-Name so there's no chance of poorly written API code reflecting them back and having nested evaluation occur.

This is a belt and braces change, as expansion defaults to disabled in v4 for the rest module, and it's somewhat unlikely that an admin woul insert one of these raw values into an SQL policy.  It's probably unecessary but at least it quiets the CVE farmers.

4 days agorlm_rest: tests for the response do_xlat and is_json defaults
Arran Cudbard-Bell [Sat, 25 Jul 2026 17:24:56 +0000 (11:24 -0600)] 
rlm_rest: tests for the response do_xlat and is_json defaults

Covers the JSON decoder (default off, do_xlat = yes, per-attribute
overrides in both directions, nested JSON with and without is_json)
and the POST decoder (default off, do_xlat = yes).

The mock API gains a /user/<username>/expand/ JSON endpoint and a
/post/expand reflector, both returning values containing xlat
expansions so the tests can verify whether the server expanded them.

4 days agoraddb: document rlm_rest response json {} and post {} subsections
Arran Cudbard-Bell [Sat, 25 Jul 2026 17:24:45 +0000 (11:24 -0600)] 
raddb: document rlm_rest response json {} and post {} subsections

The response returned by a REST API is a policy evaluated by the
server.  Expansion of values in responses is now disabled by default,
and should only be enabled where the API validates or escapes
untrusted input echoed back in the policy it returns.

Notes that configurations migrated from v3, where expansion was
enabled by default, must set do_xlat = yes if they rely on it.

4 days agorlm_rest: add response json {} and post {} config subsections
Arran Cudbard-Bell [Sat, 25 Jul 2026 17:22:51 +0000 (11:22 -0600)] 
rlm_rest: add response json {} and post {} config subsections

json { do_xlat, is_json } sets the defaults for the matching
per-attribute flags in JSON responses.  post { do_xlat } controls
xlat expansion of values in POST responses, which was previously
unconditional.

Unlike v3, do_xlat defaults to no.  The REST API must opt in to
expansion, either per decoder in the config, or with the
per-attribute do_xlat flag, which overrides the configured default
in both directions.

5 days agoload all subdirectories, so we don't have to manually list them
Alan T. DeKok [Fri, 24 Jul 2026 15:25:06 +0000 (17:25 +0200)] 
load all subdirectories, so we don't have to manually list them

6 days ago%log.destination() doesn't _require_ a file.
Alan T. DeKok [Thu, 23 Jul 2026 11:29:15 +0000 (13:29 +0200)] 
%log.destination() doesn't _require_ a file.

6 days agoword wrap log documentation
Alan T. DeKok [Thu, 23 Jul 2026 11:22:56 +0000 (13:22 +0200)] 
word wrap log documentation

6 days agouse consistent names and macros
Alan T. DeKok [Thu, 23 Jul 2026 10:56:36 +0000 (12:56 +0200)] 
use consistent names and macros

7 days agoradtest: allow overriding NAS name via HOSTNAME env var (#5901)
Alexandru Ardelean [Wed, 22 Jul 2026 15:54:02 +0000 (18:54 +0300)] 
radtest: allow overriding NAS name via HOSTNAME env var (#5901)

Use HOSTNAME when set, retaining the portable hostname/uname fallback.

Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
7 days agodocs-v4: remove duplicate dictionary info from the dictionary tutorial. `xrefs` used...
nolade [Mon, 20 Jul 2026 18:01:11 +0000 (14:01 -0400)] 
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.

7 days agofix typos in doxygen descriptions
Alan T. DeKok [Mon, 20 Jul 2026 07:44:24 +0000 (09:44 +0200)] 
fix typos in doxygen descriptions

7 days agoremove duplicated code
Alan T. DeKok [Fri, 17 Jul 2026 13:19:15 +0000 (09:19 -0400)] 
remove duplicated code

11 days agorlm_ldap: add profile child_rdn
Arran Cudbard-Bell [Fri, 17 Jul 2026 22:24:43 +0000 (18:24 -0400)] 
rlm_ldap: add profile child_rdn

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.

11 days agolib/ldap: parse naming contexts into a pooled string list
Arran Cudbard-Bell [Fri, 17 Jul 2026 22:24:42 +0000 (18:24 -0400)] 
lib/ldap: parse naming contexts into a pooled string list

One allocation now covers the pointer array and the strings. Parse failures are warned about instead of being silently ignored.

11 days agoutil: add talloc_str_array_len for NULL terminated string arrays
Arran Cudbard-Bell [Fri, 17 Jul 2026 22:24:42 +0000 (18:24 -0400)] 
util: add talloc_str_array_len for NULL terminated string arrays

Reads the string count from the talloc array header instead of walking the array.

11 days agolib/ldap: map attribute values in place
Arran Cudbard-Bell [Fri, 17 Jul 2026 19:35:16 +0000 (15:35 -0400)] 
lib/ldap: map attribute values in place

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.

11 days agolib/ldap: add fr_ldap_value_iter_t for in place value iteration
Arran Cudbard-Bell [Fri, 17 Jul 2026 19:01:55 +0000 (15:01 -0400)] 
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.

11 days agorlm_ldap: merge profile DN sources into one pooled allocation
Arran Cudbard-Bell [Fri, 17 Jul 2026 18:49:49 +0000 (14:49 -0400)] 
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.

12 days agolib/ldap: add fr_ldap_entry_value_find for in place value access
Arran Cudbard-Bell [Fri, 17 Jul 2026 18:01:30 +0000 (14:01 -0400)] 
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.

12 days agorlm_ldap: read profile references from user and group objects
Arran Cudbard-Bell [Fri, 17 Jul 2026 17:02:28 +0000 (13:02 -0400)] 
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.

12 days agolib/ldap: add functions for copying result values into a string list
Arran Cudbard-Bell [Fri, 17 Jul 2026 15:31:15 +0000 (11:31 -0400)] 
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.

12 days agoutil: add talloc_str_list_t string list functions
Arran Cudbard-Bell [Fri, 17 Jul 2026 15:30:26 +0000 (11:30 -0400)] 
util: add talloc_str_list_t string list functions

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.

12 days agorlm_ldap: add whoami xlat
Arran Cudbard-Bell [Fri, 17 Jul 2026 02:20:33 +0000 (22:20 -0400)] 
rlm_ldap: add whoami xlat

%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.

12 days agoadd TCP tests for radclient
Alan T. DeKok [Fri, 17 Jul 2026 12:37:25 +0000 (08:37 -0400)] 
add TCP tests for radclient

which test both the client functionality and the server

12 days agotreat "fail assigning ID" on fixed ID as permanent error
Alan T. DeKok [Fri, 17 Jul 2026 12:36:25 +0000 (08:36 -0400)] 
treat "fail assigning ID" on fixed ID as permanent error

12 days agocheck for more corner cases in radius tracking list
Alan T. DeKok [Fri, 17 Jul 2026 12:36:02 +0000 (08:36 -0400)] 
check for more corner cases in radius tracking list

12 days agomore descriptive errors in radclient
Alan T. DeKok [Thu, 16 Jul 2026 23:43:39 +0000 (19:43 -0400)] 
more descriptive errors in radclient

12 days agoinitialize length and use correct checks
Alan T. DeKok [Thu, 16 Jul 2026 23:35:27 +0000 (19:35 -0400)] 
initialize length and use correct checks

12 days agocorrectly set output for partial reads
Alan T. DeKok [Thu, 16 Jul 2026 23:35:00 +0000 (19:35 -0400)] 
correctly set output for partial reads

12 days agoprint out useful errors in radclient
Alan T. DeKok [Thu, 16 Jul 2026 23:10:49 +0000 (19:10 -0400)] 
print out useful errors in radclient

12 days agofix typo
Alan T. DeKok [Thu, 16 Jul 2026 23:10:40 +0000 (19:10 -0400)] 
fix typo

12 days agomake cf_pair_replace_or_add() take "const"
Alan T. DeKok [Thu, 16 Jul 2026 20:22:53 +0000 (16:22 -0400)] 
make cf_pair_replace_or_add() take "const"

which is friendlier to the callers

12 days agomash dynamic client flag in child listeners
Alan T. DeKok [Thu, 16 Jul 2026 20:03:00 +0000 (16:03 -0400)] 
mash dynamic client flag in child listeners

so that they don't check the list of networks.  All of the network
and dynamic client checks are handled by the parent listener

12 days agolib/ldap: run directory discovery during connection establishment
Arran Cudbard-Bell [Fri, 17 Jul 2026 00:15:38 +0000 (20:15 -0400)] 
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.

12 days agorlm_ldap: add tests covering the profile search_mode matrix
Arran Cudbard-Bell [Thu, 16 Jul 2026 22:22:32 +0000 (18:22 -0400)] 
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.

12 days agorlm_ldap: add profile search_mode option
Arran Cudbard-Bell [Thu, 16 Jul 2026 22:22:31 +0000 (18:22 -0400)] 
rlm_ldap: add profile search_mode option

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.

12 days agolib/ldap: add helpers for retrieving sets of objects by DN
Arran Cudbard-Bell [Thu, 16 Jul 2026 22:22:31 +0000 (18:22 -0400)] 
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.

12 days agorlm_ldap: add dn_attribute config option
Arran Cudbard-Bell [Thu, 16 Jul 2026 18:45:57 +0000 (14:45 -0400)] 
rlm_ldap: add dn_attribute config option

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).

12 days agolib/ldap: expose connection state machine callbacks
Arran Cudbard-Bell [Thu, 16 Jul 2026 18:45:14 +0000 (14:45 -0400)] 
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.

12 days agotweak use of "use_connected"
Alan T. DeKok [Thu, 16 Jul 2026 20:12:18 +0000 (16:12 -0400)] 
tweak use of "use_connected"

13 days agoci: publish profiling results to cinfra-ca.inkbridge.io (#5902)
Marc-Andre Casavant [Thu, 16 Jul 2026 15:46:53 +0000 (11:46 -0400)] 
ci: publish profiling results to cinfra-ca.inkbridge.io (#5902)

* ci: publish profiling results to cinfra-ca.inkbridge.io/profiling/data

* ci: address review feedback on the profiling publish (#5902)

* ci: check profiling results of latest vs previous

13 days agorlm_krb5: assume thread-safety when cross-compiling (#5903)
Alexandru Ardelean [Thu, 16 Jul 2026 13:52:33 +0000 (16:52 +0300)] 
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>
13 days agocf_section_dup: descend into child sections when copying (#5904)
Ethan Thompson [Thu, 16 Jul 2026 12:25:30 +0000 (08:25 -0400)] 
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.

13 days agoeap_aka_sim: fix SIM-SQN check that rejected every value (#5905)
Pau Nadeu [Thu, 16 Jul 2026 12:23:37 +0000 (15:23 +0300)] 
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:

    control.SIM-SQN incorrect length.  Expected 6 bytes, got 0 bytes
    Failed retrieving UMTS vectors

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.

2 weeks agoadd note on connected UDP sockets
Alan T. DeKok [Wed, 15 Jul 2026 18:03:47 +0000 (14:03 -0400)] 
add note on connected UDP sockets

which apparently work now

remove redundant checks for dst_ipaddr->af, and make the error
messages clearer

2 weeks agofix typo in title indentation
Alan T. DeKok [Wed, 15 Jul 2026 18:04:34 +0000 (14:04 -0400)] 
fix typo in title indentation

2 weeks agoRemove spurious policy from sample default virtual server developer/ndptech
Nick Porter [Tue, 14 Jul 2026 16:34:03 +0000 (17:34 +0100)] 
Remove spurious policy from sample default virtual server

2 weeks agoci: bump FreeBSD pip package to py312-pip
Arran Cudbard-Bell [Tue, 14 Jul 2026 14:47:25 +0000 (10:47 -0400)] 
ci: bump FreeBSD pip package to py312-pip

FreeBSD's package repos dropped the python 3.11 flavour, py312 is the current default.

2 weeks agojson: skip json_object_put leak assert on json-c >= 0.19
Arran Cudbard-Bell [Tue, 14 Jul 2026 14:43:10 +0000 (10:43 -0400)] 
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.

2 weeks agoadd %module.call()
Alan T. DeKok [Tue, 14 Jul 2026 11:58:29 +0000 (07:58 -0400)] 
add %module.call()

and update the home server / proxy documentation to match

2 weeks agoadd %module.call()
Alan T. DeKok [Tue, 14 Jul 2026 11:58:29 +0000 (07:58 -0400)] 
add %module.call()

with some rather severe limitations, but that's OK

2 weeks agochange variable name
Alan T. DeKok [Tue, 14 Jul 2026 11:55:12 +0000 (07:55 -0400)] 
change variable name

to make it clearer that the function is generic

2 weeks agodelay check for virtual server until we need to dereference it
Alan T. DeKok [Tue, 14 Jul 2026 02:26:25 +0000 (22:26 -0400)] 
delay check for virtual server until we need to dereference it

2 weeks agomake error message more descriptive
Alan T. DeKok [Tue, 14 Jul 2026 01:50:03 +0000 (21:50 -0400)] 
make error message more descriptive

2 weeks agoaccount for packet header when calling memmove() in radclient
Alan T. DeKok [Tue, 14 Jul 2026 01:37:45 +0000 (21:37 -0400)] 
account for packet header when calling memmove() in radclient

2 weeks agoloop over virtual modules, compiling them
Alan T. DeKok [Mon, 13 Jul 2026 22:24:08 +0000 (18:24 -0400)] 
loop over virtual modules, compiling them

2 weeks agoadd unlang_compile_virtual_module()
Alan T. DeKok [Mon, 13 Jul 2026 22:23:29 +0000 (18:23 -0400)] 
add unlang_compile_virtual_module()

as a minimal wrapper around unlang_compile_section()

2 weeks agoexport API to iterate over virtual modules
Alan T. DeKok [Mon, 13 Jul 2026 18:47:18 +0000 (14:47 -0400)] 
export API to iterate over virtual modules

2 weeks agocheck dictionaries in a virtual module.
Alan T. DeKok [Mon, 13 Jul 2026 18:00:23 +0000 (14:00 -0400)] 
check dictionaries in a virtual module.

this doesn't catch all of the situations, but it catches many of
them.

2 weeks agoRevert "disable json assert on OSX, it always fails"
Alan T. DeKok [Mon, 13 Jul 2026 17:52:37 +0000 (13:52 -0400)] 
Revert "disable json assert on OSX, it always fails"

This reverts commit b4789234503dd6d5f16ec5c08d2728dca7dfb630.

it randomly fails on other platforms, too

2 weeks agoadd check for "all same" modules and xlat_redundant
Alan T. DeKok [Mon, 13 Jul 2026 15:54:51 +0000 (11:54 -0400)] 
add check for "all same" modules and xlat_redundant

the previous commit was step 1, this is step 2.

2 weeks agodo not immediately resolve modules in a virtual module
Alan T. DeKok [Mon, 13 Jul 2026 15:43:23 +0000 (11:43 -0400)] 
do not immediately resolve modules in a virtual module

due to ordering issues, they may not have been loaded yet.

2 weeks agocheck for duplicate virtual modules, too
Alan T. DeKok [Mon, 13 Jul 2026 14:49:59 +0000 (10:49 -0400)] 
check for duplicate virtual modules, too

2 weeks agoupdate the example configuration for radius module
Alan T. DeKok [Mon, 13 Jul 2026 14:59:56 +0000 (10:59 -0400)] 
update the example configuration for radius module

so that it works