Skip to content

Commit da19a6d

Browse files
committed
Merge branch 'master' into multi-server-tests
2 parents 62787e6 + 060c71d commit da19a6d

81 files changed

Lines changed: 2448 additions & 563 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

debian/control.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Source: freeradius
22
Build-Depends: @BUILDDEPS@ debhelper (>= 9),
3-
asciidoctor,
43
autotools-dev,
54
dh-systemd (>= 1.5) | debhelper (>= 13.3.0),
65
dpkg-dev (>= 1.13.19),
@@ -34,7 +33,6 @@ Build-Depends: @BUILDDEPS@ debhelper (>= 9),
3433
libwbclient-dev,
3534
libykclient-dev,
3635
libyubikey-dev,
37-
pandoc,
3836
python3-dev,
3937
quilt,
4038
samba-dev,

doc/antora/modules/reference/pages/raddb/sites-available/default.adoc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,11 +1542,16 @@ The server is supposed to conclude that the start time was
15421542
"Acct-Delay-Time" seconds in the past.
15431543

15441544
If there's no Event-Timestamp, then we create one, using
1545-
Acct-Delay-Time as an offset if it exists.
1545+
Acct-Delay-Time as an offset if it exists. BUT we only do
1546+
this if Acct-Delay-Time exists, and has a reasonable value.
15461547

15471548
```
15481549
if (!Event-Timestamp) {
1549-
Event-Timestamp := %time.request() - %{Acct-Delay-Time || 0}
1550+
Event-Timestamp := %time.request()
1551+
1552+
if (Acct-Delay-Time && (Acct-Delay-Time < 86400 * 7)) {
1553+
Event-Timestamp -= Acct-Delay-Time
1554+
}
15501555
}
15511556

15521557
```

doc/antora/modules/troubleshooting/nav.adoc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
*** Server does not start
66
**** xref:network/bind.adoc[Failed binding to socket]
77

8-
*** Common Errors
8+
*** Common Errors*
9+
**** xref:network/shared_secret.adoc[Shared secret is incorrect]
10+
**** xref:network/packet_fails_verification.adoc[Packet fails verification]
11+
**** xref:network/message_authenticator_invalid.adoc[Message-Authenticator fail verification]
912
**** xref:network/unknown_packet_code.adoc[Unknown packet code]
1013
**** xref:network/unexpected_request_code.adoc[Unexpected request code]
1114
**** xref:network/message_authenticator_missing.adoc[Message-Authenticator is missing]
12-
**** xref:network/message_authenticator_invalid.adoc[Message-Authenticator fail verification]
1315
**** xref:network/proxy_state_missing.adoc[Proxy-State is missing]
14-
**** xref:network/packet_fails_verification.adoc[Packet fails verification]
1516
**** xref:network/no_matching_request.adoc[Did not find request which matched response]
1617

1718
*** Other Errors
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
= Shared Secret is incorrect.
2+
3+
The shared secret is wrong. Fix it.
4+
5+
// Copyright (C) 2026 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
6+
// This documentation was developed by Network RADIUS SAS.

raddb/sites-available/default

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,10 +1357,15 @@ recv Accounting-Request {
13571357
# "Acct-Delay-Time" seconds in the past.
13581358
#
13591359
# If there's no Event-Timestamp, then we create one, using
1360-
# Acct-Delay-Time as an offset if it exists.
1360+
# Acct-Delay-Time as an offset if it exists. BUT we only do
1361+
# this if Acct-Delay-Time exists, and has a reasonable value.
13611362
#
13621363
if (!Event-Timestamp) {
1363-
Event-Timestamp := %time.request() - %{Acct-Delay-Time || 0}
1364+
Event-Timestamp := %time.request()
1365+
1366+
if (Acct-Delay-Time && (Acct-Delay-Time < 86400 * 7)) {
1367+
Event-Timestamp -= Acct-Delay-Time
1368+
}
13641369
}
13651370

13661371
#

share/dictionary/radius/dictionary.rfc8045

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ ATTRIBUTE Range-End .10 uint32
2626
ATTRIBUTE Local-Id .11 string
2727

2828
ATTRIBUTE IP-Port-Range 241.6 tlv clone=.IP-Port-Limit-Info
29-
ATTRIBUTE Range-Start .9 uint32
30-
ATTRIBUTE Range-End .10 uint32
31-
ATTRIBUTE Local-Id .11 string
3229

3330
ATTRIBUTE IP-Port-Forwarding-Map 241.7 tlv clone=.IP-Port-Range
3431

src/lib/io/worker.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,12 +994,21 @@ static int8_t worker_runnable_cmp(void const *one, void const *two)
994994
request_t const *a = one, *b = two;
995995
int ret;
996996

997-
ret = CMP(b->priority, a->priority);
997+
/*
998+
* Prefer higher priority packets.
999+
*/
1000+
ret = CMP_PREFER_LARGER(b->priority, a->priority);
9981001
if (ret != 0) return ret;
9991002

1000-
ret = CMP(a->sequence, b->sequence);
1003+
/*
1004+
* Prefer packets which are further along in their processing sequence.
1005+
*/
1006+
ret = CMP_PREFER_LARGER(a->sequence, b->sequence);
10011007
if (ret != 0) return ret;
10021008

1009+
/*
1010+
* Smaller timestamp (i.e. earlier) is more important.
1011+
*/
10031012
return fr_time_cmp(a->async->recv_time, b->async->recv_time);
10041013
}
10051014

src/lib/server/cf_file.c

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -307,27 +307,35 @@ char const *cf_expand_variables(char const *cf, int lineno,
307307
* it's the property of a section.
308308
*/
309309
if (q) {
310-
CONF_SECTION *find = cf_item_to_section(ci);
310+
CONF_SECTION *find;
311+
char const *f;
312+
size_t flen;
311313

312314
if (ci->type != CONF_ITEM_SECTION) {
313315
ERROR("%s[%d]: Can only reference properties of sections", cf, lineno);
314316
return NULL;
315317
}
316318

319+
find = cf_item_to_section(ci);
317320
switch (fr_table_value_by_str(conf_property_name, q, CONF_PROPERTY_INVALID)) {
318321
case CONF_PROPERTY_NAME:
319-
strcpy(p, find->name1);
322+
f = find->name1;
320323
break;
321324

322325
case CONF_PROPERTY_INSTANCE:
323-
strcpy(p, find->name2 ? find->name2 : find->name1);
326+
f = find->name2 ? find->name2 : find->name1;
324327
break;
325328

326329
default:
327330
ERROR("%s[%d]: Invalid property '%s'", cf, lineno, q);
328331
return NULL;
329332
}
330-
p += strlen(p);
333+
334+
flen = talloc_array_length(f) - 1;
335+
if ((p + flen) >= (output + outsize)) goto too_long;
336+
337+
memcpy(p, f, flen);
338+
p += flen;
331339
ptr = next;
332340

333341
} else if (ci->type == CONF_ITEM_PAIR) {
@@ -462,6 +470,7 @@ char const *cf_expand_variables(char const *cf, int lineno,
462470

463471
check_eos:
464472
if (p >= (output + outsize)) {
473+
too_long:
465474
ERROR("%s[%d]: Reference \"%s\" is too long",
466475
cf, lineno, input);
467476
return NULL;
@@ -595,7 +604,10 @@ static int cf_file_open(CONF_SECTION *cs, char const *filename, bool from_dir, F
595604
return -1;
596605
}
597606

598-
if (fstatat(my_fd, r, &my_file.buf, 0) < 0) goto error;
607+
if (fstatat(my_fd, r, &my_file.buf, 0) < 0) {
608+
if (my_fd != AT_FDCWD) close(my_fd);
609+
goto error;
610+
}
599611

600612
file = fr_rb_find(tree, &my_file);
601613

@@ -671,8 +683,8 @@ static int cf_file_open(CONF_SECTION *cs, char const *filename, bool from_dir, F
671683
*/
672684
void cf_file_check_set_uid_gid(uid_t uid, gid_t gid)
673685
{
674-
if (uid != 0) conf_check_uid = uid;
675-
if (gid != 0) conf_check_gid = gid;
686+
if (uid != (uid_t) -1) conf_check_uid = uid;
687+
if (gid != (gid_t) -1) conf_check_gid = gid;
676688
}
677689

678690
/** Perform an operation with the effect/group set to conf_check_gid and conf_check_uid
@@ -689,17 +701,17 @@ cf_file_check_err_t cf_file_check_effective(char const *filename,
689701
{
690702
int ret;
691703

692-
uid_t euid = (uid_t)-1;
693-
gid_t egid = (gid_t)-1;
704+
uid_t euid = (uid_t) -1;
705+
gid_t egid = (gid_t) -1;
694706

695-
if ((conf_check_gid != (gid_t)-1) && ((egid = getegid()) != conf_check_gid)) {
707+
if ((conf_check_gid != (gid_t) -1) && ((egid = getegid()) != conf_check_gid)) {
696708
if (setegid(conf_check_gid) < 0) {
697709
fr_strerror_printf("Failed setting effective group ID (%d) for file check: %s",
698710
(int) conf_check_gid, fr_syserror(errno));
699711
return CF_FILE_OTHER_ERROR;
700712
}
701713
}
702-
if ((conf_check_uid != (uid_t)-1) && ((euid = geteuid()) != conf_check_uid)) {
714+
if ((conf_check_uid != (uid_t) -1) && ((euid = geteuid()) != conf_check_uid)) {
703715
if (seteuid(conf_check_uid) < 0) {
704716
fr_strerror_printf("Failed setting effective user ID (%d) for file check: %s",
705717
(int) conf_check_uid, fr_syserror(errno));
@@ -915,10 +927,10 @@ cf_file_check_err_t cf_file_check(CONF_PAIR *cp, bool check_perms)
915927

916928
top = cf_root(cp);
917929
tree = cf_data_value(cf_data_find(top, fr_rb_tree_t, "filename"));
918-
if (!tree) return false;
930+
if (!tree) return CF_FILE_OTHER_ERROR;
919931

920932
file = talloc(tree, cf_file_t);
921-
if (!file) return false;
933+
if (!file) return CF_FILE_OTHER_ERROR;
922934

923935
file->filename = talloc_strdup(file, filename); /* The rest of the code expects this to be talloced */
924936
file->cs = cf_item_to_section(cf_parent(cp));
@@ -1236,7 +1248,7 @@ static int process_include(cf_stack_t *stack, CONF_SECTION *parent, char const *
12361248
*/
12371249
{
12381250
char *directory;
1239-
DIR *dir;
1251+
DIR *dir = NULL;
12401252
struct dirent *dp;
12411253
struct stat stat_buf;
12421254
cf_file_heap_t *h;
@@ -1258,6 +1270,7 @@ static int process_include(cf_stack_t *stack, CONF_SECTION *parent, char const *
12581270
frame->filename, frame->lineno, value,
12591271
fr_syserror(errno));
12601272
error:
1273+
if (dir) closedir(dir);
12611274
talloc_free(directory);
12621275
return -1;
12631276
}
@@ -1318,8 +1331,8 @@ static int process_include(cf_stack_t *stack, CONF_SECTION *parent, char const *
13181331
* Check for valid characters
13191332
*/
13201333
for (p = dp->d_name; *p != '\0'; p++) {
1321-
if (isalpha((uint8_t)*p) ||
1322-
isdigit((uint8_t)*p) ||
1334+
if (isalpha((uint8_t) *p) ||
1335+
isdigit((uint8_t) *p) ||
13231336
(*p == '-') ||
13241337
(*p == '_') ||
13251338
(*p == '.')) continue;
@@ -1337,8 +1350,8 @@ static int process_include(cf_stack_t *stack, CONF_SECTION *parent, char const *
13371350
continue;
13381351
}
13391352
if ((len > 9) && (strncmp(&dp->d_name[len - 9], ".dpkg-old", 9) == 0)) goto pkg_file;
1340-
if ((len > 7) && (strncmp(&dp->d_name[len - 7], ".rpmnew", 9) == 0)) goto pkg_file;
1341-
if ((len > 8) && (strncmp(&dp->d_name[len - 8], ".rpmsave", 10) == 0)) goto pkg_file;
1353+
if ((len > 7) && (strncmp(&dp->d_name[len - 7], ".rpmnew", 7) == 0)) goto pkg_file;
1354+
if ((len > 8) && (strncmp(&dp->d_name[len - 8], ".rpmsave", 8) == 0)) goto pkg_file;
13421355

13431356
snprintf(stack->buff[1], stack->bufsize, "%s%s",
13441357
frame->directory, dp->d_name);
@@ -1362,6 +1375,7 @@ static int process_include(cf_stack_t *stack, CONF_SECTION *parent, char const *
13621375
h->heap_id = FR_HEAP_INDEX_INVALID;
13631376
(void) fr_heap_insert(&frame->heap, h);
13641377
}
1378+
13651379
closedir(dir);
13661380
return 1;
13671381
}
@@ -1870,9 +1884,10 @@ static CONF_ITEM *process_catch(cf_stack_t *stack)
18701884
continue;
18711885
}
18721886

1873-
if (argc > RLM_MODULE_NUMCODES) {
1887+
if (argc >= RLM_MODULE_NUMCODES) {
18741888
ERROR("%s[%d]: Invalid syntax for 'catch' - too many arguments at'%s'",
18751889
frame->filename, frame->lineno, ptr);
1890+
talloc_free(name2);
18761891
return NULL;
18771892
}
18781893

@@ -2623,11 +2638,11 @@ static int parse_input(cf_stack_t *stack)
26232638
}
26242639

26252640
name2_token = gettoken(&ptr, buff[2], stack->bufsize, false); /* can't be EOL */
2626-
if (name1_token == T_INVALID) {
2641+
if (name2_token == T_INVALID) {
26272642
return parse_error(stack, ptr2, fr_strerror());
26282643
}
26292644

2630-
if (name1_token != T_BARE_WORD) {
2645+
if (name2_token != T_BARE_WORD) {
26312646
return parse_error(stack, ptr2, "Unexpected quoted string after section name");
26322647
}
26332648

src/lib/server/cf_parse.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,6 @@ static int cf_pair_unescape(CONF_PAIR *cp, conf_parser_t const *rule)
441441
p = cp->value;
442442
q = str;
443443
while (*p) {
444-
unsigned int x;
445-
446444
if (*p != '\\') {
447445
*(q++) = *(p++);
448446
continue;
@@ -461,15 +459,30 @@ static int cf_pair_unescape(CONF_PAIR *cp, conf_parser_t const *rule)
461459
break;
462460

463461
default:
464-
if (*p >= '0' && *p <= '9' &&
465-
sscanf(p, "%3o", &x) == 1) {
466-
if (!x) {
467-
cf_log_err(cp, "Cannot have embedded zeros in value for %s", cp->attr);
462+
if ((*p >= '0') && (*p <= '7')) {
463+
unsigned long oct;
464+
char *end;
465+
466+
oct = strtoul(p, &end, 8);
467+
if (oct == ULONG_MAX) {
468+
cf_log_err(cp, "Failed parsing octal string");
469+
error:
470+
talloc_free(str);
468471
return -1;
469472
}
470473

471-
*q++ = x;
472-
p += 2;
474+
if (!oct) {
475+
cf_log_err(cp, "Cannot have embedded zeros in value at %s", p);
476+
goto error;
477+
}
478+
479+
if (oct > UINT8_MAX) {
480+
cf_log_err(cp, "Invalid octal number in value at %s", p);
481+
goto error;
482+
}
483+
484+
*q++ = oct;
485+
p = end;
473486
} else {
474487
*q++ = *p;
475488
}
@@ -480,9 +493,8 @@ static int cf_pair_unescape(CONF_PAIR *cp, conf_parser_t const *rule)
480493
*q = '\0';
481494

482495
unescaped = talloc_typed_strdup(cp, str); /* no embedded NUL */
483-
if (!unescaped) return -1;
484-
485496
talloc_free(str);
497+
if (!unescaped) return -1;
486498

487499
/*
488500
* Replace the old value with the new one.

src/lib/server/cf_priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ typedef struct {
148148
* Will be declared in the scope of the loop.
149149
*/
150150
#define cf_item_foreach(_ci, _iter) \
151-
for (CONF_ITEM *_iter = fr_dlist_head(&(_ci)->children); _iter; _iter = fr_dlist_next(&(_ci)->children, _iter))
151+
for (CONF_ITEM *JOIN(_next,_iter), *_iter = fr_dlist_head(&(_ci)->children); JOIN(_next,_iter) = fr_dlist_next(&(_ci)->children, _iter), _iter != NULL; _iter = JOIN(_next,_iter))
152152

153153
/** Iterate over the contents of a list
154154
*

0 commit comments

Comments
 (0)