*** xref:mods-available/etc_group.adoc[etc_group Module]
*** xref:mods-available/exec.adoc[Exec Module]
*** xref:mods-available/files.adoc[Files Module]
+**** xref:mods-config/files/users.adoc[users file format]
*** xref:mods-available/idn.adoc[IDN Module]
*** xref:mods-available/isc_dhcp.adoc[ISC DHCP Module]
*** xref:mods-available/imap.adoc[IMAP Module]
The `users` file as located in `raddb/mods-config/files/authorize`. (Livingston-style format).
-See `man 1 users` for more information.
-
-
-
-NOTE: Temporarily (2023-08-27), the check items only supports
-"real" attributes. This limitation will be removed when the module
-is rewritten to support xlat expressions for conditions.
-
-The module also does not support xlat expansions on the RHS.
+See the in the xref:raddb:mods-config/files/users.adoc[users] file documention for information
+on the format of the input file, and how it operates.
--- /dev/null
+= The users file
+
+The `users` file is managed by the xref:raddb:mods-available/files.adoc[files] module. The format largely goes back to the original Livingston RADIUS server in 1991!
+
+While the format is still called `users` for historical reasons, the name of the file is controlled by the configuration of the xref:raddb:mods-available/files.adoc[files] module, and can therefore something other than `users`.
+
+The format is text-based. Empty lines, and lines which begin with a
+comment (`#`) or whitespace plus a comment are ignored. All other
+text has to follow a fixed format:
+
+.users file format
+----
+name ... check items ...
+ ... reply items ...,
+ ... reply items ...
+----
+
+name:: The name of the entry. It must be an unquoted string such as `john`. The xref:raddb:mods-available/files.adoc[files] module configuration expands the `key` configuration item, and then uses the result to match the `name` of the entry.
+
+check items:: A comma-separated list of attributes to use for conditional matches, such as `Framed-IP-Address == 192.0.2.1`, or `NAS-IP-Address == 192.0.2.2, NAS-Port = 15`. Multiple conditions are matched with a logical "and". There is no way to use a logical "or" between conditions.
++
+The conditional matching must be done via comparison operators such as `==`, `<`, `<=`, etc.
++
+The list of check items can be empty, in which case the first line of the entry contains the `name`, and nothing more.
+
+reply items:: A comma-separated list of attributes which are added to the reply, such as `Reply-Message := "Hello"`, or `Filter-Id := "foo", Filter-Id += "bar"`.
++
+The list of reply items can span multiple line, in which case each intermediate line must end with a comma, and the last line of the reply items must not end with a comma.
++
+Each line containing reply items must begin with a tab character.
++
+The list of reply items can be empty, in which case there must be a blank line after the line which contains the `name` and check items.
+
+There is no limit to the size of the file or number of entries in it, other than available memory. The file is read and cached when the server starts, and cannot be changed while the server is running.
+
+== Processing
+
+The file is processed by finding one or more matching entries, subject to the additional functionality described below.
+
+The entries are placed into a data structure which nest leverages the data type of the `key`:
+
+IP addresses and prefixes:: Patricia trie.
+
+string, octets, date, time_delta:: balanced binary tree.
+
+structural types:: not allowed
+
+all other data types:: hash.
+
+These data structures allow the module to operate extremely quickly. When doing performance tests, there is very little difference between a `users` file which contains one entry, and a `users` file which contains a million entries.
+
+Where multiple entries are matched, the entries are matched in the order that they appear in the file. That is, they are matched from the top of the file to the bottom of the file.
+
+=== The $INCLUDE directive
+
+As a special case, the line can begin with the name `$INCLUDE`. The `$INCLUDE` name must be followed by a filename.
+
+.Example
+----
+$INCLUDE next_users_file
+----
+
+The `$INCLUDE` directive reads another file into the current `users` file, as if the contents had been included in-place in the original file.
+
+The filename can be absolute, and begin with `/`. That usage is not recommended.
+
+If the filename does not begin with `/`, it is a relative filename. The module reads the file which is relative to the current file being processed. For example, if the current file is `/etc/raddb/mods-config/files/users` and that file contains a directive `$INCLUDE next`, the file which will be read is `/etc/raddb/mods-config/files/next`.
+
+The `$INCLUDE` can be nested to any depth, subject only to available memory. The module does not cross-reference `$INCLUDE` files, so it is possible for a file to `$INCLUDE` itself in an infinite loop. This practice is not recommended. When this misconfiguration happens, the server will run out of memory processing the file, and then exit.
+
+The purpose of `$INCLUDE` is to allow the `users` file to be broken up into multiple logical pieces. For example, a system mayneed to generate multiple different types of `users ` file entries, depending on the type of user. These different entries may be placed into different files, so that each different file can be regenerated independently.
+
+=== Matching an entry
+
+An entry is said to match if the `name` field matches. Once the entry matches, the module looks for and processes any check items.
+
+The check items are matched using the same operations as for xref:reference:unlang/condition/cmp.adoc[conditional comparisons].
+
+NOTE: Only conditional comparisons are allowed, the rest of the conditional syntax such as nested conditions `(...)` or `||` and `&&` are not permitted.
+
+If the check items all match, the module adds the reply items (if any) to the request.
+
+For historical compatibility, the check item list also supports some attribute assignments. Any check item which uses an assignment operator (`=`, `:=`, etc.) is added to the `control` list.
+
+=== Fall-Through
+
+When processing the reply items, the attribute `Fall-Through = yes` has special meaning. If it is found in list of reply items, then the module will continue processing the `users` file, and will look for a subsequent matching entry.
+
+The `Fall-Through` attribute is most commonly used to apply rules to specific users, but then also apply generic rules, as in the example below.
+
+.Example
+----
+bob Password.Cleartext := "hello"
+ Framed-IP-Address := 192.0.2.1,
+ Fall-Through = yes
+
+DEFAULT
+ Reply-Message := "Hello %{User-Name}"
+----
+
+In this example, the user `bob` will have both the `Framed-IP-Address` and `Reply-Message` attributes added in any reply.
+
+=== Next-Shortest-Prefix
+
+If the `key` field is an IP address or prefix data type, the module tracks the prefix. When an entry matches, the `Next-Shortest-Prefix` attribute is also checked. If set to `yes`, the module will decrease the value of the prefix, and look for a matching entry. i.e. the "next shortest prefix" after the current one.
+
+The interaction between `Fall-Through` and `Next-Shortest-Prefix` allows the `users` file to match both multiple entries for the current `key` value, and also to apply rules to entire networks. However, the reply items should only contain one of `Fall-Through` or `Next-Shortest-Prefix`. If both appear in the reply item list, the `Next-Shortest-Prefix` attribute is ignored.
+
+.Example
+----
+192.0.2.1
+ Filter-Id := "foo",
+ Next-Shortest-Prefix = yes
+
+192.0.0.0/8
+ Reply-Message = "In the 192 network"
+----
+
+In this example, a `key` of `192.0.2.1` will both a `Filter-Id` attribute, and a `Reply-Message` attribute. In contrast, a `key` of `192.0.2.255` will only return a `Reply-Message` attribute.
+
+=== The DEFAULT name
+
+If no entry matches, the special name `DEFAULT` will be matched. The `DEFAULT` entry can also match if a previous `name` matched, and the reply items contained `Fall-Through = yes`, or `Next-Shortest-Prefix = yes`.
+
+We recommend not using `DEFAULT` when the `key` is an IP address or prefix. It is better instead to use a network and mask, such as `192.0.2/24`, or `0/0`.
+
+=== Recommendations
+
+Entries which reject requests should go at the top of the file, and
+should not use `Fall-Through` item. Entries for specific users who do
+not have a `Fall-Through`, should come next. Any `DEFAULT` entries
+should usually come last. This ordering means that it will be easier
+to debug policies, and understand how the file works.
+
+== Check and Reply item format
+
+Each check item or reply item must follow the same format, which is shown in the examples above. The format is an attribute name, followed by an operator, and then a value.
+
+attribute:: An attribute name such as `Framed-IP-Address`
+
+operator:: A comparison operator (for check items), or an assignment operator. See the "Item Operators" section for a list of operators abd their meaning.
+
+value:: A value such as `192.0.2.1`, `15`, or string `"foo"`. Values can also be attribute references. See the "Item Values" section below for more information.
+
+=== Item Attributes
+
+The `attribute` name for an item can be a simple name such as `Filter-Id`. The name can also be an xref:reference:unlang/attr.adoc[attribute reference] such as `reply.Reply-Message`.
+
+Attribute references are supported for both the check items and reply items.
+
+The default list for the check items is `control`. Specifying another list means that the comparison is done instead on the referenced attribute.
+
+The default list for the reply items is `reply`. Specifying another list means that the other list is updated, instead of the `reply` list.
+
+It is not possible in the `users` file to create, compare, or edit a structural data type such as `struct` or `tlv`. Instead, the relevant leaf or child attribute has to be created, which will automatically create the parent.
+
+=== Item Operators
+
+The list of comparison operators for check items is given in the xref:reference:unlang/condition/cmp.adoc[conditional comparisons] page. However, the `users` file format does not support casting in a comparison.
+
+The assignment operators follow the behavior of the `user` file, and *do not* follow the new xref:reference:unlang/edit.adoc[editing operators] behavior. The reason for this mismatch is that we prefer to not break backwards compatibility for the `users` file. Both because of how how the operators work, and because using the new-style operators in the `users` format would require changing the `users` file format so much that it would be unrecognizable, and likely not usable.
+
+As a result, the attribute editing operators for the `users` file follow the old-style functionality, as documented below.
+
+.Attribute Editing Operators
+[options="header"]
+[cols="10%,90%"]
+|=====
+| Operator | Description
+| = | Set the attribute to the contents of the value, if the given attribute does not exist. If the attribute already exists, nothing is done. If the attribute does not exist, it is created, and the contents set to the given value.
+| := | Delete all existing copies of the named attribute, and create a new attribute with the contents set to the given value.
+| += | Create the attribute using the given value, and append the attribute to the list (insert at tail).
+| ^= | Create the attribute using the given value, and prepend the attribute to the list (insert at head).
+| -= | Delete all attributes which match the given value.
+|=====
+
+There are also _filtering_ operators. These operators ensure that the
+value of the attribute passes the filter. If the attribute being
+filtered does not exist, it is created.
+
+.Attribute Filtering Operators
+[options="header"]
+[cols="10%,90%"]
+|=====
+| Operator | Description
+| \<= | Ensure that the attribute exists, and has value less than or equal to the given value.
+| >= | Ensure that the attribute exists, and has value greater than than or equal to the given value.
+|=====
+
+If the value does not pass the filter comparison, its value is replaced with the value from the filter comparison.
+
+=== Item Values
+
+The values for items can be a simple value such as `192.0.2.1`, an xref:reference:xlat/index.adoc[xlat] string to expand such as `"Hello %{User-Name}"`, or an xref:reference:unlang/attr.adoc[attribute reference] such as `&request.Filter-Id`.
+
+The attribute references should have an `&` prefix, to more clearly separate them from enumeration values such as `Service-Type := Framed-User`.
+
+References can be to an attribute which has a different data type than the attribute named on the left-hand side of the check item or reply item. In which case the values will be automatically cast to the correct type, as documented in the xref:reference:unlang/condition/cmp.adoc[conditional comparison] and ref:reference:unlang/edit.adoc[edit] pages.
+
+.Example
+----
+#
+# Match "bob", but only if he's logging in from this particular NAS
+# Send a user-specific Reply-Message, and ACK any Framed-IP-Address
+# which was requested.
+#
+bob NAS-IP-Address == 192.0.2.1, Password.Cleartext := "hello"
+ Reply-Message := "Hello %{User-Name}",
+ Framed-IP-Address := &request.Framed-IP-Address
+----
+
+
+// Copyright (C) 2023 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// This documentation was developed by Network RADIUS SAS.
+++ /dev/null
-.\" # DS - begin display
-.de DS
-.RS
-.nf
-.sp
-..
-.\" # DE - end display
-.de DE
-.fi
-.RE
-.sp
-..
-.TH USERS 5 "27 Apr 2021" "" "FreeRADIUS user authorization file"
-.SH NAME
-users \- user authorization file for the FreeRADIUS server
-.SH DESCRIPTION
-The \fBusers\fP files reside in the files module configuration directory,
-by default \fB/etc/raddb/mods-config/files/\fP. It contains a series
-of configuration directives which are used by the \fIfiles\fP
-module to decide how to authorize and authenticate each user request.
-
-Every line starting with a hash sign
-.RB (' # ')
-is treated as comment and ignored.
-.PP
-Each entry of the file begins with a username, followed by a (possibly
-empty) list of check items, all on one line. The next line begins
-with a tab, and a (possibly empty) list of reply items. Each item in
-the check or reply item list is an attribute of the form \fBname =
-value\fP. Multiple items may be placed on one line, in which case
-they must be separated by commas. The reply items may be specified
-over multiple lines, in which case each line must end with a comma,
-and the last line of the reply items must not end with a comma.
-
-The check items are a list of attributes used to match the incoming
-request. If the username matches, AND all of the check items match
-the incoming request, then the reply items are added to the list of
-attributes which will be used in the reply to that request. This
-process is repeated for all of the entries in the users file.
-
-If the incoming request matches NO entry, then the request is
-rejected.
-
-.SH CAVEATS
-The special keyword \fBDEFAULT\fP matches any usernames.
-
-The entries are processed in order, from the top of the \fBusers\fP file,
-on down. If an entry contains the special item \fBFall-Through =
-No\fP as a reply attribute, then the processing of the file stops, and
-no more entries are matched. Any reply item list without any
-\fBFall-Through\fP attribute is treated as though it included a
-\fBFall-Through = No\fP attribute.
-
-If an entry contains the special item \fBFall-Through = Yes\fP as a
-reply attribute, then the processing proceeds to the next entry in
-order.
-
-Care should be taken when using \fBFall-Through\fP. The server should
-be tested in debugging mode with a number of test requests, in order
-to verify that the configured entries behave as expected.
-
-.SH OPERATORS
-Additional operators other than \fB=\fP may be used for the attributes in
-either the check item, or reply item list. The following is a list of
-operators, and their meaning.
-
-.TP 0.5i
-.B "Attribute = Value"
-Not allowed as a check item for RADIUS protocol attributes. It is
-allowed for server configuration attributes (Auth-Type, etc), and sets
-the value of an attribute, only if there is no other item of the
-same attribute.
-.br
-As a reply item, it means "add the item
-to the reply list, but only if there is no other item of the same
-attribute."
-
-.TP 0.5i
-.B "Attribute := Value"
-Always matches as a check item, and replaces in the configuration
-items any attribute of the same name. If no attribute of that name
-appears in the request, then this attribute is added.
-.br
-As a reply item, it has an identical meaning, but for the reply items,
-instead of the request items.
-
-.TP 0.5i
-.B "Attribute == Value"
-As a check item, it matches if the named attribute is present in the
-request, AND has the given value.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute += Value"
-Always matches as a check item, and adds the current attribute with
-value to the tail of the list of configuration items.
-.br
-As a reply item, it has an identical meaning, but the attribute is
-added to the tail of the reply items list.
-
-.TP 0.5i
-.B "Attribute ^= Value"
-Always matches as a check item, and adds the current attribute with
-value to the head of the list of configuration items.
-.br
-As a reply item, it has an identical meaning, but the attribute is
-added to the head of the reply items list.
-
-.TP 0.5i
-.B "Attribute != Value"
-As a check item, matches if the given attribute is in the request, AND
-does not have the given value.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute > Value"
-As a check item, it matches if the request contains an attribute with
-a value greater than the one given.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute >= Value"
-As a check item, it matches if the request contains an attribute with
-a value greater than, or equal to the one given.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute < Value"
-As a check item, it matches if the request contains an attribute with
-a value less than the one given.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute <= Value"
-As a check item, it matches if the request contains an attribute with
-a value less than, or equal to the one given.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute =* Value"
-As a check item, it matches if the request contains the named
-attribute, no matter what the value is.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute !* Value"
-As a check item, it matches if the request does not contain the named
-attribute, no matter what the value is.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute =~ /regex/"
-As a check item, it matches if the value of the regular expression
-matches the value of the attribute.
-.br
-Not allowed as a reply item.
-
-.TP 0.5i
-.B "Attribute !~ /regex/"
-As a check item, it matches if the value of the value of the regular expression
-does not the value of the attribute.
-Not allowed as a reply item.
-
-.SH EXAMPLES
-
-.DS
-bob Password.Cleartext := "hello"
-
-.DE
-.RS
-Requests containing the User-Name attribute, with value "bob", will be
-authenticated using the "known good" password "hello". There are no
-reply items, so the reply will be empty.
-.RE
-
-.DS
-DEFAULT Service-Type == Framed-User, Framed-Protocol == PPP
-.br
- Service-Type = Framed-User,
-.br
- Framed-Protocol = PPP,
-.br
- Fall-Through = Yes
-
-.DE
-.RS
-If the request packet contains the attributes Service-Type and
-Framed-Protocol, with the given values, then include those attributes
-in the reply.
-
-That is, give the user what they ask for. This entry also shows how
-to specify multiple reply items.
-.RE
-
-See the \fBusers\fP file supplied with the server for more examples
-and comments.
-
-.SH HINTS
-Run the server in debugging mode (\fB-X\fP), and use the
-\fBradclient\fP program to send it test packets which you think will
-match specific entries. The server will print out which entries were
-matched for that request, so you can verify your expectations. This
-should be the FIRST thing you do if you suspect problems with the
-file.
-
-Care should be taken when writing entries for the \fBusers\fP file. It is
-easy to misconfigure the server so that requests are accepted when you
-wish to reject them. The entries should be ordered, and the
-Fall-Through item should be used ONLY where it is required.
-
-Entries rejecting certain requests should go at the top of the file,
-and should not have a Fall-Through item in their reply items. Entries
-for specific users, who do not have a Fall-Through item, should come
-next. Any DEFAULT entries should usually come last, except as fall-through
-entries that set reply attributes.
-
-.SH FILES
-/etc/raddb/mods-config/files/
-.SH "SEE ALSO"
-.BR radclient (1),
-.BR radiusd (8),
-.BR dictionary (5),
-
-.SH AUTHOR
-The FreeRADIUS team.
#
# The `users` file as located in `raddb/mods-config/files/authorize`. (Livingston-style format).
#
-# See `man 1 users` for more information.
-#
-
-#
-# NOTE: Temporarily (2023-08-27), the check items only supports
-# "real" attributes. This limitation will be removed when the module
-# is rewritten to support xlat expressions for conditions.
-#
-# The module also does not support xlat expansions on the RHS.
+# See the asciidoc documentation in the `raddb/mods-config/files/users` file for information
+# on the format of the `users` file, and how it operates.
#
#
#
# Configuration file for the rlm_files module.
-# Please see rlm_files(5) manpage for more information.
+# Please see rlm_files documentation for more information.
#
# This file contains authentication security and configuration
# information for each user. Accounting requests are NOT processed
-# through this file. Instead, see 'accounting', in this directory.
+# through this file. Instead, see the 'accounting' file in this directory.
#
-# The first field is the user's name and can be up to
-# 253 characters in length. This is followed (on the same line) with
-# the list of authentication requirements for that user. This can
-# include password, comm server name, comm server port number, protocol
-# type.
+# The first field is the user's name, followed (on the same
+# line) with the list of check items for that user. The next
+# lines are reply items, which must begin with tabs.
#
# If you are not sure why a particular reply is being sent by the
# server, then run the server in debugging mode (radiusd -X), and
# you will see which entries in this file are matched.
#
-# When an authentication request is received from the comm server,
-# these values are tested. Only the first match is used unless the
-# "Fall-Through" variable is set to "Yes".
+# The special attribute Fall-Through is used to control whether or not
+# multiple entries match.
#
-# A special user named "DEFAULT" matches on all usernames.
-# You can have several DEFAULT entries. All entries are processed
-# in the order they appear in this file. The first entry that
-# matches the login-request will stop processing unless you use
-# the Fall-Through variable.
-#
-# Indented (with the tab character) lines following the first
-# line indicate the configuration values to be passed back to
-# the comm server to allow the initiation of a user session.
-# This can include things like the PPP configuration values
-# or the host to log the user onto.
+# A special entry "DEFAULT" matches all entries. You can have
+# several DEFAULT entries. All entries are processed in the
+# order they appear in this file. The first entry that matches
+# the login-request will stop processing unless you use the
+# Fall-Through variable.
#
# You can include another `users' file with `$INCLUDE users.other'
-#
-# For a list of RADIUS attributes, and links to their definitions,
-# see: http://www.freeradius.org/rfc/attributes.html
#
# Entries below this point are examples included in the server for
# educational purposes. They may be deleted from the deployed