This file is indexed.

/etc/freeradius/3.0/mods-available/expr is in freeradius-config 3.0.16+dfsg-1ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# -*- text -*-
#
#  $Id: 663a9f47b9fac5e43ef6bb165aab31ecbf75d339 $

#
#  This module performs mathematical calculations:
#
#	Attribute-Name = "%{expr:2 + 3 + &NAS-Port}"
#
#  It supports the following operators (in order of precedence)
#
#	&	binary AND
#	|	binary OR
#	<<	left shift
#	>>	right shift
#	+	addition
#	-	subtraction
#	*	multiply
#	/	divide
#	%%	remainder
#	^	exponentiation
#	(...)	sub-expression
#
#  Operator precedence follows the normal rules.
#  Division by zero means that the entire expression is invalid.
#
#  Note that in versions before 3.0.5, the expression
#  was parsed strictly left to right, and ignored operator
#  precedence.
#
#  It also allows unary negation:	-1
#  And twos complement:			~1
#
#  All calculations are done on signed 63-bit integers.
#  e.g. int64_t.  This should be sufficient for all normal
#  purposes.
#
#  Hex numbers are supported:		0xabcdef
#
#  As with all string expansions, you can nest the expansions:
#
#	%{expr: %{NAS-Port} + 1}
#	%{expr: %{sql:SELECT ... } + 1}
#
#  Attribute references are supported for integer attributes.
#  e.g. &NAS-Port.  The benefit of using attribute references
#  is that the expression is calculated directly on the
#  attribute.  It skips the step of "print to string, and then
#  parse to number".  This means it's a little faster.
#
#  Otherwise, all numbers are decimal.
#

#
#  The module also registers a few paircompare functions, and
#  many string manipulation functions, including:
#
#  rand		get random number from 0 to n-1
#		"%{rand:10}" == "9"
#
#  randstr	get random string built from character classes:
#			c lowercase letters
#			C uppercase letters
#			n numbers
#			a alphanumeric
#			! punctuation
#			. alphanumeric + punctuation
#			s alphanumeric + "./"
#			o characters suitable for OTP (easily confused removed)
#			h binary data as lowercase hex
#			H binary data as uppercase hex
#
#		"%{randstr:CCCC!!cccnnn}" == "IPFL>{saf874"
#		"%{randstr:oooooooo}" == "rfVzyA4y"
#		"%{randstr:hhhh}" == "68d60de3"
#
#  urlquote	quote special characters in URI
#		"%{urlquote:http://example.org/}" == "http%3A%47%47example.org%47"
#
#  urlunquote	unquote URL special characters
#		"%{urlunquote:http%%3A%%47%%47example.org%%47}" == "http://example.org/"
#
#  escape	escape string similar to rlm_sql safe_characters
#		"%{escape:<img>foo.jpg</img>}" == "=60img=62foo.jpg=60/img=62" 
#
#  unescape	reverse of escape
#		"%{unescape:=60img=62foo.jpg=60/img=62}" == "<img>foo.jpg</img>"
#
#  tolower	convert to lowercase
#		"%{tolower:Bar}" == "bar"
#
#  toupper	convert to uppercase
#		"%{toupper:Foo}" == "FOO"
#
#  md5		get md5sum hash
#		"%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8"
#		
#  sha1		get sha1 hash
#		"%{sha1:foo}" == "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
#
#  sha256	get sha256 hash
#		"%{sha256:foo}" == "2c26b46b68ffc68ff99b453c1d30413413422d706..."
#
#  sha512	get sha512 hash
#		"%{sha512:foo}" == "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae29838..."
#
#  hmacmd5	generate HMAC-MD5 of string
#		"%{hmacmd5:foo bar}" == "31b6db9e5eb4addb42f1a6ca07367adc"
#
#  hmacsha1	generate HMAC-SHA1 of string
#		"%{hmacsha1:foo bar}" == "85d155c55ed286a300bd1cf124de08d87e914f3a"
#
#  pairs	serialize attributes as comma-delimited string
#		"%{pairs:request:}" == "User-Name = 'foo', User-Password = 'bar', ..."
#
#  base64	encode string as base64
#		"%{base64:foo}" == "Zm9v"
#
#  base64tohex	convert base64 to hex
#		"%{base64tohex:Zm9v}" == "666f6f"
#
#  explode	split an attribute into multiple new attributes based on a delimiter
#		"%{explode:&ref <delim>}"
#
#  nexttime	calculate number of seconds until next n hour(s), day(s), week(s), year(s)
#		if it were 16:18, %{nexttime:1h} would expand to 2520
#
#  lpad		left-pad a string
#		if User-Name is "foo": "%{lpad:&User-Name 6 x}" == "xxxfoo"
#
#  rpad		right-pad a string
#		if User-Name is "foo": "%{rpad:&User-Name 5 -}" == "foo--"
#

expr {
	#
	# Characters that will not be encoded by the %{escape}
	# xlat function.
	#
	safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /äéöüàâæçèéêëîïôœùûüaÿÄÉÖÜßÀÂÆÇÈÉÊËÎÏÔŒÙÛÜŸ"
}