From: Alan T. DeKok Date: Tue, 5 Jul 2022 12:22:06 +0000 (-0400) Subject: more docs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a996b69adadfa00d9f514e6c0460a0591199002b;p=thirdparty%2Ffreeradius-server.git more docs --- diff --git a/doc/antora/modules/reference/nav.adoc b/doc/antora/modules/reference/nav.adoc index feb51d0d7d4..790aa85fde6 100644 --- a/doc/antora/modules/reference/nav.adoc +++ b/doc/antora/modules/reference/nav.adoc @@ -49,6 +49,7 @@ ** xref:type/index.adoc[Data Types] *** xref:type/index.adoc[List of Data Types] +*** xref:type/cast.adoc[Casts] *** xref:type/ip.adoc[IP Addresses] *** xref:type/numb.adoc[Numbers] *** xref:type/string/single.adoc[Single Quoted Strings] diff --git a/doc/antora/modules/reference/pages/type/cast.adoc b/doc/antora/modules/reference/pages/type/cast.adoc new file mode 100644 index 00000000000..96c77b4e12a --- /dev/null +++ b/doc/antora/modules/reference/pages/type/cast.adoc @@ -0,0 +1,69 @@ += Casts + +Values can be *cast* from one data type to another. However, this +cast only changes the _type_ of the data, it does not change the datas +_value_. That is, a cast allows you to convert an `octets` data type +to a `string`, but the resulting `string` may still contain +non-printable characters. + +Casting is used when the server is unable to automatically figure out +the correct data type to use. For example, in the following +expansion, it is not immediately obvious that the right side of the +expression is an IP address. It could instead be interpreted as a string +`"192.0.2.1"`. + +[source,unlang] +---- +if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == 192.0.2.1) } + .... +} +---- + +Since there is no attribute reference on either side of the `==` +operator, the interpreter has no way of knowing that the string +`192.0.2.1` is an IP address. There is unfortunately no way of +_always_ parsing strings in order to automatically determine which +data type to use. Any such automatic parsing would work most of the +time, but it would have error cases where the parsing was incorrect. + +The solution is to resolve these ambiguities by allowing the values to +be cast to a particular type. Casting a value to a type tells the +interpreter how that value should be parsed. Casting is done by +prefixing a value with the type name, surrounded by brackets; +`(...)`. + +.Syntax +---- +(...)value +---- + +We can add a cast to the above example, as follows: + +[source,unlang] +---- +if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == (ipaddr)192.0.2.1) } + .... +} +---- + +In this example, we prefix the IP address with the string `(ipaddr)`. +The interpreter then knows that the value `192.0.2.` should be +interpreted as the data type `ipaddr`, and not as the literal string +`"192.0.2."`. + +For a full list of data types which can be used in a cast, please see +the xref:unlang/type/all_types.adoc[list of data types] page, and the +"Basic Type Types" section. + +In most cases, the server can automatically determine what data type +to use. The cast syntax is used when either the data type is +ambiguous, or when data should be normalized prior to comparison, or +when a specific data type is required. + +=== Compatibility + +For compatibility with version 3, the `` syntax is also +supported. We recommend, however, that people use the new syntax. + +// Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +// Development of this documentation was sponsored by Network RADIUS SAS. diff --git a/doc/antora/modules/reference/pages/type/double.adoc b/doc/antora/modules/reference/pages/type/double.adoc index a824d81fe01..ee5af7e6c0c 100644 --- a/doc/antora/modules/reference/pages/type/double.adoc +++ b/doc/antora/modules/reference/pages/type/double.adoc @@ -22,7 +22,7 @@ The output of the dynamic expansion can be interpreted as a string, a number, or an IP address, depending on its context. Note that the interpretation of text _strongly_ depends on the -context. The text `"0000"` can be interpreted as a data type +context. The text `0000` can be interpreted as a data type "integer", having value zero, or a data type "string", having value `"0000"`. In general when a particular piece of text is used, it is used with the context of a known attribute. That attribute has a @@ -35,5 +35,66 @@ data type. `"a string"` + `"this has embedded\ncharacters"` +== Methods of Creating Strings + +There are a few different ways in which double-quoted strings can be +created. The simplest is just an in-line string, as in `"string"`. +However, strings can also be created via +xref:unlang/expression.adoc[expressions]. and +xref:xlat/index.adoc[dynamic expansions]. + +In general, creating strings via xref:xlat/index.adoc[dynamic +expansions] will result in the _printed_ version of the expansion +being used. + +.Example +[source,unlang] +---- +"User-Name is %{User-Name}" +"IP Address is %{reply.Framed-IP-Address} +---- + +Both of the above expansions will return the _printed_ version of the +expansion. For `User-Name`, it will be the string version of the +users name, as would be expected. However, for the +`Framed-IP-Address` example, the printed version will be an ASCII +string such as `192.0.2.1`, even though the actual IP address is a +32-bit number. + +When a string is created via an +xref:unlang/expression.adoc[expression] using the `+` operator, the +resulting string can be quite different, depending on the inputs. + +.Example +[source,unlang] +---- +"User-Name is " + &User-Name +"IP Address is " + (string) &reply.Framed-IP-Address +---- + +The first expansion here returns the same string as the previous +example `"User-Name is %{User-Name}"`. This behavior is because the +`User-Name` attribute is defined as type `string`. So appending a +`string` to a `string` yields a `string`. + +However, the second example returns the string `"IP Address is "` +followed by four (4) bytes of the actual IP address, with embedded +zeros, and other non-ASCII characters + +This behavior is because the xref:type/cast.doc[cast] operator +`(string)` will convert the data type from `ipv4addr` to `string`, but +it will not change or modify the _contents_ of the data. The result +of the `+` concatenation is therefore the original `string`, followed +by the 4 bytes of the `ipv4addr` data. + +If the printed version of the data is needed, the expansion should be +enclosed in double-quotes, as in the first example. + +=== To Remember + +`"foo" + (string) &Bar` produces `"foo"` plus `&Bar` _cast_ to a string. + +`"foo%{Bar}"` produces `"foo"` plus `&Bar` _printed_ to a string. + // Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0. // Development of this documentation was sponsored by Network RADIUS SAS. diff --git a/doc/antora/modules/reference/pages/type/index.adoc b/doc/antora/modules/reference/pages/type/index.adoc index c054a094e71..9bf7447bb78 100644 --- a/doc/antora/modules/reference/pages/type/index.adoc +++ b/doc/antora/modules/reference/pages/type/index.adoc @@ -66,62 +66,11 @@ comparisons, for all attributes and data types. === Casting Data Types -In some cases, it is necessary to parse values which do not refer to -attributes. This situation usually occurs when two values need to be -compared, as in the following example: - -[source,unlang] ----- -if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == 192.0.2.1) } - .... -} ----- - -Since there is no attribute on either side of the `==` operator, the -interpreter has no way of knowing that the string `192.0.2.1` is an IP -address. There is unfortunately no way of automatically parsing -strings in order to determine the data type to use. Any such -automatic parsing would work most of the time, but it would have -error cases where the parsing was incorrect. - -The solution is to resolve these ambiguities by allowing the values to -be cast to a particular type. Casting a value to a type tells the -interpreter how that value should be parsed. Casting is done by -prefixing a value with the type name, surrounded by brackets; -`(...)`. - -.Syntax ----- -(...)value ----- - -We can add a cast to the above example, as follows: - -[source,unlang] ----- -if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == (ipaddr)192.0.2.1) } - .... -} ----- - -In this example, we prefix the IP address with the string `(ipaddr)`. -The interpreter then knows that the value `192.0.2.` should be -interpreted as the data type `ipaddr`, and not as the literal string -`"192.0.2."`. - -For a full list of data types which can be used in a cast, please see -the xref:unlang/type/all_types.adoc[list of data types] page, and the -"Basic Type Types" section. - -In most cases, the server can automatically determine what data type -to use. The cast syntax is used when either the data type is -ambiguous, or when data should be normalized prior to comparison, or -when a specific data type is required. - -=== Compatibility - -For compatibility with version 3, the `` syntax is also -supported. We recommend, however, that people use the new syntax. +Values can be xref:type/cast.adoc[cast] from one data type to another. +However, this cast only changes the _type_ of the data, it does not +change the datas _value_. That is, a cast allows you to convert an +`octets` data type to a `string`, but the resulting `string` may still +contain non-printable characters. // Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0. // Development of this documentation was sponsored by Network RADIUS SAS. diff --git a/doc/antora/modules/reference/pages/unlang/expression.adoc b/doc/antora/modules/reference/pages/unlang/expression.adoc index d99ffa6fc3d..ae47ecf25d5 100644 --- a/doc/antora/modules/reference/pages/unlang/expression.adoc +++ b/doc/antora/modules/reference/pages/unlang/expression.adoc @@ -75,6 +75,10 @@ The suffix can then be "subtracted" off, with: Will result in `&Reply-Message == "foo"` !. +Note that the `-=` operator behaves differently from earlier versions +of the server! Since the server no longer needs `update` sections, we +could re-purpose the operator. + Other data types will generally yield results which make sense. For example: @@ -106,5 +110,13 @@ deprecated. Mathematical operations which cause overflow, underflow, or division by zero will return a `null` result. This result will propagate through any calculations, so that an expression which relies on `null` -will also return `null`. +will generally also return `null`. + +A `null` result can be removed via the `||` operator. For example: + +[source,unlang] +---- +&NAS-Port-Id = (5 - "foo") || 6 +---- +Will return `6`, as the left side expression of the `||` operator evaluates to `null`. diff --git a/doc/antora/modules/reference/pages/xlat/index.adoc b/doc/antora/modules/reference/pages/xlat/index.adoc index 0ba53685a10..31089f8d860 100644 --- a/doc/antora/modules/reference/pages/xlat/index.adoc +++ b/doc/antora/modules/reference/pages/xlat/index.adoc @@ -4,13 +4,17 @@ Dynamic expansion is a feature that allows values to be dynamically expanded at run time. For historical reasons, these string expansions are called "xlats". -Dynamioc expansion is performed via the following syntax: +Dynamic expansion is performed via the following syntax: `%{...}` Where the `%{` signals the start of a dynamic expansion, and `}` -signals the end of the dynamic expansion. The contents of the -expansion can be many things: +signals the end of the dynamic expansion. Dynamic expansions are most +commonly used in xref:type/string/double.adoc[double-quoted strings], +and xref:unlang/expression.adoc[expressions / conditions]. + +The contents of an expansion can be many things, such as attribute +references, function calls, etc. The table below gives more examples of expansions. .Types of Expansions [options="header"] @@ -20,23 +24,20 @@ expansion can be many things: | xref:xlat/character.adoc[single character] | Single character expansions. | xref:xlat/module.adoc[modules] | Pass a string to a module such as `sql`. | xref:xlat/alternation.adoc[condition] | Conditionally expand a string. -| xref:xlat/builtin.adoc[built-in expansions] | Such as string length, tolower, etc... +| xref:xlat/builtin.adoc[built-in expansions] | Functions as string length, tolower, etc... |===== -This feature is used to create policies which refer to concepts rather -than to specific values. For example, a policy can be created that -refers to the User-Name in a request, via: - -`%{User-Name}` - -This expansion is done only for double-quoted strings and for -the back-tick operator. +Expansions are used inside of +xref:type/string/double.adoc[double-quoted strings] and for the +xref:string/backticks.adoc[back-tick quoted strings] == Caveats Unlike other languages, there is no way to define new variables. All -of the expansions must refer to attributes that already exist, -or to modules that will return a string value. +of the expansions must refer to attributes that already exist, or to +pre-defined functions which take arguments, and return values. + +New variables are defined in the xref:raddb:dictionary.adoc[site-local dictionaries]. == Character Escaping @@ -44,9 +45,12 @@ Some characters need to be escaped within a dynamically expanded string `%{...}`. The `%` character is used for variable expansion, so a literal `%` character can be created by using `%%`. -Other than within a dynamically expanded string, very little -character escaping is needed. The rules of the enclosing string context -determine whether or not a space or " character needs to be escaped. +Other than within a dynamically expanded string, very little character +escaping is needed. The rules of the enclosing string context +determine whether or not a space or `"` character needs to be escaped. +See the ref:type/string/double.adoc[double-quoted strings] and +xref:string/backticks.adoc[back-tick quoted strings] pages for more +information. .Example