Where `<driver>` is cassandra, db2, firebird, freetds, null, mysql
oracle, postgresql, sqlite and unixodbc.
+For authorization queries, the default schema mirrors the
+functionality of the `files` module, including check items and
+reply items. See the
+xref:raddb:mods-config/files/users.adoc[users] file
+documentation for information on the format of the check items and
+reply items.
+
## Configuration Settings
This example copies the `Vendor-Specific.Cisco` group from the `&control` list. If the attribute does not exist in the control list, nothing is done.
-Structural attributes can be created from a string, as with the xref:reference:unlang/edit.adoc[edit] funtionality.
+Structural attributes can be created from a string, as with the xref:reference:unlang/edit.adoc[edit] funtionality. Note that the string should not contain brackets such as `"{ AVPair = 'hello' }".
.Creating a Structural attribute from a string
----
This example creates the reply attribute `Vendor-Specific.Cisco.AVPair`, with value `hello`. If the parent attributes `Vendor-Specific` or `Cisco` do not exist, they are created.
+As the right-hand side is a double-quoted string, it is expanded via the normal xref:reference:xlat/index.adoc[xlat] process as discussed below in "Item Values".
+
+All of the attributes in the double-quoted string *must* use the `=` operator. Other operators are not supported.
+
+==== Relative Attribute References
+
+The format of the `users` file is not well suited for structural data types. The xref:reference:unlang/edit.adoc[edit] functionality supports nested lists such as `&foo = { &bar = 1 }`. Instead, the "dotted" notation of attribute references is leveraged, to create _relative_ attribute refefences. The example below shows how relative attribute references can be used.
+
+.Creating Relative Attributes
+----
+bob Password.Cleartext := "hello"
+ Vendor-Specific = "",
+ .Cisco = "",
+ .AVPair += "Hello"
+----
+
+In the above example, the reply items start out with a reference to a structural attribute which is at the "root" of the attribure tree. In this case, the attribute is `Vendor-Specific`. The assignment uses the `=` operator, which creates the attribute if it does not already exist. If the `Vendor-Specific` attribute exists, no changes are made. The value assigned is an empty string, which (if necessary) will create an empty `Vendor-Specific` attribute.
+
+The next line contains a _relative_ attribute reference: `.Cisco`. The attribute reference is _relative_ because it begins with a `.` character. The relative attribute must be a child of the previous structural attribute, in this case `Vendor-Specific`.
+
+As with `Vendor-Specific`, and `.Cisco` attribute uses the `=` operator, and an empty string to create the `Cisco` attribute inside of the `Vendor-Specific` one.
+
+The final line contains `.AVPair += "Hello"`. This line also contains a _relative_ attribute reference. It creates a `AVPair` attribute inside of the `Cisco` attribute, and then assigns the value `"Hello"` to it. The created attribute is appended to the tail of the `Cisco` list, due to the use of the `+=` operator.
+
+The relative attributes work fairly simply, subject to the following rules:
+
+* a relative attribute `.foo` *must* have a structural attribute before it
+* a relative attribute `.foo` *must* be a child of the previous structural atrribute
+* an absolute attribute can be used at any point, even if the previous attribute as relative.
+* using an absolute attribute will "reset" the reference for relative attributes, to be either itself (if it is structural), or nothing (if it is a leaf)
+* relative attributes can use multiple `.` to reference attributes "higher" in the tree
+
+.Using multiple '.'
+----
+bob Password.Cleartext := "hello"
+ Vendor-Specific = "",
+ .Cisco = "",
+ .AVPair += "Hello",
+ ..HP = "",
+ .Privilege-Level += 1
+----
+
+In general, intermediate relative attributes should use `= ""`, as with the `.Cisco` example above. The final "leaf" attribute should use `+=`.
+
=== 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.
# Where `<driver>` is cassandra, db2, firebird, freetds, null, mysql
# oracle, postgresql, sqlite and unixodbc.
#
+# For authorization queries, the default schema mirrors the
+# functionality of the `files` module, including check items and
+# reply items. See the
+# doc/antora/modules/raddb/pages/mods-config/files/users.adoc file
+# documentation for information on the format of the check items and
+# reply items.
+#
#
# ## Configuration Settings