* `–username=%{User-Name}` - this will fail if you’re using realms or
host-based auth
-* `–username=%(mschap:User-Name)` - this will fail if using using suffix
+* `–username=%mschap(User-Name)` - this will fail if using using suffix
i.e. user@domain
You’ll need to fit this to your local needs.
```
mschap {
passchange {
- local_cpw = %{sql:select change_password('%{User-Name}','%{MS-CHAP-New-NT-Password}')}'
+ local_cpw = %sql("select change_password('%{User-Name}','%{MS-CHAP-New-NT-Password}')")
}
}
```
. update via
```
-SQL local_cpw = %{sql:update radcheck set value='%{MS-CHAP-New-NT-Password}' where username=%{User-Name} and
-attribute=’Password.NT'}
+SQL local_cpw = %sql("update radcheck set value='%{MS-CHAP-New-NT-Password}' where username=%{User-Name} and attribute=’Password.NT'")
```
Or:
. update via exec/script
```
-local_cpw = `%(exec:/my/script %{User-Name} %{MS-CHAP-New-Password.Cleartext})`
+local_cpw = `%exec('/my/script', %{User-Name}, %{MS-CHAP-New-Password.Cleartext})`
```
WARNING: Wherever possible, you should use `MS-CHAP-New-NT-Password`. The
}
```
-In v4, you can remove the `update`, and also remove the double quotes:
+In v4, you can remove the `update`, and rewrite the SQL call to:
```
-&reply.Framed-IP-Address := %{sql:SELECT ...}
+&reply.Framed-IP-Address := %sql("SELECT ...")
```
Using double quotes everywhere means that every bit of data gets
This module handles the `%{client:..}` xlat expansions.
-The `Client-Shortname` attribute has been removed. You should use `%{client:shortname}` instead.
+The `Client-Shortname` attribute has been removed. You should use `%client(shortname)` instead.
=== rlm_radius
=== rlm_expr
-Allow `&Attr-Name[*]` to mean _sum_. Previously, it just referred to
-the first attribute.
+The `expr` module is no longer necessary and has been removed.
-Using `%{expr:0 + &Attr-Name[*]}` will cause it to return the sum of
-the values of all attributes with the given name.
+The xref:reference:xlat/index.adoc[xlat] expansions just support math
+natively. For example:
-Note that `%{expr:1 * &Attr-Name[*]}` does _not_ mean repeated
-multiplication. Instead, the sum of the attributes is taken as before,
-and then the result is multiplied by one.
+```
+&Reply-Message := "1 + 2 = %{1 + 2}"
+```
+
+will return the string `1 + 2 = 3`. The contents of the expansion can
+be any math or condition. Attribute assignments in expansions are not
+supported.
=== rlm_expiration
=== rlm_ldap
-The `ldap` module provides an expansion `%{ldap.memberof:<name>}` instead of
+The `ldap` module provides an expansion `%ldap.memberof(<name>)` instead of
`LDAP-Group` for dynamically testing group membership. The old method of
```
-LDAP-Group == "foo"
+if (LDAP-Group == "foo") { ...
```
-will no longer work.
+will no longer work. Instead, use
+
+```
+if (%ldap.memberof(foo)) { ...
+```
The cacheing of group membership into attributes in the `control` list is
still available, so
```
recv Access-Request {
- update request {
- &Stripped-User-Name := "%{tolower:%{User-Name}}"
- }
+ &Stripped-User-Name := %tolower(%{User-Name})
...
}
```
expressions.
It is possible to force a dynamic group lookup via the expansion
-`%{sql.group:foo}`. This expansion returns `true` if the user is a
+`%sql.group(foo)`. This expansion returns `true` if the user is a
member of that SQL group, and `false` otherwise.
```
-if (%{sql.group:sales}) {
+if (%sql.group(sales)) {
...
}
```
=== rlm_unix
-The `unix` module uses an expansion `%{unix.group:<name>}` instead of
+The `unix` module uses an expansion `%unix.group(<name>)` instead of
`Unix-Group`, `Group` or `Group-Name`. The old method of doing
```
=== rlm_winbind
-The `winbind` module uses an expansion `%{winbind.group:<name>}` instead of
+The `winbind` module uses an expansion `%(winbind.group(<name>)` instead of
`Winbind-Group == <name>`.
== Deleted Modules
Many "virtual" or "fake" attributes have been removed or renamed.
-`&Module-Return-Code` should be replaced by `%(interpreter:rcode)`.
+`&Module-Return-Code` should be replaced by `%interpreter(rcode)`.
`&Response-Packet-Type` should be replaced by `&reply.Packet-Type`.
-`&Virtual-Server` should be replaced by `%(interpreter:server)`.
+`&Virtual-Server` should be replaced by `%interpreter(server)`.
-`&Packet-Authentication-Vector` should be replaced by `%{radius.packet.vector:}`.
+`&Packet-Authentication-Vector` should be replaced by `%radius.packet.vector()`.
`&Packet-Dst-IP-Address` and `&Packet-Dst-IPv6-Address` should be replaced by `&Net.Dst.IP`.
RADIUS UDP / TCP socket IO.
+Overrides the default transport prefix set by
+namespace and loads the detail reader code.
+
+
+
Types of packets we are reading.
+
We handled the packet successfully. Run the "send ok" section.
namespace = radius
directory = ${radacctdir}/detail
listen detail {
+ proto = detail
type = Accounting-Request
# priority = 1
file {
}
}
recv Accounting-Request {
- &request.Acct-Delay-Time := "%{expr:%{%{Acct-Delay-Time}:-0} + %c - %(integer:%{%{Event-Timestamp}:-%{Packet-Original-Timestamp}})}"
+ if (!&Event-Timestamp) {
+ &Event-Timestamp := &Packet-Original-Timestamp
+ }
+ if (&Event-Timestamp < %c) {
+ &request.Acct-Delay-Time += %c - &Event-Timestamp
+ }
ok
}
send Accounting-Response {
}
recv Status-Server {
if ("%sql('SELECT pg_is_in_recovery()')" != "f") {
- if ("%{db_online:}" != "fail") {
- %{db_online:fail}
+ if (%db_online() != "fail") {
+ %db_online(fail)
}
} else {
- if ("%{db_online:}" != "alive") {
- %{db_online:alive}
+ if (%db_online() != "alive") {
+ %db_online(alive)
}
}
}
[source,unlang]
----
-if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == 192.0.2.1) }
+if (%sql("SELECT ipaddress FROM table WHERE user=%{User-Name}") == 192.0.2.1) }
....
}
----
.Example
[source,unlang]
----
-if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == (ipaddr)192.0.2.1) }
+if (%sql("SELECT ipaddress FROM table WHERE user=%{User-Name}") == (ipaddr)192.0.2.1) }
....
}
----
string, and assigning the resulting value to the `string`. For a
value of typ e `octets`, this means that the output is a hex string,
prefixed with `0x`. In order to get the "raw" hex values of an
-`octets` data type, the `%{hex:...}` expansion is used. It prints out
+`octets` data type, the `%hex(...)` expansion is used. It prints out
the hex value of its input, without the leading `0x` characters.
Casting a `string` value to another data type means _parsing_ the
...
}
-if ( &Calling-Station-Id == "%{sql:SELECT ...}" ) {
+if ( &Calling-Station-Id == "%sql("SELECT ...") ) {
...
}
----
* If you want to check that an attribute exists _and_ has a particular value, use `if !(&Attr == value)`, instead of `if (&Attr != value)`. The difference us that if the attribute does not exist, it will match the condition `(&Attr != value)`, because the attribute has no value.
-
// Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
When using libpcre[2], named capture groups may also be accessed using the
built-in expansion +
-`%{regex:<named capture group>}`.
+`%regex(<named capture group>)`.
Please see the xref:xlat/builtin.adoc#_0_32[xlat documentation] for
more information on regular expression matching.
====
[source,unlang]
----
-&reply += "%{sql:SELECT pairs FROM pair_table WHERE username = '%{User-Name}'}"
+&reply += "sql("SELECT pairs FROM pair_table WHERE username = '%{User-Name}'")
----
====
[source,unlang]
----
-&NAS-Port-Id = (uint32) "%{sql: SELECT...}" + 4
+&NAS-Port-Id = (uint32) "%sql("SELECT...") + 4
----
== Errors
.Example
[source,unlang]
----
-&reply.Framed-IP-Address := "%{sql:SELECT static_ip from table WHERE user = '%{User-Name}'}"
+&reply.Framed-IP-Address := %sql("SELECT static_ip from table WHERE user = '%{User-Name}'")
----
== Data Types
`load-balance` section can be defined as a module in the `mods-enabled/`
directory.
-For example, the following file can be placed into
+For example, the following text can be placed into the file
`mods-enabled/sql123`. Once it is there, it can be used as a module
named `sql123`, and used anywhere a module is allowed to use.
In previous versions of the server, this definition would be placed
into the `instantiate` section of `radiusd.conf. This configuration
-is no longer used, and the `sql123` definition can just be placed into
-a module definition in the `mods-enabled/` directory.
+is no longer used, and the `sql123` definition can just be placed as
+a module definition into the `mods-enabled/` directory.
== Load-Balance Expansions
.Example of Load-Balance SQL module
[source,unlang]
----
-&Reply-Message := %{sql123:SELECT message FROM table WHERE name='%{User-Name}'}
+&Reply-Message := %sql123("SELECT message FROM table WHERE name='%{User-Name}'")
}
----
`redundant-load-balance` section can be defined as a module in the `mods-enabled/`
directory.
-For example, the following file can be placed into
+For example, the following text can be placed into the file
`mods-enabled/sql123`. Once it is there, it can be used as a module
named `sql123`, and used anywhere a module is allowed to use.
In previous versions of the server, this definition would be placed
into the `instantiate` section of `radiusd.conf. This configuration
-is no longer used, and the `sql123` definition can just be placed into
-a module definition in the `mods-enabled/` directory.
+is no longer used, and the `sql123` definition can just be placed as
+a module definition into the `mods-enabled/` directory.
== Redundant-Load-Balance Expansions
.Example of Redundant-Load-Balance SQL module
[source,unlang]
----
-&Reply-Message := %{sql123:SELECT message FROM table WHERE name='%{User-Name}'}
+&Reply-Message := %sql123("SELECT message FROM table WHERE name='%{User-Name}'")
}
----
`redundant` section can be defined as a module in the `mods-enabled/`
directory.
-For example, the following file can be placed into
+For example, the following text can be placed into the file
`mods-enabled/sql123`. Once it is there, it can be used as a module
named `sql123`, and used anywhere a module is allowed to use.
In previous versions of the server, this definition would be placed
into the `instantiate` section of `radiusd.conf. This configuration
-is no longer used, and the `sql123` definition can just be placed into
-a module definition in the `mods-enabled/` directory.
+is no longer used, and the `sql123` definition can just be placed as
+a module definition into the `mods-enabled/` directory.
== Redundant Expansions
.Example of Redundant SQL module
[source,unlang]
----
-&Reply-Message := %{sql123:SELECT message FROM table WHERE name='%{User-Name}'}
+&Reply-Message := %sql123("SELECT message FROM table WHERE name='%{User-Name}'")
}
----
- `rest`
- `sql`
-The redis module has a string expansion %{redis:<command>} which can be used
+The redis module has a string expansion %redis(<command>) which can be used
to retrieve a single value from the datastore.
Call the backend module's authorize method (or run an appropriate expansion) to
if ("%sql('SELECT pg_is_in_recovery()')" != "f") {
# Fail the db_online module, if it isn't already
- if ("%{db_online:}" != "fail") {
- %{db_online:fail}
+ if (%db_online() != "fail") {
+ %db_online(fail)
}
} else {
# Set the db_online module status to alive, if it isn't already
- if ("%{db_online:}" != "alive") {
- %{db_online:alive}
+ if (%db_online() != "alive") {
+ %db_online(alive)
}
}