Codebase list freeradius / 3af10be
New upstream version 3.0.21+dfsg Bernhard Schmidt 4 years ago
108 changed file(s) with 4006 addition(s) and 1785 deletion(s). Raw diff Collapse all Expand all
4141 files for more detailed copyright statements.
4242
4343
44 Copyright (C) 1999-2019 The FreeRADIUS Server Project
44 Copyright (C) 1999-2020 The FreeRADIUS Server Project
4545
4646 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Alan DeKok
4747 <aland@deployingradius.com>
3232 #
3333 ifneq "$(MAKECMDGOALS)" "deb"
3434 ifneq "$(MAKECMDGOALS)" "rpm"
35 ifeq "$(findstring docker,$(MAKECMDGOALS))" ""
36 ifeq "$(findstring crossbuild,$(MAKECMDGOALS))" ""
3537 $(if $(wildcard Make.inc),,$(error Missing 'Make.inc' Run './configure [options]' and retry))
3638
3739 include Make.inc
40 endif
41 endif
3842 endif
3943 endif
4044
5155 # And over-ride all of the other magic.
5256 ifneq "$(MAKECMDGOALS)" "deb"
5357 ifneq "$(MAKECMDGOALS)" "rpm"
58 ifeq "$(findstring docker,$(MAKECMDGOALS))" ""
59 ifeq "$(findstring crossbuild,$(MAKECMDGOALS))" ""
5460 include scripts/boiler.mk
61 endif
62 endif
5563 endif
5664 endif
5765
282290 # high-level targets
283291 .PHONY: dist-check
284292 dist-check: redhat/freeradius.spec suse/freeradius.spec debian/changelog
285 @if [ `grep ^Version: redhat/freeradius.spec | sed 's/.*://;s/ //'` != "$(RADIUSD_VERSION_STRING)" ]; then \
286 cat redhat/freeradius.spec | sed 's/^Version: .*/Version: $(RADIUSD_VERSION_STRING)/' > redhat/.foo; \
293 @if [ `grep ^Version: redhat/freeradius.spec | sed 's/.*://;s/ //g'` != "$(RADIUSD_VERSION_STRING)" ]; then \
294 cat redhat/freeradius.spec | sed 's/^Version:.*/Version: $(RADIUSD_VERSION_STRING)/' > redhat/.foo; \
287295 mv redhat/.foo redhat/freeradius.spec; \
288296 echo redhat/freeradius.spec 'Version' needs to be updated; \
289297 exit 1; \
290298 fi
291 @if [ `grep ^Version: suse/freeradius.spec | sed 's/.*://;s/ //'` != "$(RADIUSD_VERSION_STRING)" ]; then \
292 cat suse/freeradius.spec | sed 's/^Version: .*/Version: $(RADIUSD_VERSION_STRING)/' > suse/.foo; \
299 @if [ `grep ^Version: suse/freeradius.spec | sed 's/.*://;s/ //g'` != "$(RADIUSD_VERSION_STRING)" ]; then \
300 cat suse/freeradius.spec | sed 's/^Version: .*/Version: $(RADIUSD_VERSION_STRING)/' > suse/.foo; \
293301 mv suse/.foo suse/freeradius.spec; \
294302 echo suse/freeradius.spec 'Version' needs to be updated; \
295303 exit 1; \
296304 fi
297 @if [ `head -n 1 debian/changelog | sed 's/.*(//;s/-0).*//;s/-1).*//;s/\+.*//'` != "$(RADIUSD_VERSION_STRING)" ]; then \
305 @if [ `head -n 1 doc/ChangeLog | awk '/^FreeRADIUS/{print $$2}'` != "$(RADIUSD_VERSION_STRING)" ]; then \
306 echo doc/ChangeLog needs to be updated; \
307 exit 1; \
308 fi
309 @if [ `head -n 1 debian/changelog | sed 's/.*(//;s/-0).*//;s/-1).*//;s/\+.*//'` != "$(RADIUSD_VERSION_STRING)" ]; then \
298310 echo debian/changelog needs to be updated; \
299311 exit 1; \
300312 fi
301313
302314 dist: dist-check freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz freeradius-server-$(RADIUSD_VERSION_STRING).tar.bz2
303315
304 dist-sign: freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz.sig freeradius-server-$(RADIUSD_VERSION_STRING).tar.bz2.sig
316 dist-sign: dist-check freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz.sig freeradius-server-$(RADIUSD_VERSION_STRING).tar.bz2.sig
305317
306318 dist-publish: freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz.sig freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz.sig freeradius-server-$(RADIUSD_VERSION_STRING).tar.bz2 freeradius-server-$(RADIUSD_VERSION_STRING).tar.gz.sig freeradius-server-$(RADIUSD_VERSION_STRING).tar.bz2.sig
307319 scp $^ freeradius.org@ftp.freeradius.org:public_ftp
314326 @echo "git tag release_`echo $(RADIUSD_VERSION_STRING) | tr .- __`"
315327
316328 #
317 # Docker-related targets
318 #
319 .PHONY: docker
320 docker:
321 docker build scripts/docker/ubuntu18 --build-arg=release=release_`echo $(RADIUSD_VERSION_STRING) | tr .- __` -t freeradius/freeradius-server:$(RADIUSD_VERSION_STRING)
322 docker build scripts/docker/alpine --build-arg=release=release_`echo $(RADIUSD_VERSION_STRING) | tr .- __` -t freeradius/freeradius-server:$(RADIUSD_VERSION_STRING)-alpine
323
324 .PHONY: docker-push
325 docker-push: docker
326 docker push freeradius/freeradius-server:$(RADIUSD_VERSION_STRING)
327 docker push freeradius/freeradius-server:$(RADIUSD_VERSION_STRING)-alpine
328
329 .PHONY: docker-tag-latest
330 docker-tag-latest: docker
331 docker tag freeradius/freeradius-server:$(RADIUSD_VERSION_STRING) freeradius/freeradius-server:latest
332 docker tag freeradius/freeradius-server:$(RADIUSD_VERSION_STRING)-alpine freeradius/freeradius-server:latest-alpine
333
334 .PHONY: docker-push-latest
335 docker-push-latest: docker-push docker-tag-latest
336 docker push freeradius/freeradius-server:latest
337 docker push freeradius/freeradius-server:latest-alpine
338
339 .PHONY: docker-publish
340 docker-publish: docker-push-latest
329 # Docker-related targets (main docker images and crossbuild)
330 #
331 ifneq "$(findstring docker,$(MAKECMDGOALS))" ""
332 include scripts/docker/docker.mk
333 endif
334
335 ifneq "$(findstring crossbuild,$(MAKECMDGOALS))" ""
336 include scripts/crossbuild/crossbuild.mk
337 endif
341338
342339 #
343340 # Build a debian package
0 3.0.20
0 3.0.21
87798779 sys/event.h \
87808780 sys/fcntl.h \
87818781 sys/prctl.h \
8782 sys/procctl.h \
87828783 sys/ptrace.h \
87838784 sys/resource.h \
87848785 sys/security.h \
11501150 sys/event.h \
11511151 sys/fcntl.h \
11521152 sys/prctl.h \
1153 sys/procctl.h \
11531154 sys/ptrace.h \
11541155 sys/resource.h \
11551156 sys/security.h \
0 FreeRADIUS 3.0.21 Tue 24 Mar 2020 12:00:00 EDT urgency=low
1 Feature improvements
2 * New stored procedure for allocating IPs with PostgreSQL.
3 Rates of 1500 IPs per second are now possible.
4 See raddb/mods-config/sql/ippool/postgresql/procedure.sql
5 Patch from Terry Burton.
6 * Add SQL IP pool support for Microsoft SQL Server
7 See raddb/mods-config/sql/ippool/mssql/
8 Patch from Terry Burton.
9 * Added RCNTEC dictionary. Closes #3168.
10 * Added Pica8 dictionary. Closes #3179.
11 * Add TLS-Client-Cert-Valid-Since attribute holding notBefore date.
12 Patch from Boris Lytochkin. Fixes #3157.
13 * Generate attributes containing unknown OIDs.
14 See raddb/sites-available/tls. Patch from Boris Lytochkin.
15 * Update the WiMAX dictionary.
16 * Added ability to rlm_python(Python2) show a stacktrace from errors. #2979
17 * Add WiFi Alliance Policy OIDs. See raddb/certs/xpextensions
18 Patch from Stefan Winter.
19 * radmin now shows coa stats, too.
20 * Sample schema extensions for summarizing data in SQL.
21 See mods-config/sql/main/*/process-radacct.sql
22 Many patches from Terry Burton.
23 * Update dictionary.aerohive, dictionary.fortinet,
24 dictionary.arista and dictionary.erx
25 * Added VAS Experts dictionary.
26 * Many updates to RPM and jenkins builds from Matthew Newton
27 * Added %C (time now in seconds) and %c (microsecond component of now)
28 back-ported from the "master" branch.
29 * Add reload capability to systemd unit file in Debian and RedHat.
30 * Increase timestamp precision in postauth to maximum supported by each
31 database and simplify (and make more consistent between drivers) the
32 timestamps in SQL queries by using expansions.
33 Patches from Terry Burton.
34 * Option to set dictionary path in raduat script. Patch from Terry Burton.
35
36 Bug fixes
37 * Various fixes found by PVS-Studio.
38 * Set permissions of certificates in bootstrap shell script.
39 Fixes #3132.
40 * Increase the 'nasportid' SQL field for 'varchar(32)'. #3141
41 * Skip processing proxy reply if there are no home servers
42 available.
43 * Update SQLite IPPool queries. Fixes #3177
44 Patch from Terry Burton.
45 * rlm_sql_unixodbc fixes. Patches from Terry Burton. Fixes #2822
46 * Fixes when building with LibreSSL. Patch from Nathan Owens.
47 * Fix the rlm_python3 build. Note that this module is experimental. #3183
48 * The rlm_python should append the 'python_path' paths in 'sys.path',
49 It fixes the expected behavior to use the existing Python modules.
50 Fixes #3180
51 * Fix rlm_python to print the script errors properly.
52 * Bound total query time for PostgreSQL. Fixes #3253
53 * Many fixes to Oracle sqlippool. It now does 500 IPs per second
54 without any tuning. Fixes #3270.
55 * Reference sqlippool by it's correct name. Fixes #3272
56 * Revert 3.0.20 patch which caused crashes on duplicate clients.
57 * Update WiMAX-MSK attribute. Fixes #3280.
58 * Fix crash when trying to access non-existant regex capture group.
59 * Use timestamps (request or server) rather than SQL NOW() in
60 accounting queries so that these are stable when replayed from a
61 file buffer.
62 Patches from Terry Burton.
63
064 FreeRADIUS 3.0.20 Thu 14 Nov 2019 12:00:00 EDT urgency=medium
165 Feature improvements
266 * Add Jenkins continuous integration. Fixes #2620.
5353 Print packet headers only, not contents.
5454 .IP \-p\ \fIport\fP
5555 \tListen for packets on port.
56 .IP \-r\ \fIresponse-filter\fP
56 .IP \-r\ \fIattribute-filter\fP
5757 RADIUS attribute request filter.
58 .IP \-R\ \fIrequest-filter\fP
58 .IP \-R\ \fIattribute-filter\fP
5959 RADIUS attribute response filter.
6060 .IP \-s\ \fIsecret\fP
6161 RADIUS secret.
4141
4242 if [ ! -f server.key ]; then
4343 openssl req -new -out server.csr -keyout server.key -config ./server.cnf || exit 1
44 chmod g+r server.key
4445 fi
4546
4647 if [ ! -f ca.key ]; then
6162
6263 if [ ! -f server.p12 ]; then
6364 openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -passin pass:`grep output_password server.cnf | sed 's/.*=//;s/^ *//'` -passout pass:`grep output_password server.cnf | sed 's/.*=//;s/^ *//'` || exit 1
65 chmod g+r server.p12
6466 fi
6567
6668 if [ ! -f server.pem ]; then
6769 openssl pkcs12 -in server.p12 -out server.pem -passin pass:`grep output_password server.cnf | sed 's/.*=//;s/^ *//'` -passout pass:`grep output_password server.cnf | sed 's/.*=//;s/^ *//'` || exit 1
6870 openssl verify -CAfile ca.pem server.pem || exit 1
71 chmod g+r server.pem
6972 fi
7073
7174 if [ ! -f ca.der ]; then
7477
7578 if [ ! -f client.key ]; then
7679 openssl req -new -out client.csr -keyout client.key -config ./client.cnf
80 chmod g+r client.key
7781 fi
7882
7983 if [ ! -f client.crt ]; then
1313 extendedKeyUsage = 1.3.6.1.5.5.7.3.1
1414 crlDistributionPoints = URI:http://www.example.com/example_ca.crl
1515
16 # Enterprise Wi-Fi clients from 2020 onwards which have the
17 # Wi-Fi Certified WPA3 Release 2 (December 2019) certification
18 # honour the following two policies for enhanced security
19 # posture regarding certificate validation:
20 #
21 # https://www.wi-fi.org/discover-wi-fi/security
22 #
23 # Adding the 'Trust Override Disabled - STRICT' policy means that
24 # the client device is not allowed to request and accept ad-hoc
25 # trust decisions from the user ("Is this the certificate you
26 # expect here?") and instead aborts authentication until the
27 # device has been properly configured using out-of-band means
28 # with all the details needed to verify the certificate (i.e.
29 # either the tuple (CA, server name) or the literal server cert).
30 #
31 # Adding the 'Trust Override Disabled - TOFU' policy means that
32 # the client device is allowed to ask the end user for such an
33 # override exactly once, when first connecting to an unknown
34 # network. Once the network is known and the trust decision made,
35 # any other certificate that is presented and would require
36 # another override is rejected and authentication aborted.
37 #
38 # Both of these policies provide a protection against rogue
39 # authentication servers in that they make sure configurations
40 # on end user devices are sufficient to identify the genuine
41 # server.
42 #
43 # The difference is that the TOFU policy allows a leap of faith
44 # on first sight of a network ONCE - very much comparable to
45 # how SSH establishes trust in a new host. This adds convenience
46 # for end users who did not bother to configure their devices
47 # beforehand, but adds an element of uncertainty in that the
48 # attacker could be present on that first contact with the network.
49 #
50 # Network administrators who consider the TOFU leap of faith
51 # unacceptable should choose STRICT; everyone else gains security
52 # by choosing TOFU without giving up on convenience for their
53 # end users.
54 #
55 # For completeness, it is also possible to include none of the
56 # two to stay with the "anything goes" that was the situation
57 # prior to Wi-Fi Certified WPA3 Release December 2019.
58 #
59 # This is the 'Trust Override Disabled - STRICT' policy.
60 #certificatePolicies = 1.3.6.1.4.1.40808.1.3.1
61 # This is the 'Trust Override Disabled - TOFU' policy.
62 certificatePolicies = 1.3.6.1.4.1.40808.1.3.2
63
1664 #
1765 # Add this to the PKCS#7 keybag attributes holding the client's private key
1866 # for machine authentication.
1212 # item is GLOBAL TO THE SERVER. That is, you cannot have two
1313 # instances of the python module, each with a different path.
1414 #
15 # python_path="/path/to/python/files:/another_path/to/python_files/"
15 # python_path="${modconfdir}/${.:name}:/path/to/python/files:/another_path/to/python_files/"
1616
1717 module = example
1818
1212 # item is GLOBAL TO THE SERVER. That is, you cannot have two
1313 # instances of the python module, each with a different path.
1414 #
15 # python_path="/path/to/python/files:/another_path/to/python_files/"
15 # python_path="${modconfdir}/${.:name}:/another_path/to/python_files"
1616
1717 module = example
1818
1010 # Host where the redis server is located.
1111 # We recommend using ONLY 127.0.0.1 !
1212 server = 127.0.0.1
13
14 # Select the Redis logical database having the specified zero-based numeric index.
15 # database = 0
1316
1417 # The default port.
1518 port = 6379
5555 # rlm_sql_freetds
5656 # rlm_sql_iodbc
5757 # rlm_sql_unixodbc
58 # rlm_sql_mongo
5958 #
6059 driver = "rlm_sql_null"
6160 # driver = "rlm_sql_${dialect}"
246245 # connection pool, use "pool = name" instead of a "pool"
247246 # section. e.g.
248247 #
249 # sql1 {
248 # sql sql1 {
250249 # ...
251250 # pool {
252251 # ...
254253 # }
255254 #
256255 # # sql2 will use the connection pool from sql1
257 # sql2 {
256 # sql sql2 {
258257 # ...
259258 # pool = sql1
260259 # }
149149 # an already existing name-value pair.
150150 #
151151
152 #
153 # Set up different IP address pools for the terminal servers.
154 # Note that the "+" behind the IP address means that this is the "base"
155 # IP address. The Port-Id (S0, S1 etc) will be added to it.
156 #
157 #DEFAULT Service-Type == Framed-User, Huntgroup-Name == "alphen"
158 # Framed-IP-Address = 192.0.2.32+,
159 # Fall-Through = Yes
160
161 #DEFAULT Service-Type == Framed-User, Huntgroup-Name == "delft"
162 # Framed-IP-Address = 198.51.100.32+,
163 # Fall-Through = Yes
164
165 #
166152 # Sample defaults for all framed connections.
167153 #
168154 #DEFAULT Service-Type == Framed-User
22 # ippool/mongo/queries.conf -- Mongo queries for rlm_sqlippool
33 #
44 # $Id$
5
6 #
7 # The IP Pool queries expect a result like:
8 #
9 # {
10 # pool_key: "bob"
11 # pool_name: "my_pool"
12 # expiry_time: xxx
13 # value: "192.168.1.1"
14 # }
15 #
16 # i.e. the results are in "value", and not "framed_ip_address".
17 #
18 # When using dynamic expansions such as "%{sql:... mongo query ...}",
19 # Mongo uses a lot of curly brackets, {..}. Any closing braces have
20 # to be escaped as %}. Sorry, that is a limitation of the FreeRADIUS
21 # parser.
22 #
523
624 #
725 # TBD
1937 'query': {' \
2038 '$and': [ \
2139 { \
22 'pool_name': '{Control:Pool-Name}' \
40 'pool_name': '%{control:Pool-Name}' \
2341 }, \
2442 { \
2543 'nas_ip': '%{Nas-IP-Address}' \
0 --
1 -- A stored procedure to reallocate a user's previous address, otherwise
2 -- provide a free address.
3 --
4 -- Using this SP reduces the usual set dialogue of queries to a single
5 -- query:
6 --
7 -- BEGIN TRAN; "SELECT FOR UPDATE"; UPDATE; COMMIT TRAN; -> EXEC sp
8 --
9 -- The stored procedure is executed on an database instance within a single
10 -- round trip which often leads to reduced deadlocking and significant
11 -- performance improvements especially on multi-master clusters, perhaps even
12 -- by an order of magnitude or more.
13 --
14 -- To use this stored procedure the corresponding queries.conf statements must
15 -- be configured as follows:
16 --
17 -- allocate_begin = ""
18 -- allocate_find = "\
19 -- EXEC fr_allocate_previous_or_new_framedipaddress \
20 -- @v_pool_name = '%{control:${pool_name}}', \
21 -- @v_username = '%{User-Name}', \
22 -- @v_callingstationid = '%{Calling-Station-Id}', \
23 -- @v_nasipaddress = '%{NAS-IP-Address}', \
24 -- @v_pool_key = '${pool_key}', \
25 -- @v_lease_duration = ${lease_duration} \
26 -- "
27 -- allocate_update = ""
28 -- allocate_commit = ""
29 --
30
31 CREATE INDEX UserName_CallingStationId ON radippool(pool_name,UserName,CallingStationId)
32 GO
33
34 CREATE OR ALTER PROCEDURE fr_allocate_previous_or_new_framedipaddress
35 @v_pool_name VARCHAR(64),
36 @v_username VARCHAR(64),
37 @v_callingstationid VARCHAR(64),
38 @v_nasipaddress VARCHAR(15),
39 @v_pool_key VARCHAR(64),
40 @v_lease_duration INT
41 AS
42 BEGIN
43
44 -- MS SQL lacks a "SELECT FOR UPDATE" statement, and its table
45 -- hints do not provide a direct means to implement the row-level
46 -- read lock needed to guarentee that concurrent queries do not
47 -- select the same Framed-IP-Address for allocation to distinct
48 -- users.
49 --
50 -- The "WITH cte AS ( SELECT ... ) UPDATE cte ... OUTPUT INTO"
51 -- patterns in this procedure body compensate by wrapping
52 -- the SELECT in a synthetic UPDATE which locks the row.
53
54 DECLARE @r_address_tab TABLE(id VARCHAR(15));
55 DECLARE @r_address VARCHAR(15);
56
57 BEGIN TRAN;
58
59 -- Reissue an existing IP address lease when re-authenticating a session
60 --
61 WITH cte AS (
62 SELECT TOP(1) FramedIPAddress
63 FROM radippool
64 WHERE pool_name = @v_pool_name
65 AND expiry_time > CURRENT_TIMESTAMP
66 AND UserName = @v_username
67 AND CallingStationId = @v_callingstationid
68 )
69 UPDATE cte WITH (rowlock, readpast)
70 SET FramedIPAddress = FramedIPAddress
71 OUTPUT INSERTED.FramedIPAddress INTO @r_address_tab;
72 SELECT @r_address = id FROM @r_address_tab;
73
74 -- Reissue an user's previous IP address, provided that the lease is
75 -- available (i.e. enable sticky IPs)
76 --
77 -- When using this SELECT you should delete the one above. You must also
78 -- set allocate_clear = "" in queries.conf to persist the associations
79 -- for expired leases.
80 --
81 -- WITH cte AS (
82 -- SELECT TOP(1) FramedIPAddress
83 -- FROM radippool
84 -- WHERE pool_name = @v_pool_name
85 -- AND UserName = @v_username
86 -- AND CallingStationId = @v_callingstationid
87 -- )
88 -- UPDATE cte WITH (rowlock, readpast)
89 -- SET FramedIPAddress = FramedIPAddress
90 -- OUTPUT INSERTED.FramedIPAddress INTO @r_address_tab;
91 -- SELECT @r_address = id FROM @r_address_tab;
92
93 -- If we didn't reallocate a previous address then pick the least
94 -- recently used address from the pool which maximises the likelihood
95 -- of re-assigning the other addresses to their recent user
96 --
97 IF @r_address IS NULL
98 BEGIN
99 WITH cte AS (
100 SELECT TOP(1) FramedIPAddress
101 FROM radippool
102 WHERE pool_name = @v_pool_name
103 AND ( expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL )
104 ORDER BY
105 expiry_time
106 )
107 UPDATE cte WITH (rowlock, readpast)
108 SET FramedIPAddress = FramedIPAddress
109 OUTPUT INSERTED.FramedIPAddress INTO @r_address_tab;
110 SELECT @r_address = id FROM @r_address_tab;
111 END
112
113 -- Return nothing if we failed to allocated an address
114 --
115 IF @r_address IS NULL
116 BEGIN
117 COMMIT TRAN;
118 RETURN;
119 END
120
121 -- Update the pool having allocated an IP address
122 --
123 UPDATE radippool
124 SET
125 NASIPAddress = @v_nasipaddress,
126 pool_key = @v_pool_key,
127 CallingStationId = @v_callingstationid,
128 UserName = @v_username,
129 expiry_time = DATEADD(SECOND,@v_lease_duration,CURRENT_TIMESTAMP)
130 WHERE framedipaddress = @r_address;
131
132 COMMIT TRAN;
133
134 -- Return the address that we allocated
135 SELECT @r_address;
136
137 END
138 GO
0 # -*- text -*-
1 #
2 # ippool/mssql/queries.conf -- MSSQL queries for rlm_sqlippool
3 #
4 # $Id$
5
6 # MSSQL-specific syntax
7 allocate_begin = "BEGIN TRAN"
8 allocate_commit = "COMMIT TRAN"
9
10 #
11 # This series of queries allocates an IP address
12 #
13 #allocate_clear = "\
14 # UPDATE ${ippool_table} \
15 # SET \
16 # NASIPAddress = '', \
17 # pool_key = 0, \
18 # CallingStationId = '', \
19 # UserName = '', \
20 # expiry_time = NULL \
21 # WHERE pool_key = '${pool_key}'"
22
23 #
24 # (Note: If your pool_key is set to Calling-Station-Id and not NAS-Port
25 # then you may wish to delete the "AND nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'
26 # from the WHERE clause)
27 #
28 allocate_clear = "\
29 UPDATE ${ippool_table} \
30 SET \
31 NASIPAddress = '', \
32 pool_key = 0, \
33 CallingStationID = '', \
34 UserName = '', \
35 expiry_time = NULL \
36 WHERE expiry_time <= DATEADD(SECOND,-1,CURRENT_TIMESTAMP) \
37 AND NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
38
39 #
40 # The ORDER BY clause of this query tries to allocate the same IP-address
41 # which user had last session...
42 #
43 allocate_find = "\
44 WITH cte AS ( \
45 SELECT TOP(1) FramedIPAddress FROM ${ippool_table} \
46 WHERE pool_name = '%{control:${pool_name}}' \
47 AND ( expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL ) \
48 OR ( NASIPAddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
49 ORDER BY \
50 CASE WHEN UserName = '%{User-Name}' THEN 0 ELSE 1 END, \
51 CASE WHEN CallingStationId = '%{Calling-Station-Id}' THEN 0 ELSE 1 END, \
52 expiry_time \
53 ) \
54 UPDATE cte WITH (rowlock, readpast) \
55 SET FramedIPAddress = FramedIPAddress \
56 OUTPUT INSERTED.FramedIPAddress"
57
58 #
59 # If you prefer to allocate a random IP address every time, use this query instead.
60 # Note: This is very slow if you have a lot of free IPs.
61 #
62 #allocate_find = "\
63 # WITH cte AS ( \
64 # SELECT TOP(1) FramedIPAddress FROM ${ippool_table} \
65 # WHERE pool_name = '%{control:${pool_name}}' \
66 # AND ( \
67 # expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL \
68 # ) \
69 # ORDER BY \
70 # newid() \
71 # ) \
72 # UPDATE cte WITH (rowlock, readpast) \
73 # SET FramedIPAddress = FramedIPAddress \
74 # OUTPUT INSERTED.FramedIPAddress"
75
76 #
77 # If an IP could not be allocated, check to see if the pool exists or not
78 # This allows the module to differentiate between a full pool and no pool
79 # Note: If you are not running redundant pool modules this query may be
80 # commented out to save running this query every time an ip is not allocated.
81 #
82 pool_check = "\
83 SELECT TOP(1) id \
84 FROM ${ippool_table} \
85 WHERE pool_name='%{control:${pool_name}}'"
86
87 #
88 # This is the final IP Allocation query, which saves the allocated ip details.
89 #
90 allocate_update = "\
91 UPDATE ${ippool_table} \
92 SET \
93 NASIPAddress = '%{NAS-IP-Address}', pool_key = '${pool_key}', \
94 CallingStationId = '%{Calling-Station-Id}', \
95 UserName = '%{User-Name}', expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
96 WHERE FramedIPAddress = '%I'"
97
98 #
99 # Use a stored procedure to find AND allocate the address. Read and customise
100 # `procedure.sql` in this directory to determine the optimal configuration.
101 #
102 #allocate_begin = ""
103 #allocate_find = "\
104 # EXEC fr_allocate_previous_or_new_framedipaddress \
105 # @v_pool_name = '%{control:${pool_name}}', \
106 # @v_username = '%{User-Name}', \
107 # @v_callingstationid = '%{Calling-Station-Id}', \
108 # @v_nasipaddress = '%{NAS-IP-Address}', \
109 # @v_pool_key = '${pool_key}', \
110 # @v_lease_duration = ${lease_duration} \
111 # "
112 #allocate_update = ""
113 #allocate_commit = ""
114
115 #
116 # This series of queries frees an IP number when an accounting START record arrives.
117 #
118 start_update = "\
119 UPDATE ${ippool_table} \
120 SET \
121 expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
122 WHERE NASIPAddress = '%{NAS-IP-Address}' \
123 AND pool_key = '${pool_key}' \
124 AND UserName = '%{User-Name}' \
125 AND CallingStationId = '%{Calling-Station-Id}' \
126 AND FramedIPAddress = '%{${attribute_name}}'"
127
128 #
129 # Free an IP when an accounting STOP record arrives
130 #
131 stop_clear = "\
132 UPDATE ${ippool_table} \
133 SET \
134 NASIPAddress = '', \
135 pool_key = 0, \
136 CallingStationId = '', \
137 UserName = '', \
138 expiry_time = NULL \
139 WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}' \
140 AND pool_key = '${pool_key}' \
141 AND UserName = '%{User-Name}' \
142 AND CallingStationId = '%{Calling-Station-Id}' \
143 AND FramedIPAddress = '%{${attribute_name}}'"
144
145 #
146 # Update the expiry time for an IP when an accounting ALIVE record arrives
147 #
148 alive_update = "\
149 UPDATE ${ippool_table} \
150 SET \
151 expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
152 WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}' \
153 AND pool_key = '${pool_key}' \
154 AND UserName = '%{User-Name}' \
155 AND CallingStationId = '%{Calling-Station-Id}' \
156 AND FramedIPAddress = '%{${attribute_name}}'"
157
158 #
159 # Frees all IPs allocated to a NAS when an accounting ON record arrives
160 #
161 on_clear = "\
162 UPDATE ${ippool_table} \
163 SET \
164 NASIPAddress = '', \
165 pool_key = 0, \
166 CallingStationId = '', \
167 UserName = '', \
168 expiry_time = NULL \
169 WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
170
171 #
172 # Frees all IPs allocated to a NAS when an accounting OFF record arrives
173 #
174 off_clear = "\
175 UPDATE ${ippool_table} \
176 SET \
177 NASIPAddress = '', \
178 pool_key = 0, \
179 CallingStationId = '', \
180 UserName = '', \
181 expiry_time = NULL \
182 WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
0 --
1 -- Table structure for table 'radippool'
2 --
3 CREATE TABLE radippool (
4 id int IDENTITY (1,1) NOT NULL,
5 pool_name varchar(30) NOT NULL,
6 FramedIPAddress varchar(15) NOT NULL default '',
7 NASIPAddress varchar(15) NOT NULL default '',
8 CalledStationId VARCHAR(32) NOT NULL,
9 CallingStationId VARCHAR(30) NOT NULL,
10 expiry_time DATETIME NULL default NULL,
11 UserName varchar(64) NOT NULL default '',
12 pool_key varchar(30) NOT NULL default '',
13 PRIMARY KEY (id)
14 )
15 GO
16
17 CREATE INDEX poolname_expire ON radippool(pool_name, expiry_time)
18 GO
19
20 CREATE INDEX FramedIPAddress ON radippool(FramedIPAddress)
21 GO
22
23 CREATE INDEX NASIPAddress_poolkey_FramedIPAddress ON radippool(NASIPAddress, pool_key, FramedIPAddress)
24 GO
1616 --
1717 -- allocate_begin = ""
1818 -- allocate_find = "\
19 -- CALL sp_allocate_previous_or_new_framedipaddress( \
19 -- CALL fr_allocate_previous_or_new_framedipaddress( \
2020 -- '%{control:${pool_name}}', \
2121 -- '%{User-Name}', \
2222 -- '%{Calling-Station-Id}', \
3232
3333 DELIMITER $$
3434
35 DROP PROCEDURE IF EXISTS sp_allocate_previous_or_new_framedipaddress;
36 CREATE PROCEDURE sp_allocate_previous_or_new_framedipaddress (
35 DROP PROCEDURE IF EXISTS fr_allocate_previous_or_new_framedipaddress;
36 CREATE PROCEDURE fr_allocate_previous_or_new_framedipaddress (
3737 IN v_pool_name VARCHAR(64),
3838 IN v_username VARCHAR(64),
3939 IN v_callingstationid VARCHAR(64),
113113 nasipaddress = '%{NAS-IP-Address}', pool_key = '${pool_key}', \
114114 callingstationid = '%{Calling-Station-Id}', \
115115 username = '%{User-Name}', expiry_time = NOW() + INTERVAL ${lease_duration} SECOND \
116 WHERE framedipaddress = '%I'
116 WHERE framedipaddress = '%I'"
117117
118118 #
119119 # Use a stored procedure to find AND allocate the address. Read and customise
121121 #
122122 #allocate_begin = ""
123123 #allocate_find = "\
124 # CALL sp_allocate_previous_or_new_framedipaddress( \
124 # CALL fr_allocate_previous_or_new_framedipaddress( \
125125 # '%{control:${pool_name}}', \
126126 # '%{User-Name}', \
127127 # '%{Calling-Station-Id}', \
0 --
1 -- A stored procedure to reallocate a user's previous address, otherwise
2 -- provide a free address.
3 --
4 -- Using this SP reduces the usual set dialogue of queries to a single
5 -- query:
6 --
7 -- BEGIN; SELECT FOR UPDATE; UPDATE; COMMIT; -> SELECT sp() FROM dual
8 --
9 -- The stored procedure is executed on an database instance within a single
10 -- round trip which often leads to reduced deadlocking and significant
11 -- performance improvements especially on multi-master clusters, perhaps even
12 -- by an order of magnitude or more.
13 --
14 -- To use this stored procedure the corresponding queries.conf statements must
15 -- be configured as follows:
16 --
17 -- allocate_begin = ""
18 -- allocate_find = "\
19 -- SELECT fr_allocate_previous_or_new_framedipaddress( \
20 -- '%{control:${pool_name}}', \
21 -- '%{User-Name}', \
22 -- '%{%{Calling-Station-Id}:-0}', \
23 -- '%{NAS-IP-Address}', \
24 -- '${pool_key}', \
25 -- ${lease_duration} \
26 -- ) FROM dual"
27 -- allocate_update = ""
28 -- allocate_commit = ""
29 --
30
31 CREATE OR REPLACE FUNCTION fr_allocate_previous_or_new_framedipaddress (
32 v_pool_name IN VARCHAR2,
33 v_username IN VARCHAR2,
34 v_callingstationid IN VARCHAR2,
35 v_nasipaddress IN VARCHAR2,
36 v_pool_key IN VARCHAR2,
37 v_lease_duration IN INTEGER
38 )
39 RETURN varchar2 IS
40 PRAGMA AUTONOMOUS_TRANSACTION;
41 r_address varchar2(15);
42 BEGIN
43
44 -- Reissue an existing IP address lease when re-authenticating a session
45 --
46 BEGIN
47 SELECT framedipaddress INTO r_address FROM radippool WHERE id IN (
48 SELECT id FROM (
49 SELECT *
50 FROM radippool
51 WHERE pool_name = v_pool_name
52 AND expiry_time > current_timestamp
53 AND username = v_username
54 AND callingstationid = v_callingstationid
55 ) WHERE ROWNUM <= 1
56 ) FOR UPDATE SKIP LOCKED;
57 EXCEPTION
58 WHEN NO_DATA_FOUND THEN
59 r_address := NULL;
60 END;
61
62 -- Reissue an user's previous IP address, provided that the lease is
63 -- available (i.e. enable sticky IPs)
64 --
65 -- When using this SELECT you should delete the one above. You must also
66 -- set allocate_clear = "" in queries.conf to persist the associations
67 -- for expired leases.
68 --
69 -- BEGIN
70 -- SELECT framedipaddress INTO r_address FROM radippool WHERE id IN (
71 -- SELECT id FROM (
72 -- SELECT *
73 -- FROM radippool
74 -- WHERE pool_name = v_pool_name
75 -- AND username = v_username
76 -- AND callingstationid = v_callingstationid
77 -- ) WHERE ROWNUM <= 1
78 -- ) FOR UPDATE SKIP LOCKED;
79 -- EXCEPTION
80 -- WHEN NO_DATA_FOUND THEN
81 -- r_address := NULL;
82 -- END;
83
84 -- If we didn't reallocate a previous address then pick the least
85 -- recently used address from the pool which maximises the likelihood
86 -- of re-assigning the other addresses to their recent user
87 --
88 IF r_address IS NULL THEN
89 BEGIN
90 SELECT framedipaddress INTO r_address FROM radippool WHERE id IN (
91 SELECT id FROM (
92 SELECT *
93 FROM radippool
94 WHERE pool_name = v_pool_name
95 AND expiry_time < CURRENT_TIMESTAMP
96 ORDER BY expiry_time
97 ) WHERE ROWNUM <= 1
98 ) FOR UPDATE SKIP LOCKED;
99 EXCEPTION
100 WHEN NO_DATA_FOUND THEN
101 r_address := NULL;
102 END;
103 END IF;
104
105 -- Return nothing if we failed to allocated an address
106 --
107 IF r_address IS NULL THEN
108 COMMIT;
109 RETURN r_address;
110 END IF;
111
112 -- Update the pool having allocated an IP address
113 --
114 UPDATE radippool
115 SET
116 nasipaddress = v_nasipaddress,
117 pool_key = v_pool_key,
118 callingstationid = v_callingstationid,
119 username = v_username,
120 expiry_time = CURRENT_TIMESTAMP + v_lease_duration * INTERVAL '1' SECOND(1)
121 WHERE framedipaddress = r_address;
122
123 -- Return the address that we allocated
124 COMMIT;
125 RETURN r_address;
126
127 END;
128 /
+0
-41
raddb/mods-config/sql/ippool/oracle/procedures.sql less more
0 CREATE OR REPLACE FUNCTION msqlippool(user varchar2, pool varchar2)
1 RETURN varchar2 IS
2
3 PRAGMA AUTONOMOUS_TRANSACTION;
4 ip_temp varchar2(20);
5 BEGIN
6
7 -- If the user's pool is dynamic, get an ipaddress (oldest one) from the corresponding pool
8
9 if pool = 'Dynamic' then
10 select framedipaddress into ip_temp from (select framedipaddress from radippool where expiry_time < current_timestamp and pool_name = pool ORDER BY expiry_time) where rownum = 1;
11 return (ip_temp);
12
13 -- Else, then get the static ipaddress for that user from the corresponding pool
14
15 else
16 select framedipaddress into ip_temp from radippool where username = user and pool_name = pool;
17 return (ip_temp);
18 end if;
19
20 exception
21
22 -- This block is executed if there's no free ipaddresses or no static ip assigned to the user
23
24 when NO_DATA_FOUND then
25 if pool = 'Dynamic' then
26 return(''); -- so sqlippool can log it on radius.log
27 end if;
28
29 -- Else, grabs a free IP from the static pool and saves it in radippool so the user will always get the same IP the next time
30
31 select framedipaddress into ip_temp from (select framedipaddress from radippool where expiry_time < current_timestamp and username is null and pool_name = pool) where rownum = 1;
32 UPDATE radippool SET username = user where framedipaddress = ip_temp;
33 commit;
34 return (ip_temp);
35
36 when others
37 then return('Oracle Exception');
38
39 END;
40 /
1616 # to the user that they had last session...
1717 #
1818 allocate_find = "\
19 SELECT framedipaddress \
20 FROM ${ippool_table} \
21 WHERE pool_name = '%{control:${pool_name}}' \
22 AND ( \
23 expiry_time < current_timestamp \
24 OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
25 ) \
26 AND rownum <= 1 \
27 ORDER BY \
28 (username <> '%{SQL-User-Name}'), \
29 (callingstationid <> '%{Calling-Station-Id}'), \
30 expiry_time \
31 FOR UPDATE"
19 SELECT framedipaddress FROM ${ippool_table} WHERE id IN ( \
20 SELECT id FROM ( \
21 SELECT * \
22 FROM ${ippool_table} \
23 WHERE pool_name = '%{control:${pool_name}}' \
24 AND ( \
25 expiry_time < current_timestamp \
26 OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
27 ) \
28 ORDER BY \
29 DECODE(username,'%{SQL-User-Name}',2,1), \
30 DECODE(callingstationid,'%{%{Calling-Station-Id}:-0}',2,1), \
31 expiry_time \
32 ) WHERE ROWNUM <= 1 \
33 ) FOR UPDATE"
3234
3335 #
3436 # The above query again, but with SKIP LOCKED. This requires Oracle > 11g.
3537 # It may work in 9i and 10g, but is not documented, so YMMV.
3638 #
3739 #allocate_find = "\
38 # SELECT framedipaddress \
39 # FROM ${ippool_table} \
40 # WHERE pool_name = '%{control:${pool_name}}' \
41 # AND expiry_time < current_timestamp \
42 # AND rownum <= 1 \
43 # ORDER BY \
44 # (username <> '%{SQL-User-Name}'), \
45 # (callingstationid <> '%{Calling-Station-Id}'), \
46 # expiry_time \
47 # FOR UPDATE SKIP LOCKED"
48
49 #
50 # This function is available if you want to use multiple pools
51 #
52 #allocate_find = "\
53 # SELECT msqlippool('%{SQL-User-Name}','%{control:${pool_name}}') \
54 # FROM dual"
40 # SELECT framedipaddress FROM ${ippool_table} WHERE id IN ( \
41 # SELECT id FROM ( \
42 # SELECT * \
43 # FROM ${ippool_table} \
44 # WHERE pool_name = '%{control:${pool_name}}' \
45 # AND ( \
46 # expiry_time < current_timestamp \
47 # OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
48 # ) \
49 # ORDER BY \
50 # DECODE(username,'%{SQL-User-Name}',2,1), \
51 # DECODE(callingstationid,'%{%{Calling-Station-Id}:-0}',2,1), \
52 # expiry_time \
53 # ) WHERE ROWNUM <= 1 \
54 # ) FOR UPDATE SKIP LOCKED"
5555
5656 #
5757 # If you prefer to allocate a random IP address every time, use this query instead
5858 # Note: This is very slow if you have a lot of free IPs.
5959 #
6060 #allocate_find = "\
61 # SELECT framedipaddress \
62 # FROM ${ippool_table} \
63 # WHERE pool_name = '%{control:${pool_name}}' \
64 # AND expiry_time < current_timestamp \
65 # AND rownum <= 1 \
66 # ORDER BY RANDOM() \
67 # FOR UPDATE"
61 # SELECT framedipaddress FROM ${ippool_table} WHERE id IN ( \
62 # SELECT id FROM ( \
63 # SELECT * \
64 # FROM ${ippool_table} \
65 # WHERE pool_name = '%{control:${pool_name}}' \
66 # AND expiry_time < current_timestamp \
67 # ORDER BY DBMS_RANDOM.VALUE \
68 # ) WHERE ROWNUM <= 1 \
69 # ) FOR UPDATE"
6870
6971 #
7072 # The above query again, but with SKIP LOCKED. This requires Oracle > 11g.
7173 # It may work in 9i and 10g, but is not documented, so YMMV.
7274 #
7375 #allocate_find = "\
74 # SELECT framedipaddress \
75 # FROM ${ippool_table} \
76 # WHERE pool_name = '%{control:${pool_name}}' \
77 # AND expiry_time < current_timestamp \
78 # AND rownum <= 1 \
79 # ORDER BY RANDOM() \
80 # FOR UPDATE SKIP LOCKED"
76 # SELECT framedipaddress FROM ${ippool_table} WHERE id IN ( \
77 # SELECT id FROM (\
78 # SELECT * \
79 # FROM ${ippool_table} \
80 # WHERE pool_name = '%{control:${pool_name}}' \
81 # AND expiry_time < current_timestamp \
82 # ORDER BY DBMS_RANDOM.VALUE \
83 # ) WHERE ROWNUM <= 1 \
84 # ) FOR UPDATE SKIP LOCKED"
8185
8286 #
8387 # If an IP could not be allocated, check to see whether the pool exists or not
103107 SET \
104108 nasipaddress = '%{NAS-IP-Address}', \
105109 pool_key = '${pool_key}', \
106 callingstationid = '%{Calling-Station-Id}', \
110 callingstationid = '%{%{Calling-Station-Id}:-0}', \
107111 username = '%{SQL-User-Name}', \
108112 expiry_time = current_timestamp + INTERVAL '${lease_duration}' second(1) \
109113 WHERE framedipaddress = '%I'"
121125 allocate_clear = "\
122126 UPDATE ${ippool_table} \
123127 SET \
124 nasipaddress = '', \
125 pool_key = 0, \
126 callingstationid = '', \
127 expiry_time = current_timestamp - INTERVAL '1' second(1) \
128 WHERE pool_key = '${pool_key}'"
128 nasipaddress = '0', \
129 pool_key = '0', \
130 callingstationid = '0', \
131 expiry_time = current_timestamp - INTERVAL '1' second(1) \
132 WHERE nasipaddress = '%{NAS-IP-Address}' \
133 AND pool_key = '${pool_key}'"
134
135
136 #
137 # Use a stored procedure to find AND allocate the address. Read and customise
138 # `procedure.sql` in this directory to determine the optimal configuration.
139 #
140 #allocate_begin = ""
141 #allocate_find = "\
142 # SELECT fr_allocate_previous_or_new_framedipaddress( \
143 # '%{control:${pool_name}}', \
144 # '%{SQL-User-Name}', \
145 # '%{%{Calling-Station-Id}:-0}', \
146 # '%{NAS-IP-Address}', \
147 # '${pool_key}', \
148 # '${lease_duration}' \
149 # )"
150 #allocate_update = ""
151 #allocate_commit = ""
129152
130153 #
131154 # This query extends an IP address lease by "lease_duration" when an accounting
144167 stop_clear = "\
145168 UPDATE ${ippool_table} \
146169 SET \
147 nasipaddress = '', \
148 pool_key = 0, \
149 callingstationid = '', \
170 nasipaddress = '0', \
171 pool_key = '0', \
172 callingstationid = '0', \
150173 expiry_time = current_timestamp - INTERVAL '1' second(1) \
151174 WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}' \
152175 AND pool_key = '${pool_key}' \
153176 AND username = '%{SQL-User-Name}' \
154 AND callingstationid = '%{Calling-Station-Id}'"
177 AND callingstationid = '%{%{Calling-Station-Id}:-0}' \
178 AND framedipaddress = '%{${attribute_name}}'"
155179
156180 #
157181 # This query extends an IP address lease by "lease_duration" when an accounting
165189 AND pool_key = '${pool_key}' \
166190 AND framedipaddress = '%{${attribute_name}}' \
167191 AND username = '%{SQL-User-Name}' \
168 AND callingstationid = '%{Calling-Station-Id}'"
192 AND callingstationid = '%{%{Calling-Station-Id}:-0}'"
169193
170194 #
171195 # This query frees all IP addresses allocated to a NAS when an
174198 on_clear = "\
175199 UPDATE ${ippool_table} \
176200 SET \
177 nasipaddress = '', \
178 pool_key = 0, \
179 callingstationid = '', \
201 nasipaddress = '0', \
202 pool_key = '0', \
203 callingstationid = '0', \
180204 expiry_time = current_timestamp - INTERVAL '1' second(1) \
181205 WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
182206
187211 off_clear = "\
188212 UPDATE ${ippool_table} \
189213 SET \
190 nasipaddress = '', \
191 pool_key = 0, \
192 callingstationid = '', \
214 nasipaddress = '0', \
215 pool_key = '0', \
216 callingstationid = '0', \
193217 expiry_time = current_timestamp - INTERVAL '1' second(1) \
194218 WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
00 CREATE TABLE radippool (
11 id INT PRIMARY KEY,
22 pool_name VARCHAR(30) NOT NULL,
3 framedipaddress VARCHAR(30) NOT NULL,
4 nasipaddress VARCHAR(30) NOT NULL,
5 pool_key INT NOT NULL,
6 CalledStationId VARCHAR(64),
3 framedipaddress VARCHAR(15) NOT NULL,
4 nasipaddress VARCHAR(15) NOT NULL,
5 pool_key VARCHAR(30) NOT NULL,
6 CalledStationId VARCHAR(64) NOT NULL,
77 CallingStationId VARCHAR(64) NOT NULL,
88 expiry_time timestamp(0) NOT NULL,
9 username VARCHAR(100)
9 username VARCHAR(64)
1010 );
1111
12 CREATE INDEX radippool_poolname_ipaadr ON radippool (pool_name, framedipaddress);
1312 CREATE INDEX radippool_poolname_expire ON radippool (pool_name, expiry_time);
14 CREATE INDEX radippool_nasipaddr_key ON radippool (nasipaddress, pool_key);
15 CREATE INDEX radippool_nasipaddr_calling ON radippool (nasipaddress, callingstationid);
13 CREATE INDEX radippool_framedipaddress ON radippool (framedipaddress);
14 CREATE INDEX radippool_nasip_poolkey_ipaddress ON radippool (nasipaddress, pool_key, framedipaddress);
1615
1716 CREATE SEQUENCE radippool_seq START WITH 1 INCREMENT BY 1;
1817
00 --
1 -- Use the following indexes and function if using the stored procedure to
2 -- find the previously used address.
1 -- A stored procedure to reallocate a user's previous address, otherwise
2 -- provide a free address.
33 --
4 -- You may wish to set the ORDER BY expiry_time to DESC for the first two
5 -- queries in order to assign the address that the user had most recently,
6 -- instead of assigning the oldest address the user had used.
4 -- Using this SP reduces the usual set dialogue of queries to a single
5 -- query:
6 --
7 -- START TRANSACTION; SELECT FOR UPDATE; UPDATE; COMMIT; -> SELECT sp()
8 --
9 -- The stored procedure is executed on an database instance within a single
10 -- round trip which often leads to reduced deadlocking and significant
11 -- performance improvements especially on multi-master clusters, perhaps even
12 -- by an order of magnitude or more.
13 --
14 -- To use this stored procedure the corresponding queries.conf statements must
15 -- be configured as follows:
16 --
17 -- allocate_begin = ""
18 -- allocate_find = "\
19 -- SELECT fr_allocate_previous_or_new_framedipaddress( \
20 -- '%{control:${pool_name}}', \
21 -- '%{User-Name}', \
22 -- '%{Calling-Station-Id}', \
23 -- '%{NAS-IP-Address}', \
24 -- '${pool_key}', \
25 -- ${lease_duration} \
26 -- )"
27 -- allocate_update = ""
28 -- allocate_commit = ""
729 --
830
9 CREATE INDEX radippool_pool_name ON radippool USING btree (pool_name);
10 CREATE INDEX radippool_username ON radippool USING btree (username);
11 CREATE INDEX radippool_callingstationid ON radippool USING btree (callingstationid);
31 CREATE INDEX radippool_poolname_username_callingstationid ON radippool(pool_name,username,callingstationid);
1232
13 CREATE OR REPLACE FUNCTION find_previous_or_new_framedipaddress (
33 CREATE OR REPLACE FUNCTION fr_allocate_previous_or_new_framedipaddress (
1434 v_pool_name VARCHAR(64),
1535 v_username VARCHAR(64),
16 v_callingstationid VARCHAR(64)
36 v_callingstationid VARCHAR(64),
37 v_nasipaddress VARCHAR(16),
38 v_pool_key VARCHAR(64),
39 v_lease_duration INT
1740 )
1841 RETURNS inet
1942 LANGUAGE plpgsql
2144 DECLARE
2245 r_address inet;
2346 BEGIN
47
48 -- Reissue an existing IP address lease when re-authenticating a session
49 --
2450 SELECT framedipaddress INTO r_address
2551 FROM radippool
26 WHERE radippool.pool_name = v_pool_name
27 AND radippool.expiry_time < 'now'::timestamp(0)
28 AND radippool.username = v_username
29 AND radippool.callingstationid = v_callingstationid
30 ORDER BY expiry_time
52 WHERE pool_name = v_pool_name
53 AND expiry_time > NOW()
54 AND username = v_username
55 AND callingstationid = v_callingstationid
3156 LIMIT 1
3257 FOR UPDATE SKIP LOCKED;
33 IF r_address IS NOT NULL THEN
58
59 -- Reissue an user's previous IP address, provided that the lease is
60 -- available (i.e. enable sticky IPs)
61 --
62 -- When using this SELECT you should delete the one above. You must also
63 -- set allocate_clear = "" in queries.conf to persist the associations
64 -- for expired leases.
65 --
66 -- SELECT framedipaddress INTO r_address
67 -- FROM radippool
68 -- WHERE pool_name = v_pool_name
69 -- AND username = v_username
70 -- AND callingstationid = v_callingstationid
71 -- LIMIT 1
72 -- FOR UPDATE SKIP LOCKED;
73
74 -- If we didn't reallocate a previous address then pick the least
75 -- recently used address from the pool which maximises the likelihood
76 -- of re-assigning the other addresses to their recent user
77 --
78 IF r_address IS NULL THEN
79 SELECT framedipaddress INTO r_address
80 FROM radippool
81 WHERE pool_name = v_pool_name
82 AND expiry_time < NOW()
83 ORDER BY
84 expiry_time
85 LIMIT 1
86 FOR UPDATE SKIP LOCKED;
87 END IF;
88
89 -- Return nothing if we failed to allocated an address
90 --
91 IF r_address IS NULL THEN
3492 RETURN r_address;
3593 END IF;
36 SELECT framedipaddress INTO r_address
37 FROM radippool
38 WHERE radippool.pool_name = v_pool_name
39 AND radippool.expiry_time < 'now'::timestamp(0)
40 AND radippool.username = v_username
41 ORDER BY expiry_time
42 LIMIT 1
43 FOR UPDATE SKIP LOCKED;
44 IF r_address IS NOT NULL THEN
45 RETURN r_address;
46 END IF;
47 SELECT framedipaddress INTO r_address
48 FROM radippool
49 WHERE radippool.pool_name = v_pool_name
50 AND radippool.expiry_time < 'now'::timestamp(0)
51 ORDER BY expiry_time
52 LIMIT 1
53 FOR UPDATE SKIP LOCKED;
94
95 -- Update the pool having allocated an IP address
96 --
97 UPDATE radippool
98 SET
99 nasipaddress = v_nasipaddress,
100 pool_key = v_pool_key,
101 callingstationid = v_callingstationid,
102 username = v_username,
103 expiry_time = NOW() + v_lease_duration * interval '1 sec'
104 WHERE framedipaddress = r_address;
105
106 -- Return the address that we allocated
54107 RETURN r_address;
108
55109 END
56110 $$;
3939 # FOR UPDATE SKIP LOCKED"
4040
4141 #
42 # Use a stored procedure to find the address. This requires PostgreSQL >= 9.5 as
43 # SKIP LOCKED is used. See `procedure.sql` in this directory for the
44 # indices and stored procedure used by this query.
45 #
46 # The "NO LOAD BALANCE" comment is included here to indicate to a PgPool
47 # system that this needs to be a write transaction. PgPool itself cannot
48 # detect this from the statement alone. If you are using PgPool and do not
49 # have this comment, the query may go to a read only server, and will fail.
50 # This has no negative effect if you are not using PgPool.
51 #
52 # allocate_find = "\
53 # /*NO LOAD BALANCE*/ \
54 # SELECT find_previous_or_new_framedipaddress( \
55 # '%{control:${pool_name}}', \
56 # '%{SQL-User-Name}', \
57 # '%{Calling-Station-Id}' \
58 # )"
59
60 #
6142 # If you prefer to allocate a random IP address every time, use this query instead
6243 # Note: This is very slow if you have a lot of free IPs.
6344 #
125106 AND pool_key = '${pool_key}'"
126107
127108 #
109 # Use a stored procedure to find AND allocate the address. Read and customise
110 # `procedure.sql` in this directory to determine the optimal configuration.
111 #
112 # This requires PostgreSQL >= 9.5 as SKIP LOCKED is used.
113 #
114 # The "NO LOAD BALANCE" comment is included here to indicate to a PgPool
115 # system that this needs to be a write transaction. PgPool itself cannot
116 # detect this from the statement alone. If you are using PgPool and do not
117 # have this comment, the query may go to a read only server, and will fail.
118 # This has no negative effect if you are not using PgPool.
119 #
120 #allocate_begin = ""
121 #allocate_find = "\
122 # /*NO LOAD BALANCE*/ \
123 # SELECT fr_allocate_previous_or_new_framedipaddress( \
124 # '%{control:${pool_name}}', \
125 # '%{SQL-User-Name}', \
126 # '%{Calling-Station-Id}', \
127 # '%{NAS-IP-Address}', \
128 # '${pool_key}', \
129 # '${lease_duration}' \
130 # )"
131 #allocate_update = ""
132 #allocate_commit = ""
133
134 #
128135 # This query extends an IP address lease by "lease_duration" when an accounting
129136 # START record arrives
130137 #
22 # ippool/sqlite/queries.conf -- SQLite queries for rlm_sqlippool
33 #
44 # $Id$
5
6 #
7 # SQLite does not implement SELECT FOR UPDATE which is normally used to place
8 # an exclusive lock over rows to prevent the same address from being
9 # concurrently selected for allocation to multiple users.
10 #
11 # The most granular read-blocking lock that SQLite has is an exclusive lock
12 # over the database, so that's what we use. All locking in SQLite is performed
13 # over the entire database and we perform a row update for any IP that we
14 # allocate, requiring an exclusive lock. Taking the exclusive lock from the
15 # start of the transaction (even if it were not required to guard the SELECT)
16 # is actually quicker than if we deferred it causing SQLite to "upgrade" the
17 # automatic shared lock for the transaction to an exclusive lock for the
18 # subsequent UPDATE.
19 #
20 allocate_begin = "BEGIN EXCLUSIVE"
21 allocate_commit = "COMMIT"
522
623 #
724 # This series of queries allocates an IP address
4764 (username <> '%{User-Name}'), \
4865 (callingstationid <> '%{Calling-Station-Id}'), \
4966 expiry_time \
50 LIMIT 1 \
51 FOR UPDATE"
67 LIMIT 1"
5268
5369 #
5470 # If you prefer to allocate a random IP address every time, i
6278 # WHERE pool_name = '%{control:${pool_name}}' \
6379 # AND expiry_time IS NULL \
6480 # ORDER BY RAND() \
65 # LIMIT 1 \
66 # FOR UPDATE"
81 # LIMIT 1"
6782
6883 #
6984 # If an IP could not be allocated, check to see if the pool exists or not
88103 callingstationid = '%{Calling-Station-Id}', \
89104 username = '%{User-Name}', \
90105 expiry_time = datetime(strftime('%%s', 'now') + ${lease_duration}, 'unixepoch') \
91 WHERE framedipaddress = '%I'
106 WHERE framedipaddress = '%I'"
92107
93108 #
94 # This series of queries frees an IP number when an accounting START record arrives
109 # Free an IP when an accounting START record arrives
95110 #
96111 start_update = "\
97112 UPDATE ${ippool_table} \
104119 AND framedipaddress = '%{${attribute_name}}'"
105120
106121 #
107 # This series of queries frees an IP number when an accounting STOP record arrives
122 # Free an IP when an accounting STOP record arrives
108123 #
109124 stop_clear = "\
110125 UPDATE ${ippool_table} \
121136 AND framedipaddress = '%{${attribute_name}}'"
122137
123138 #
124 # This series of queries frees an IP number when an accounting
125 # ALIVE record arrives
139 # Update the expiry time for an IP when an accounting ALIVE record arrives
126140 #
127141 alive_update = "\
128142 UPDATE ${ippool_table} \
135149 AND framedipaddress = '%{${attribute_name}}'"
136150
137151 #
138 # This series of queries frees the IP numbers allocate to a
139 # NAS when an accounting ON record arrives
152 # Frees all IPs allocated to a NAS when an accounting ON record arrives
140153 #
141154 on_clear = "\
142155 UPDATE ${ippool_table} \
149162 WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
150163
151164 #
152 # This series of queries frees the IP numbers allocate to a
153 # NAS when an accounting OFF record arrives
165 # Frees all IPs allocated to a NAS when an accounting OFF record arrives
154166 #
155167 off_clear = "\
156168 UPDATE ${ippool_table} \
5454 # { "attribute" : "ClearText-Password", "value" : "pwd1", "op" : ":=" }
5555 # { "attribute" : "Cache-TTL", "value" : 1000, "op" : ":=" }
5656 #
57 authorize_check_query = "db.mobiles.aggregate([ \
57 authorize_check_query = "db.${authcheck_table}.aggregate([ \
5858 { \
5959 '$match': { \
6060 'calling_station_id': '%{Calling-Station-id}', \
0 # -*- text -*-
1 #
2 # main/mssql/process-radacct.sql -- Schema extensions for processing radacct entries
3 #
4 # $Id$
5
6 -- ---------------------------------
7 -- - Per-user data usage over time -
8 -- ---------------------------------
9 --
10 -- An extension to the standard schema to hold per-user data usage statistics
11 -- for arbitrary periods.
12 --
13 -- The data_usage_by_period table is populated by periodically calling the
14 -- fr_new_data_usage_period stored procedure.
15 --
16 -- This table can be queried in various ways to produce reports of aggregate
17 -- data use over time. For example, if the fr_new_data_usage_period SP is
18 -- invoked one per day just after midnight, to produce usage data with daily
19 -- granularity, then a reasonably accurate monthly bandwidth summary for a
20 -- given user could be obtained with:
21 --
22 -- SELECT
23 -- FORMAT(period_start, 'yyyy-MMMM') AS month,
24 -- SUM(acctinputoctets)/1000/1000/1000 AS GB_in,
25 -- SUM(acctoutputoctets)/1000/1000/1000 AS GB_out
26 -- FROM
27 -- data_usage_by_period
28 -- WHERE
29 -- username='bob' AND
30 -- period_end <> 0
31 -- GROUP BY
32 -- FORMAT(period_start, 'yyyy-MMMM');
33 --
34 -- +----------------+----------+-----------+
35 -- | month | GB_in | GB_out |
36 -- +----------------+----------+-----------+
37 -- | 2019-July | 5.782279 | 50.545664 |
38 -- | 2019-August | 4.230543 | 48.523096 |
39 -- | 2019-September | 4.847360 | 48.631835 |
40 -- | 2019-October | 6.456763 | 51.686231 |
41 -- | 2019-November | 6.362537 | 52.385710 |
42 -- | 2019-December | 4.301524 | 50.762240 |
43 -- | 2020-January | 5.436280 | 49.067775 |
44 -- +----------------+----------+-----------+
45 --
46 CREATE TABLE data_usage_by_period (
47 username VARCHAR(64) NOT NULL,
48 period_start DATETIME NOT NULL,
49 period_end DATETIME NOT NULL,
50 acctinputoctets NUMERIC(19),
51 acctoutputoctets NUMERIC(19),
52 PRIMARY KEY (username, period_start)
53 );
54 GO
55
56 CREATE INDEX idx_data_usage_by_period_period_end ON data_usage_by_period(period_end);
57 GO
58
59 --
60 -- Stored procedure that when run with some arbitrary frequency, say
61 -- once per day by cron, will process the recent radacct entries to extract
62 -- time-windowed data containing acct{input,output}octets ("data usage") per
63 -- username, per period.
64 --
65 -- Each invocation will create new rows in the data_usage_by_period tables
66 -- containing the data used by each user since the procedure was last invoked.
67 -- The intervals do not need to be identical but care should be taken to
68 -- ensure that the start/end of each period aligns well with any intended
69 -- reporting intervals.
70 --
71 -- It can be invoked by running:
72 --
73 -- EXEC fr_new_data_usage_period;
74 --
75 --
76 CREATE OR ALTER PROCEDURE fr_new_data_usage_period
77 AS
78 BEGIN
79
80 DECLARE @v_start DATETIME;
81 DECLARE @v_end DATETIME;
82
83 SELECT @v_start = COALESCE(MAX(period_start), CAST('1970-01-01' AS DATETIME)) FROM data_usage_by_period;
84 SELECT @v_end = CAST(CURRENT_TIMESTAMP AS DATETIME2(0));
85
86 BEGIN TRAN;
87
88 --
89 -- Add the data usage for the sessions that were active in the current
90 -- period to the table. Include all sessions that finished since the start
91 -- of this period as well as those still ongoing.
92 --
93 MERGE INTO data_usage_by_period d
94 USING (
95 SELECT
96 username,
97 @v_start AS period_start,
98 @v_end AS period_end,
99 SUM(acctinputoctets) AS acctinputoctets,
100 SUM(acctoutputoctets) AS acctoutputoctets
101 FROM
102 radacct
103 WHERE
104 acctstoptime > @v_start OR
105 acctstoptime=0
106 GROUP BY
107 username
108 ) s
109 ON ( d.username = s.username AND d.period_start = s.period_start )
110 WHEN MATCHED THEN
111 UPDATE SET
112 acctinputoctets = d.acctinputoctets + s.acctinputoctets,
113 acctoutputoctets = d.acctoutputoctets + s.acctoutputoctets,
114 period_end = @v_end
115 WHEN NOT MATCHED THEN
116 INSERT
117 (username, period_start, period_end, acctinputoctets, acctoutputoctets)
118 VALUES
119 (s.username, s.period_start, s.period_end, s.acctinputoctets, s.acctoutputoctets);
120
121 --
122 -- Create an open-ended "next period" for all ongoing sessions and carry a
123 -- negative value of their data usage to avoid double-accounting when we
124 -- process the next period. Their current data usage has already been
125 -- allocated to the current and possibly previous periods.
126 --
127 -- MSSQL doesn't allow a DATETIME to be NULL so we use "0" (1900-01-01) to
128 -- indicate the open-ended interval.
129 --
130 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
131 SELECT *
132 FROM (
133 SELECT
134 username,
135 DATEADD(ss,1,@v_end) AS period_start,
136 0 AS period_end,
137 0 - SUM(acctinputoctets) AS acctinputoctets,
138 0 - SUM(acctoutputoctets) AS acctoutputoctets
139 FROM
140 radacct
141 WHERE
142 acctstoptime=0
143 GROUP BY
144 username
145 ) s;
146
147 COMMIT;
148
149 END
150 GO
2424 #sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-none}}"
2525 #
2626 sql_user_name = "%{User-Name}"
27
28 #######################################################################
29 # Query config: Event-Timestamp
30 #######################################################################
31 # event_timestamp_epoch is the basis for the time inserted into
32 # accounting records. Typically this will be the Event-Timestamp of the
33 # accounting request, which is usually provided by a NAS.
34 #
35 # Uncomment the next line, if you want the timestamp to be based on the
36 # request reception time recorded by this server, for example if you
37 # distrust the provided Event-Timestamp.
38 #event_timestamp_epoch = "%l"
39
40 event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
41
42 # event_timestamp is the SQL snippet for converting an epoch timestamp
43 # to an SQL date.
44
45 event_timestamp = "DATEADD(SS, ${event_timestamp_epoch}, '19700101')"
2746
2847 #######################################################################
2948 # Authorization Queries
106125 query = "\
107126 UPDATE ${....acct_table1} \
108127 SET \
109 AcctStopTime='%S', \
110 AcctSessionTime=unix_timestamp('%S') - \
111 unix_timestamp(AcctStartTime), \
128 AcctStopTime=${....event_timestamp}, \
129 AcctSessionTime=${....event_timestamp_epoch} - \
130 DATEDIFF(SS, '1970-01-01', AcctStartTime), \
112131 AcctTerminateCause='%{%{Acct-Terminate-Cause}:-NAS-Reboot}', \
113132 AcctStopDelay = %{%{Acct-Delay-Time}:-0} \
114133 WHERE AcctStopTime = 0 \
115134 AND NASIPAddress = '%{NAS-IP-Address}' \
116 AND AcctStartTime <= '%S'"
135 AND AcctStartTime <= ${....event_timestamp}"
117136 }
118137
119138 accounting-off {
231250 '%{NAS-IP-Address}', \
232251 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
233252 '%{NAS-Port-Type}', \
234 '%S', \
253 ${....event_timestamp}, \
235254 '0', \
236255 '%{Acct-Authentic}', \
237256 '%{Connect-Info}', \
285304 query = "\
286305 UPDATE ${....acct_table1} \
287306 SET \
288 AcctStartTime = '%S', \
307 AcctStartTime = ${....event_timestamp}, \
289308 AcctStartDelay = '%{%{Acct-Delay-Time}:-0}', \
290309 ConnectInfo_start = '%{Connect-Info}' \
291310 WHERE AcctUniqueId = '%{Acct-Unique-Session-ID}' \
390409 query = "\
391410 UPDATE ${....acct_table2} \
392411 SET \
393 AcctStopTime = '%S', \
412 AcctStopTime = ${....event_timestamp}, \
394413 AcctSessionTime = '%{Acct-Session-Time}', \
395414 AcctInputOctets = convert(bigint, '%{%{Acct-Input-Gigawords}:-0}' * POWER(2.0, 32)) | '%{%{Acct-Input-Octets}:-0}', \
396415 AcctOutputOctets = convert(bigint, '%{%{Acct-Output-Gigawords}:-0}' * POWER(2.0, 32)) | '%{%{Acct-Output-Octets}:-0}', \
436455 '%{NAS-IP-Address}', \
437456 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
438457 '%{NAS-Port-Type}', \
439 '%S', \
458 ${....event_timestamp}, \
440459 '%{Acct-Session-Time}', \
441460 '%{Acct-Authentic}', \
442461 '', \
506525 # Write SQL queries to a logfile. This is potentially useful for bulk inserts
507526 # when used with the rlm_sql_null driver.
508527 # logfile = ${logdir}/post-auth.sql
528
529 query = "\
530 INSERT INTO ${..postauth_table} \
531 (userName, pass, reply, authdate) \
532 VALUES(\
533 '%{User-Name}', \
534 '%{%{User-Password}:-CHAP-PASSWORD}', \
535 '%{reply:Packet-Type}', \
536 '%S.%{expr:%M / 1000}')"
509537 }
0 /***************************************************************************
1 * $Id$ *
2 * *
3 * db_mssql.sql *
4 * *
5 * Database schema for MSSQL server *
6 * *
7 * To load: *
8 * isql -S db_ip_addr -d db_name -U db_login -P db_passwd -i db_mssql.sql *
9 * *
10 * Based on: db_mysql.sql (Mike Machado <mike@innercite.com>) *
11 * *
12 * Dmitri Ageev <d_ageev@ortcc.ru> *
13 ***************************************************************************/
14
15 /****** Object: Table [radacct] Script Date: 26.03.02 16:55:17 ******/
0 -- $Id$d$
1 --
2 -- schela.sql rlm_sql - FreeRADIUS SQL Module
3 --
4 -- Database schema for MSSQL rlm_sql module
5 --
6 -- To load:
7 -- isql -S db_ip_addr -d db_name -U db_login -P db_passwd -i db_mssql.sql
8 --
9 -- Based on: db_mysql.sql (Mike Machado <mike@innercite.com>)
10 --
11 -- Dmitri Ageev <d_ageev@ortcc.ru>
12 --
13
14
15 --
16 -- Table structure for table 'radacct'
17 --
18
1619 CREATE TABLE [radacct] (
17 [RadAcctId] [numeric](21, 0) IDENTITY (1, 1) NOT NULL ,
18 [AcctSessionId] [varchar] (64) DEFAULT ('') FOR [AcctSessionId],
19 [AcctUniqueId] [varchar] (32) DEFAULT ('') FOR [AcctUniqueId],
20 [UserName] [varchar] (64) DEFAULT ('') FOR [UserName],
21 [Realm] [varchar] (64) DEFAULT ('') FOR [Realm],
22 [NASIPAddress] [varchar] (15) DEFAULT ('') FOR [NASIPAddress],
23 [NASPortId] [varchar] (15) NULL ,
24 [NASPortType] [varchar] (32) NULL ,
25 [AcctStartTime] [datetime] NOT NULL ,
26 [AcctStopTime] [datetime] NOT NULL ,
27 [AcctSessionTime] [bigint] NULL ,
28 [AcctAuthentic] [varchar] (32) NULL ,
29 [ConnectInfo_start] [varchar] (32) DEFAULT (null) FOR [ConnectInfo_start],
30 [ConnectInfo_stop] [varchar] (32) DEFAULT (null) FOR [ConnectInfo_stop],
31 [AcctInputOctets] [bigint] NULL ,
32 [AcctOutputOctets] [bigint] NULL ,
33 [CalledStationId] [varchar] (30) DEFAULT ('') FOR [CalledStationId],
34 [CallingStationId] [varchar] (30) DEFAULT ('') FOR [CallingStationId],
35 [AcctTerminateCause] [varchar] (32) DEFAULT ('') FOR [AcctTerminateCause],
36 [ServiceType] [varchar] (32) NULL ,
37 [FramedProtocol] [varchar] (32) NULL ,
38 [FramedIPAddress] [varchar] (15) DEFAULT ('') FOR [FramedIPAddress],
39 [FramedIPv6Address] [varchar] (45) DEFAULT ('') FOR [FramedIPv6Address],
40 [FramedIPv6Prefix] [varchar] (45) DEFAULT ('') FOR [FramedIPv6Prefix],
41 [FramedInterfaceId] [varchar] (44) DEFAULT ('') FOR [FramedInterfaceId],
42 [DelegatedIPv6Prefix] [varchar] (45) DEFAULT ('') FOR [DelegatedIPv6Prefix],
43 [XAscendSessionSvrKey] [varchar] (10) DEFAULT (null) FOR [XAscendSessionSvrKey],
44 [AcctStartDelay] [int] NULL ,
20 [RadAcctId] [numeric](21, 0) IDENTITY (1, 1) NOT NULL,
21 [AcctSessionId] [varchar] (64) NOT NULL,
22 [AcctUniqueId] [varchar] (32) NOT NULL,
23 [UserName] [varchar] (64) NOT NULL,
24 [GroupName] [varchar] (64) NOT NULL,
25 [Realm] [varchar] (64) NOT NULL,
26 [NASIPAddress] [varchar] (15) NOT NULL,
27 [NASPortId] [varchar] (15) NULL,
28 [NASPortType] [varchar] (32) NULL,
29 [AcctStartTime] [datetime] NOT NULL,
30 [AcctStopTime] [datetime] NOT NULL,
31 [AcctSessionTime] [bigint] NULL,
32 [AcctAuthentic] [varchar] (32) NULL,
33 [ConnectInfo_start] [varchar] (32) NULL,
34 [ConnectInfo_stop] [varchar] (32) NULL,
35 [AcctInputOctets] [bigint] NULL,
36 [AcctOutputOctets] [bigint] NULL,
37 [CalledStationId] [varchar] (30) NOT NULL,
38 [CallingStationId] [varchar] (30) NOT NULL,
39 [AcctTerminateCause] [varchar] (32) NOT NULL,
40 [ServiceType] [varchar] (32) NULL,
41 [FramedProtocol] [varchar] (32) NULL,
42 [FramedIPAddress] [varchar] (15) NOT NULL,
43 [FramedIPv6Address] [varchar] (45) NOT NULL,
44 [FramedIPv6Prefix] [varchar] (45) NOT NULL,
45 [FramedInterfaceId] [varchar] (44) NOT NULL,
46 [DelegatedIPv6Prefix] [varchar] (45) NOT NULL,
47 [AcctStartDelay] [int] NULL,
4548 [AcctStopDelay] [int] NULL
4649 ) ON [PRIMARY]
47 GO
48
49 /****** Object: Table [radcheck] Script Date: 26.03.02 16:55:17 ******/
50 CREATE TABLE [radcheck] (
51 [id] [int] IDENTITY (1, 1) NOT NULL ,
52 [UserName] [varchar] (64) NOT NULL ,
53 [Attribute] [varchar] (32) NOT NULL ,
54 [Value] [varchar] (253) NOT NULL ,
55 [op] [char] (2) NULL
56 ) ON [PRIMARY]
57 GO
58
59 /****** Object: Table [radgroupcheck] Script Date: 26.03.02 16:55:17 ******/
60 CREATE TABLE [radgroupcheck] (
61 [id] [int] IDENTITY (1, 1) NOT NULL ,
62 [GroupName] [varchar] (64) NOT NULL ,
63 [Attribute] [varchar] (32) NOT NULL ,
64 [Value] [varchar] (253) NOT NULL ,
65 [op] [char] (2) NULL
66 ) ON [PRIMARY]
67 GO
68
69 /****** Object: Table [radgroupreply] Script Date: 26.03.02 16:55:17 ******/
70 CREATE TABLE [radgroupreply] (
71 [id] [int] IDENTITY (1, 1) NOT NULL ,
72 [GroupName] [varchar] (64) NOT NULL ,
73 [Attribute] [varchar] (32) NOT NULL ,
74 [Value] [varchar] (253) NOT NULL ,
75 [op] [char] (2) NULL ,
76 [prio] [int] NOT NULL
77 ) ON [PRIMARY]
78 GO
79
80 /****** Object: Table [radreply] Script Date: 26.03.02 16:55:18 ******/
81 CREATE TABLE [radreply] (
82 [id] [int] IDENTITY (1, 1) NOT NULL ,
83 [UserName] [varchar] (64) NOT NULL ,
84 [Attribute] [varchar] (32) NOT NULL ,
85 [Value] [varchar] (253) NOT NULL ,
86 [op] [char] (2) NULL
87 ) ON [PRIMARY]
88 GO
89
90 /****** Object: Table [radusergroup] Script Date: 26.03.02 16:55:18 ******/
91 CREATE TABLE [radusergroup] (
92 [id] [int] IDENTITY (1, 1) NOT NULL ,
93 [UserName] [varchar] (64) NOT NULL ,
94 [GroupName] [varchar] (64) NULL ,
95 [Priority] [int] NULL
96 ) ON [PRIMARY]
97 GO
98
99 /****** Object: Table [radusergroup] Script Date: 16.04.08 19:44:11 ******/
100 CREATE TABLE [radpostauth] (
101 [id] [int] IDENTITY (1, 1) NOT NULL ,
102 [userName] [varchar] (64) NOT NULL ,
103 [pass] [varchar] (64) NOT NULL ,
104 [reply] [varchar] (32) NOT NULL ,
105 [authdate] [datetime] NOT NULL
106 )
10750 GO
10851
10952 ALTER TABLE [radacct] WITH NOCHECK ADD
13578 CONSTRAINT [DF_radacct_DelegatedIPv6Prefix] DEFAULT ('') FOR [DelegatedIPv6Prefix],
13679 CONSTRAINT [DF_radacct_AcctStartDelay] DEFAULT (null) FOR [AcctStartDelay],
13780 CONSTRAINT [DF_radacct_AcctStopDelay] DEFAULT (null) FOR [AcctStopDelay],
138 CONSTRAINT [PK_radacct] PRIMARY KEY NONCLUSTERED
81 CONSTRAINT [PK_radacct] PRIMARY KEY NONCLUSTERED
13982 (
14083 [RadAcctId]
141 ) ON [PRIMARY]
84 ) ON [PRIMARY]
85 GO
86
87 CREATE INDEX [UserName] ON [radacct]([UserName]) ON [PRIMARY]
88 GO
89
90 CREATE INDEX [FramedIPAddress] ON [radacct]([FramedIPAddress]) ON [PRIMARY]
91 GO
92
93 CREATE INDEX [FramedIPv6Address] ON [radacct]([FramedIPv6Address]) ON [PRIMARY]
94 GO
95
96 CREATE INDEX [FramedIPv6Prefix] ON [radacct]([FramedIPv6Prefix]) ON [PRIMARY]
97 GO
98
99 CREATE INDEX [FramedInterfaceId] ON [radacct]([FramedInterfaceId]) ON [PRIMARY]
100 GO
101
102 CREATE INDEX [DelegatedIPv6Prefix] ON [radacct]([DelegatedIPv6Prefix]) ON [PRIMARY]
103 GO
104
105 CREATE INDEX [AcctSessionId] ON [radacct]([AcctSessionId]) ON [PRIMARY]
106 GO
107
108 CREATE UNIQUE INDEX [AcctUniqueId] ON [radacct]([AcctUniqueId]) ON [PRIMARY]
109 GO
110
111 CREATE INDEX [AcctStartTime] ON [radacct]([AcctStartTime]) ON [PRIMARY]
112 GO
113
114 CREATE INDEX [AcctStopTime] ON [radacct]([AcctStopTime]) ON [PRIMARY]
115 GO
116
117 CREATE INDEX [NASIPAddress] ON [radacct]([NASIPAddress]) ON [PRIMARY]
118 GO
119
120 /* For use by onoff */
121 CREATE INDEX [RadacctBulkClose] ON [radacct]([NASIPAddress],[AcctStartTime]) WHERE [AcctStopTime] IS NULL ON [PRIMARY]
122 GO
123
124
125 --
126 -- Table structure for table 'radacct'
127 --
128
129 CREATE TABLE [radcheck] (
130 [id] [int] IDENTITY (1, 1) NOT NULL ,
131 [UserName] [varchar] (64) NOT NULL ,
132 [Attribute] [varchar] (32) NOT NULL ,
133 [Value] [varchar] (253) NOT NULL ,
134 [op] [char] (2) NULL
135 ) ON [PRIMARY]
142136 GO
143137
144138 ALTER TABLE [radcheck] WITH NOCHECK ADD
146140 CONSTRAINT [DF_radcheck_Attribute] DEFAULT ('') FOR [Attribute],
147141 CONSTRAINT [DF_radcheck_Value] DEFAULT ('') FOR [Value],
148142 CONSTRAINT [DF_radcheck_op] DEFAULT (null) FOR [op],
149 CONSTRAINT [PK_radcheck] PRIMARY KEY NONCLUSTERED
150 (
151 [id]
152 ) ON [PRIMARY]
143 CONSTRAINT [PK_radcheck] PRIMARY KEY NONCLUSTERED
144 (
145 [id]
146 ) ON [PRIMARY]
147 GO
148
149 CREATE INDEX [UserName] ON [radcheck]([UserName]) ON [PRIMARY]
150 GO
151
152
153 --
154 -- Table structure for table 'radacct'
155 --
156
157 CREATE TABLE [radgroupcheck] (
158 [id] [int] IDENTITY (1, 1) NOT NULL ,
159 [GroupName] [varchar] (64) NOT NULL ,
160 [Attribute] [varchar] (32) NOT NULL ,
161 [Value] [varchar] (253) NOT NULL ,
162 [op] [char] (2) NULL
163 ) ON [PRIMARY]
153164 GO
154165
155166 ALTER TABLE [radgroupcheck] WITH NOCHECK ADD
157168 CONSTRAINT [DF_radgroupcheck_Attribute] DEFAULT ('') FOR [Attribute],
158169 CONSTRAINT [DF_radgroupcheck_Value] DEFAULT ('') FOR [Value],
159170 CONSTRAINT [DF_radgroupcheck_op] DEFAULT (null) FOR [op],
160 CONSTRAINT [PK_radgroupcheck] PRIMARY KEY NONCLUSTERED
161 (
162 [id]
163 ) ON [PRIMARY]
171 CONSTRAINT [PK_radgroupcheck] PRIMARY KEY NONCLUSTERED
172 (
173 [id]
174 ) ON [PRIMARY]
175 GO
176
177 CREATE INDEX [GroupName] ON [radgroupcheck]([GroupName]) ON [PRIMARY]
178 GO
179
180
181 --
182 -- Table structure for table 'radacct'
183 --
184
185 CREATE TABLE [radgroupreply] (
186 [id] [int] IDENTITY (1, 1) NOT NULL ,
187 [GroupName] [varchar] (64) NOT NULL ,
188 [Attribute] [varchar] (32) NOT NULL ,
189 [Value] [varchar] (253) NOT NULL ,
190 [op] [char] (2) NULL ,
191 [prio] [int] NOT NULL
192 ) ON [PRIMARY]
164193 GO
165194
166195 ALTER TABLE [radgroupreply] WITH NOCHECK ADD
169198 CONSTRAINT [DF_radgroupreply_Value] DEFAULT ('') FOR [Value],
170199 CONSTRAINT [DF_radgroupreply_op] DEFAULT (null) FOR [op],
171200 CONSTRAINT [DF_radgroupreply_prio] DEFAULT (0) FOR [prio],
172 CONSTRAINT [PK_radgroupreply] PRIMARY KEY NONCLUSTERED
173 (
174 [id]
175 ) ON [PRIMARY]
201 CONSTRAINT [PK_radgroupreply] PRIMARY KEY NONCLUSTERED
202 (
203 [id]
204 ) ON [PRIMARY]
205 GO
206
207 CREATE INDEX [GroupName] ON [radgroupreply]([GroupName]) ON [PRIMARY]
208 GO
209
210
211 --
212 -- Table structure for table 'radacct'
213 --
214
215 CREATE TABLE [radreply] (
216 [id] [int] IDENTITY (1, 1) NOT NULL ,
217 [UserName] [varchar] (64) NOT NULL ,
218 [Attribute] [varchar] (32) NOT NULL ,
219 [Value] [varchar] (253) NOT NULL ,
220 [op] [char] (2) NULL
221 ) ON [PRIMARY]
176222 GO
177223
178224 ALTER TABLE [radreply] WITH NOCHECK ADD
180226 CONSTRAINT [DF_radreply_Attribute] DEFAULT ('') FOR [Attribute],
181227 CONSTRAINT [DF_radreply_Value] DEFAULT ('') FOR [Value],
182228 CONSTRAINT [DF_radreply_op] DEFAULT (null) FOR [op],
183 CONSTRAINT [PK_radreply] PRIMARY KEY NONCLUSTERED
184 (
185 [id]
186 ) ON [PRIMARY]
229 CONSTRAINT [PK_radreply] PRIMARY KEY NONCLUSTERED
230 (
231 [id]
232 ) ON [PRIMARY]
233 GO
234
235 CREATE INDEX [UserName] ON [radreply]([UserName]) ON [PRIMARY]
236 GO
237
238
239 --
240 -- Table structure for table 'radacct'
241 --
242
243 CREATE TABLE [radusergroup] (
244 [id] [int] IDENTITY (1, 1) NOT NULL ,
245 [UserName] [varchar] (64) NOT NULL ,
246 [GroupName] [varchar] (64) NULL ,
247 [Priority] [int] NULL
248 ) ON [PRIMARY]
187249 GO
188250
189251 ALTER TABLE [radusergroup] WITH NOCHECK ADD
190252 CONSTRAINT [DF_radusergroup_UserName] DEFAULT ('') FOR [UserName],
191253 CONSTRAINT [DF_radusergroup_GroupName] DEFAULT ('') FOR [GroupName],
192 CONSTRAINT [PK_radusergroup] PRIMARY KEY NONCLUSTERED
193 (
194 [id]
195 ) ON [PRIMARY]
254 CONSTRAINT [PK_radusergroup] PRIMARY KEY NONCLUSTERED
255 (
256 [id]
257 ) ON [PRIMARY]
258 GO
259
260 CREATE INDEX [UserName] ON [radusergroup]([UserName]) ON [PRIMARY]
261 GO
262
263
264 --
265 -- Table structure for table 'radacct'
266 --
267
268 CREATE TABLE [radpostauth] (
269 [id] [int] IDENTITY (1, 1) NOT NULL ,
270 [userName] [varchar] (64) NOT NULL ,
271 [pass] [varchar] (64) NOT NULL ,
272 [reply] [varchar] (32) NOT NULL ,
273 [authdate] [datetime] NOT NULL
274 )
196275 GO
197276
198277 ALTER TABLE [radpostauth] WITH NOCHECK ADD
205284 [id]
206285 ) ON [PRIMARY]
207286 GO
208
209 CREATE INDEX [UserName] ON [radacct]([UserName]) ON [PRIMARY]
210 GO
211
212 CREATE INDEX [FramedIPAddress] ON [radacct]([FramedIPAddress]) ON [PRIMARY]
213 GO
214
215 CREATE INDEX [FramedIPv6Address] ON [radacct]([FramedIPv6Address]) ON [PRIMARY]
216 GO
217
218 CREATE INDEX [FramedIPv6Prefix] ON [radacct]([FramedIPv6Prefix]) ON [PRIMARY]
219 GO
220
221 CREATE INDEX [FramedInterfaceId] ON [radacct]([FramedInterfaceId]) ON [PRIMARY]
222 GO
223
224 CREATE INDEX [DelegatedIPv6Prefix] ON [radacct]([DelegatedIPv6Prefix]) ON [PRIMARY]
225 GO
226
227 CREATE INDEX [AcctSessionId] ON [radacct]([AcctSessionId]) ON [PRIMARY]
228 GO
229
230 CREATE UNIQUE INDEX [AcctUniqueId] ON [radacct]([AcctUniqueId]) ON [PRIMARY]
231 GO
232
233 CREATE INDEX [AcctStartTime] ON [radacct]([AcctStartTime]) ON [PRIMARY]
234 GO
235
236 CREATE INDEX [AcctStopTime] ON [radacct]([AcctStopTime]) ON [PRIMARY]
237 GO
238
239 CREATE INDEX [NASIPAddress] ON [radacct]([NASIPAddress]) ON [PRIMARY]
240 GO
241
242 CREATE INDEX [UserName] ON [radcheck]([UserName]) ON [PRIMARY]
243 GO
244
245 CREATE INDEX [GroupName] ON [radgroupcheck]([GroupName]) ON [PRIMARY]
246 GO
247
248 CREATE INDEX [GroupName] ON [radgroupreply]([GroupName]) ON [PRIMARY]
249 GO
250
251 CREATE INDEX [UserName] ON [radreply]([UserName]) ON [PRIMARY]
252 GO
253
254 CREATE INDEX [UserName] ON [radusergroup]([UserName]) ON [PRIMARY]
255 GO
0 # -*- text -*-
1 #
2 # main/mysql/process-radacct.sql -- Schema extensions for processing radacct entries
3 #
4 # $Id$
5
6 -- ---------------------------------
7 -- - Per-user data usage over time -
8 -- ---------------------------------
9 --
10 -- An extension to the standard schema to hold per-user data usage statistics
11 -- for arbitrary periods.
12 --
13 -- The data_usage_by_period table is populated by periodically calling the
14 -- fr_new_data_usage_period stored procedure.
15 --
16 -- This table can be queried in various ways to produce reports of aggregate
17 -- data use over time. For example, if the fr_new_data_usage_period SP is
18 -- invoked one per day just after midnight, to produce usage data with daily
19 -- granularity, then a reasonably accurate monthly bandwidth summary for a
20 -- given user could be obtained with:
21 --
22 -- SELECT
23 -- DATE_FORMAT(period_start, '%Y-%M') AS month,
24 -- SUM(acctinputoctets)/1000/1000/1000 AS GB_in,
25 -- SUM(acctoutputoctets)/1000/1000/1000 AS GB_out
26 -- FROM
27 -- data_usage_by_period
28 -- WHERE
29 -- username='bob' AND
30 -- period_end IS NOT NULL
31 -- GROUP BY
32 -- YEAR(period_start), MONTH(period_start);
33 --
34 -- +----------------+----------------+-----------------+
35 -- | month | GB_in | GB_out |
36 -- +----------------+----------------+-----------------+
37 -- | 2019-July | 5.782279230000 | 50.545664820000 |
38 -- | 2019-August | 4.230543340000 | 48.523096420000 |
39 -- | 2019-September | 4.847360590000 | 48.631835480000 |
40 -- | 2019-October | 6.456763250000 | 51.686231930000 |
41 -- | 2019-November | 6.362537730000 | 52.385710570000 |
42 -- | 2019-December | 4.301524440000 | 50.762240270000 |
43 -- | 2020-January | 5.436280540000 | 49.067775280000 |
44 -- +----------------+----------------+-----------------+
45 -- 7 rows in set (0.000 sec)
46 --
47 CREATE TABLE data_usage_by_period (
48 username VARCHAR(64),
49 period_start DATETIME,
50 period_end DATETIME,
51 acctinputoctets BIGINT(20),
52 acctoutputoctets BIGINT(20),
53 PRIMARY KEY (username,period_start)
54 );
55 CREATE INDEX idx_data_usage_by_period_period_start ON data_usage_by_period (period_start);
56
57
58 --
59 -- Stored procedure that when run with some arbitrary frequency, say
60 -- once per day by cron, will process the recent radacct entries to extract
61 -- time-windowed data containing acct{input,output}octets ("data usage") per
62 -- username, per period.
63 --
64 -- Each invocation will create new rows in the data_usage_by_period tables
65 -- containing the data used by each user since the procedure was last invoked.
66 -- The intervals do not need to be identical but care should be taken to
67 -- ensure that the start/end of each period aligns well with any intended
68 -- reporting intervals.
69 --
70 -- It can be invoked by running:
71 --
72 -- CALL fr_new_data_usage_period();
73 --
74 --
75 DELIMITER $$
76
77 DROP PROCEDURE IF EXISTS fr_new_data_usage_period;
78 CREATE PROCEDURE fr_new_data_usage_period ()
79 BEGIN
80
81 DECLARE v_start DATETIME;
82 DECLARE v_end DATETIME;
83
84 SELECT IFNULL(MAX(period_start), FROM_UNIXTIME(0)) INTO v_start FROM data_usage_by_period;
85 SELECT NOW() INTO v_end;
86
87 START TRANSACTION;
88
89 --
90 -- Add the data usage for the sessions that were active in the current
91 -- period to the table. Include all sessions that finished since the start
92 -- of this period as well as those still ongoing.
93 --
94 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
95 SELECT *
96 FROM (
97 SELECT
98 username,
99 v_start,
100 v_end,
101 SUM(acctinputoctets) AS acctinputoctets,
102 SUM(acctoutputoctets) AS acctoutputoctets
103 FROM
104 radacct
105 WHERE
106 acctstoptime > v_start OR
107 acctstoptime IS NULL
108 GROUP BY
109 username
110 ) AS s
111 ON DUPLICATE KEY UPDATE
112 acctinputoctets = data_usage_by_period.acctinputoctets + s.acctinputoctets,
113 acctoutputoctets = data_usage_by_period.acctoutputoctets + s.acctoutputoctets,
114 period_end = v_end;
115
116 --
117 -- Create an open-ended "next period" for all ongoing sessions and carry a
118 -- negative value of their data usage to avoid double-accounting when we
119 -- process the next period. Their current data usage has already been
120 -- allocated to the current and possibly previous periods.
121 --
122 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
123 SELECT *
124 FROM (
125 SELECT
126 username,
127 DATE_ADD(v_end, INTERVAL 1 SECOND),
128 NULL,
129 0 - SUM(acctinputoctets),
130 0 - SUM(acctoutputoctets)
131 FROM
132 radacct
133 WHERE
134 acctstoptime IS NULL
135 GROUP BY
136 username
137 ) AS s;
138
139 COMMIT;
140
141 END$$
142
143 DELIMITER ;
4747 #sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}}"
4848 #
4949 sql_user_name = "%{User-Name}"
50
51 #######################################################################
52 # Query config: Event-Timestamp
53 #######################################################################
54 # event_timestamp_epoch is the basis for the time inserted into
55 # accounting records. Typically this will be the Event-Timestamp of the
56 # accounting request, which is usually provided by a NAS.
57 #
58 # Uncomment the next line, if you want the timestamp to be based on the
59 # request reception time recorded by this server, for example if you
60 # distrust the provided Event-Timestamp.
61 #event_timestamp_epoch = "%l"
62
63 event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
64
65 # event_timestamp is the SQL snippet for converting an epoch timestamp
66 # to an SQL date.
67
68 event_timestamp = "FROM_UNIXTIME(${event_timestamp_epoch})"
5069
5170 #######################################################################
5271 # Default profile
227246 query = "\
228247 UPDATE ${....acct_table1} \
229248 SET \
230 acctstoptime = FROM_UNIXTIME(\
231 %{integer:Event-Timestamp}), \
232 acctsessiontime = '%{integer:Event-Timestamp}' \
249 acctstoptime = ${....event_timestamp}, \
250 acctsessiontime = '${....event_timestamp_epoch}' \
233251 - UNIX_TIMESTAMP(acctstarttime), \
234252 acctterminatecause = '%{%{Acct-Terminate-Cause}:-NAS-Reboot}' \
235253 WHERE acctstoptime IS NULL \
236254 AND nasipaddress = '%{NAS-IP-Address}' \
237 AND acctstarttime <= FROM_UNIXTIME(\
238 %{integer:Event-Timestamp})"
255 AND acctstarttime <= ${....event_timestamp}"
239256 }
240257
241258 accounting-off {
261278 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
262279 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
263280 '%{NAS-Port-Type}', \
264 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
281 ${....event_timestamp}, \
265282 NULL, \
266283 NULL, \
267284 0, \
272289 0, \
273290 '%{Called-Station-Id}', \
274291 '%{Calling-Station-Id}', \
275 NULL, \
292 '', \
276293 '%{Service-Type}', \
277294 NULL, \
278295 '', \
283300
284301 query = "\
285302 UPDATE ${....acct_table1} SET \
286 AcctStartTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
287 AcctUpdateTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
303 AcctStartTime = ${....event_timestamp}, \
304 AcctUpdateTime = ${....event_timestamp}, \
288305 ConnectInfo_start = '%{Connect-Info}', \
289306 AcctSessionId = '%{Acct-Session-Id}' \
290307 WHERE UserName = '%{SQL-User-Name}' \
309326 '%{NAS-IP-Address}', \
310327 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
311328 '%{NAS-Port-Type}', \
312 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
313 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
329 ${....event_timestamp}, \
330 ${....event_timestamp}, \
314331 NULL, \
315332 '0', \
316333 '%{Acct-Authentic}', \
352369 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
353370 framedinterfaceid = '%{Framed-Interface-Id}', \
354371 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
355 AcctStartTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
356 AcctUpdateTime = FROM_UNIXTIME(%{integer:Event-Timestamp}) \
372 AcctStartTime = ${....event_timestamp}, \
373 AcctUpdateTime = ${....event_timestamp} \
357374 WHERE UserName = '%{SQL-User-Name}' \
358375 AND NASIPAddress = '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}' \
359376 AND NASPortId = '%{%{NAS-Port-ID}:-%{NAS-Port}}' \
366383 #
367384 query = "\
368385 UPDATE ${....acct_table1} SET \
369 acctstarttime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
370 acctupdatetime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
386 acctstarttime = ${....event_timestamp}, \
387 acctupdatetime = ${....event_timestamp}, \
371388 connectinfo_start = '%{Connect-Info}' \
372389 WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'"
373390
383400 UPDATE ${....acct_table1} \
384401 SET \
385402 acctupdatetime = (@acctupdatetime_old:=acctupdatetime), \
386 acctupdatetime = FROM_UNIXTIME(\
387 %{integer:Event-Timestamp}), \
388 acctinterval = %{integer:Event-Timestamp} - \
403 acctupdatetime = ${....event_timestamp}, \
404 acctinterval = ${....event_timestamp_epoch} - \
389405 UNIX_TIMESTAMP(@acctupdatetime_old), \
390406 framedipaddress = '%{Framed-IP-Address}', \
391407 framedipv6address = '%{Framed-IPv6-Address}', \
414430 '%{NAS-IP-Address}', \
415431 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
416432 '%{NAS-Port-Type}', \
417 FROM_UNIXTIME(%{integer:Event-Timestamp} - %{%{Acct-Session-Time}:-0}), \
418 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
433 FROM_UNIXTIME(${....event_timestamp_epoch} - %{%{Acct-Session-Time}:-0}), \
434 ${....event_timestamp}, \
419435 NULL, \
420436 %{%{Acct-Session-Time}:-NULL}, \
421437 '%{Acct-Authentic}', \
457473 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
458474 framedinterfaceid = '%{Framed-Interface-Id}', \
459475 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
460 AcctUpdateTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
476 AcctUpdateTime = ${....event_timestamp}, \
461477 AcctSessionTime = %{%{Acct-Session-Time}:-NULL}, \
462478 AcctInputOctets = '%{%{Acct-Input-Gigawords}:-0}' \
463479 << 32 | '%{%{Acct-Input-Octets}:-0}', \
477493 #
478494 query = "\
479495 UPDATE ${....acct_table2} SET \
480 acctstoptime = FROM_UNIXTIME(\
481 %{integer:Event-Timestamp}), \
496 acctstoptime = ${....event_timestamp}, \
482497 acctsessiontime = %{%{Acct-Session-Time}:-NULL}, \
483498 acctinputoctets = '%{%{Acct-Input-Gigawords}:-0}' \
484499 << 32 | '%{%{Acct-Input-Octets}:-0}', \
503518 '%{NAS-IP-Address}', \
504519 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
505520 '%{NAS-Port-Type}', \
506 FROM_UNIXTIME(%{integer:Event-Timestamp} - %{%{Acct-Session-Time}:-0}), \
507 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
508 FROM_UNIXTIME(%{integer:Event-Timestamp}), \
521 FROM_UNIXTIME(${....event_timestamp_epoch} - %{%{Acct-Session-Time}:-0}), \
522 ${....event_timestamp}, \
523 ${....event_timestamp}, \
509524 %{%{Acct-Session-Time}:-NULL}, \
510525 '%{Acct-Authentic}', \
511526 '', \
546561 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
547562 framedinterfaceid = '%{Framed-Interface-Id}', \
548563 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
549 AcctStopTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
550 AcctUpdateTime = FROM_UNIXTIME(%{integer:Event-Timestamp}), \
564 AcctStopTime = ${....event_timestamp}, \
565 AcctUpdateTime = ${....event_timestamp}, \
551566 AcctSessionTime = %{Acct-Session-Time}, \
552567 AcctInputOctets = '%{%{Acct-Input-Gigawords}:-0}' \
553568 << 32 | '%{%{Acct-Input-Octets}:-0}', \
591606 '%{SQL-User-Name}', \
592607 '%{%{User-Password}:-%{Chap-Password}}', \
593608 '%{reply:Packet-Type}', \
594 '%S')"
609 '%S.%M')"
595610 }
2020 username varchar(64) NOT NULL default '',
2121 realm varchar(64) default '',
2222 nasipaddress varchar(15) NOT NULL default '',
23 nasportid varchar(15) default NULL,
23 nasportid varchar(32) default NULL,
2424 nasporttype varchar(32) default NULL,
2525 acctstarttime datetime NULL default NULL,
2626 acctupdatetime datetime NULL default NULL,
131131 #
132132 # Table structure for table 'radpostauth'
133133 #
134 # Note: MySQL versions since 5.6.4 support fractional precision timestamps
135 # which we use here. Replace the authdate definition with the following
136 # if your software is too old:
137 #
138 # authdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
139 #
134140 CREATE TABLE IF NOT EXISTS radpostauth (
135141 id int(11) NOT NULL auto_increment,
136142 username varchar(64) NOT NULL default '',
137143 pass varchar(64) NOT NULL default '',
138144 reply varchar(32) NOT NULL default '',
139 authdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
145 authdate timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
140146 PRIMARY KEY (id),
141147 KEY username (username(32))
142148 ) ENGINE = INNODB;
2222 username varchar(64) NOT NULL default '',
2323 realm varchar(64) default '',
2424 nasipaddress varchar(15) NOT NULL default '',
25 nasportid varchar(15) default NULL,
25 nasportid varchar(32) default NULL,
2626 nasporttype varchar(32) default NULL,
2727 acctstarttime datetime NULL default NULL,
2828 acctupdatetime datetime NULL default NULL,
137137 username varchar(64) NOT NULL default '',
138138 pass varchar(64) NOT NULL default '',
139139 reply varchar(32) NOT NULL default '',
140 authdate timestamp NOT NULL,
140 authdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
141141 PRIMARY KEY (id)
142142 ) ENGINE=ndbcluster;
0 # -*- text -*-
1 #
2 # main/oracle/process-radacct.sql -- Schema extensions for processing radacct entries
3 #
4 # $Id$
5
6 -- ---------------------------------
7 -- - Per-user data usage over time -
8 -- ---------------------------------
9 --
10 -- An extension to the standard schema to hold per-user data usage statistics
11 -- for arbitrary periods.
12 --
13 -- The data_usage_by_period table is populated by periodically calling the
14 -- fr_new_data_usage_period stored procedure.
15 --
16 -- This table can be queried in various ways to produce reports of aggregate
17 -- data use over time. For example, if the fr_new_data_usage_period SP is
18 -- invoked one per day just after midnight, to produce usage data with daily
19 -- granularity, then a reasonably accurate monthly bandwidth summary for a
20 -- given user could be obtained with:
21 --
22 -- SELECT
23 -- MIN(TO_CHAR(period_start, 'YYYY-Month')) AS month,
24 -- SUM(acctinputoctets)/1000/1000/1000 AS GB_in,
25 -- SUM(acctoutputoctets)/1000/1000/1000 AS GB_out
26 -- FROM
27 -- data_usage_by_period
28 -- WHERE
29 -- username='bob' AND
30 -- period_end IS NOT NULL
31 -- GROUP BY
32 -- TRUNC(period_start,'month');
33 --
34 -- +----------------+----------------+-----------------+
35 -- | MONTH | GB_IN | GB_OUT |
36 -- +----------------+----------------+-----------------+
37 -- | 2019-July | 5.782279230000 | 50.545664820000 |
38 -- | 2019-August | 4.230543340000 | 48.523096420000 |
39 -- | 2019-September | 4.847360590000 | 48.631835480000 |
40 -- | 2019-October | 6.456763250000 | 51.686231930000 |
41 -- | 2019-November | 6.362537730000 | 52.385710570000 |
42 -- | 2019-December | 4.301524440000 | 50.762240270000 |
43 -- | 2020-January | 5.436280540000 | 49.067775280000 |
44 -- +----------------+----------------+-----------------+
45 --
46 CREATE TABLE data_usage_by_period (
47 id NUMBER GENERATED BY DEFAULT AS IDENTITY,
48 username VARCHAR(64) NOT NULL,
49 period_start TIMESTAMP WITH TIME ZONE NOT NULL,
50 period_end TIMESTAMP WITH TIME ZONE,
51 acctinputoctets NUMERIC(19),
52 acctoutputoctets NUMERIC(19),
53 PRIMARY KEY (id)
54 );
55 CREATE UNIQUE INDEX idx_data_usage_by_period_username_period_start ON data_usage_by_period (username,period_start);
56 CREATE INDEX idx_data_usage_by_period_period_start ON data_usage_by_period (period_start);
57
58 --
59 -- Stored procedure that when run with some arbitrary frequency, say
60 -- once per day by cron, will process the recent radacct entries to extract
61 -- time-windowed data containing acct{input,output}octets ("data usage") per
62 -- username, per period.
63 --
64 -- Each invocation will create new rows in the data_usage_by_period tables
65 -- containing the data used by each user since the procedure was last invoked.
66 -- The intervals do not need to be identical but care should be taken to
67 -- ensure that the start/end of each period aligns well with any intended
68 -- reporting intervals.
69 --
70 -- It can be invoked by running:
71 --
72 -- CALL fr_new_data_usage_period();
73 --
74 --
75 CREATE OR REPLACE PROCEDURE fr_new_data_usage_period
76 AS
77 v_start TIMESTAMP WITH TIME ZONE;
78 v_end TIMESTAMP WITH TIME ZONE;
79 BEGIN
80
81 SELECT COALESCE(MAX(period_start), TO_DATE('1970-01-01','YYYY-MM-DD')) INTO v_start FROM data_usage_by_period;
82 SELECT CAST(CURRENT_TIMESTAMP AS DATE) INTO v_end FROM dual;
83
84 BEGIN
85
86 --
87 -- Add the data usage for the sessions that were active in the current
88 -- period to the table. Include all sessions that finished since the start
89 -- of this period as well as those still ongoing.
90 --
91 MERGE INTO data_usage_by_period d
92 USING (
93 SELECT
94 username,
95 MIN(v_start) period_start,
96 MIN(v_end) period_end,
97 SUM(acctinputoctets) AS acctinputoctets,
98 SUM(acctoutputoctets) AS acctoutputoctets
99 FROM
100 radacct
101 WHERE
102 acctstoptime > v_start OR
103 acctstoptime IS NULL
104 GROUP BY
105 username
106 ) s
107 ON ( d.username = s.username AND d.period_start = s.period_start )
108 WHEN MATCHED THEN
109 UPDATE SET
110 acctinputoctets = d.acctinputoctets + s.acctinputoctets,
111 acctoutputoctets = d.acctoutputoctets + s.acctoutputoctets,
112 period_end = v_end
113 WHEN NOT MATCHED THEN
114 INSERT
115 (username, period_start, period_end, acctinputoctets, acctoutputoctets)
116 VALUES
117 (s.username, s.period_start, s.period_end, s.acctinputoctets, s.acctoutputoctets);
118
119 --
120 -- Create an open-ended "next period" for all ongoing sessions and carry a
121 -- negative value of their data usage to avoid double-accounting when we
122 -- process the next period. Their current data usage has already been
123 -- allocated to the current and possibly previous periods.
124 --
125 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
126 SELECT *
127 FROM (
128 SELECT
129 username,
130 v_end + NUMTODSINTERVAL(1,'SECOND'),
131 NULL,
132 0 - SUM(acctinputoctets),
133 0 - SUM(acctoutputoctets)
134 FROM
135 radacct
136 WHERE
137 acctstoptime IS NULL
138 GROUP BY
139 username
140 ) s;
141
142 END;
143
144 END;
145 /
1919 #sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}}"
2020 #
2121 sql_user_name = "%{User-Name}"
22
23 #######################################################################
24 # Query config: Event-Timestamp
25 #######################################################################
26 # event_timestamp_epoch is the basis for the time inserted into
27 # accounting records. Typically this will be the Event-Timestamp of the
28 # accounting request, which is provided by a NAS.
29 #
30 # Uncomment the next line, if you want the timestamp to be based on the
31 # request reception time recorded by this server, for example if you
32 # distrust the provided Event-Timestamp.
33 #event_timestamp_epoch = "%l"
34
35 event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
36
37 # event_timestamp is the SQL snippet for converting an epoch timestamp
38 # to an SQL date.
39
40 event_timestamp = "TO_DATE('1970-01-01','YYYY-MM-DD') + NUMTODSINTERVAL(${event_timestamp_epoch},'SECOND')"
2241
2342 #######################################################################
2443 # Default profile
182201 query = "\
183202 UPDATE ${....acct_table1} \
184203 SET \
185 AcctStopTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), \
186 AcctSessionTime = round((TO_DATE('%S','yyyy-mm-dd hh24:mi:ss') - \
204 AcctStopTime = ${....event_timestamp}, \
205 AcctSessionTime = ROUND((${....event_timestamp} - \
187206 TO_DATE(TO_CHAR(acctstarttime, 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh24:mi:ss'))*86400), \
188207 AcctTerminateCause='%{%{Acct-Terminate-Cause}:-NAS-Reboot}', \
189208 AcctStopDelay = %{%{Acct-Delay-Time}:-0} \
190209 WHERE AcctStopTime IS NULL \
191210 AND NASIPAddress = '%{NAS-IP-Address}' \
192 AND AcctStartTime <= TO_DATE('%S','yyyy-mm-dd hh24:mi:ss')"
211 AND AcctStartTime <= ${....event_timestamp}"
193212 }
194213
195214 accounting-off {
311330 '%{NAS-IP-Address}', \
312331 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
313332 '%{NAS-Port-Type}', \
314 TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), \
333 ${....event_timestamp}, \
315334 NULL, \
316335 '0', \
317336 '%{Acct-Authentic}', \
367386 query = "\
368387 UPDATE ${....acct_table1} \
369388 SET \
370 AcctStartTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), \
389 AcctStartTime = ${....event_timestamp}, \
371390 AcctStartDelay = '%{%{Acct-Delay-Time}:-0}', \
372391 ConnectInfo_start = '%{Connect-Info}' \
373392 WHERE AcctUniqueId = '%{Acct-Unique-Session-ID}' \
487506 query = "\
488507 UPDATE ${....acct_table2} \
489508 SET \
490 AcctStopTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), \
509 AcctStopTime = ${....event_timestamp}, \
491510 AcctSessionTime = '%{Acct-Session-Time}', \
492511 AcctInputOctets = '%{Acct-Input-Octets}' + \
493512 ('%{%{Acct-Input-Gigawords}:-0}' * 4294967296), \
539558 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
540559 '%{NAS-Port-Type}', \
541560 NULL, \
542 TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), \
561 ${....event_timestamp}, \
543562 '%{Acct-Session-Time}', \
544563 '%{Acct-Authentic}', \
545564 '', \
620639 '%{User-Name}', \
621640 '%{%{User-Password}:-%{Chap-Password}}', \
622641 '%{reply:Packet-Type}', \
623 TO_TIMESTAMP('%S','YYYY-MM-DDHH24:MI:SS'))"
642 TO_TIMESTAMP('%S.%M','YYYY-MM-DDHH24:MI:SS.FF'))"
624643 }
158158 UserName VARCHAR(64) NOT NULL,
159159 Pass VARCHAR(64),
160160 Reply VARCHAR(64),
161 AuthDate DATE
161 AuthDate TIMESTAMP(6) WITH TIME ZONE
162162 );
163163
164164 CREATE SEQUENCE radpostauth_seq START WITH 1 INCREMENT BY 1;
171171 SELECT radpostauth_seq.nextval into :new.id from dual;
172172 end if;
173173 if (:new.AuthDate is null) then
174 select sysdate into :new.AuthDate from dual;
174 select systimestamp into :new.AuthDate from dual;
175175 end if;
176176 END;
177177
0 # -*- text -*-
1 #
2 # main/postgresql/process-radacct.sql -- Schema extensions for processing radacct entries
3 #
4 # $Id$
5
6 -- ---------------------------------
7 -- - Per-user data usage over time -
8 -- ---------------------------------
9 --
10 -- An extension to the standard schema to hold per-user data usage statistics
11 -- for arbitrary periods.
12 --
13 -- The data_usage_by_period table is populated by periodically calling the
14 -- fr_new_data_usage_period stored procedure.
15 --
16 -- This table can be queried in various ways to produce reports of aggregate
17 -- data use over time. For example, if the fr_new_data_usage_period SP is
18 -- invoked one per day just after midnight, to produce usage data with daily
19 -- granularity, then a reasonably accurate monthly bandwidth summary for a
20 -- given user could be obtained by queriing this table with:
21 --
22 -- SELECT
23 -- TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-Month') AS month,
24 -- TRUNC(SUM(acctinputoctets)/1000/1000/1000,9) AS gb_in,
25 -- TRUNC(SUM(acctoutputoctets)/1000/1000/1000,9) AS gb_out
26 -- FROM
27 -- data_usage_by_period
28 -- WHERE
29 -- username='bob' AND
30 -- period_end IS NOT NULL
31 -- GROUP BY
32 -- month;
33 --
34 -- month | gb_in | gb_out
35 -- ----------------+-------------+--------------
36 -- 2019-July | 5.782279231 | 50.545664824
37 -- 2019-August | 4.230543344 | 48.523096424
38 -- 2019-September | 4.847360599 | 48.631835488
39 -- 2019-October | 6.456763254 | 51.686231937
40 -- 2019-November | 6.362537735 | 52.385710572
41 -- 2019-December | 4.301524442 | 50.762240277
42 -- 2020-January | 5.436280545 | 49.067775286
43 -- (7 rows)
44 --
45 CREATE TABLE data_usage_by_period (
46 username text,
47 period_start timestamp with time zone,
48 period_end timestamp with time zone,
49 acctinputoctets bigint,
50 acctoutputoctets bigint
51 );
52 ALTER TABLE data_usage_by_period ADD CONSTRAINT data_usage_by_period_pkey PRIMARY KEY (username, period_start);
53
54
55 --
56 -- Stored procedure that when run with some arbitrary frequency, say
57 -- once per day by cron, will process the recent radacct entries to extract
58 -- time-windowed data containing acct{input,output}octets ("data usage") per
59 -- username, per period.
60 --
61 -- Each invocation will create new rows in the data_usage_by_period tables
62 -- containing the data used by each user since the procedure was last invoked.
63 -- The intervals do not need to be identical but care should be taken to
64 -- ensure that the start/end of each period aligns well with any intended
65 -- reporting intervals.
66 --
67 -- It can be invoked by running:
68 --
69 -- SELECT fr_new_data_usage_period();
70 --
71 --
72 CREATE OR REPLACE FUNCTION fr_new_data_usage_period ()
73 RETURNS void
74 LANGUAGE plpgsql
75 AS $$
76 DECLARE v_start timestamp;
77 DECLARE v_end timestamp;
78 BEGIN
79
80 SELECT COALESCE(MAX(period_start), TO_TIMESTAMP(0)) INTO v_start FROM data_usage_by_period;
81 SELECT DATE_TRUNC('second',CURRENT_TIMESTAMP) INTO v_end;
82
83 --
84 -- Add the data usage for the sessions that were active in the current
85 -- period to the table. Include all sessions that finished since the start
86 -- of this period as well as those still ongoing.
87 --
88 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
89 SELECT *
90 FROM (
91 SELECT
92 username,
93 v_start,
94 v_end,
95 SUM(acctinputoctets) AS acctinputoctets,
96 SUM(acctoutputoctets) AS acctoutputoctets
97 FROM
98 radacct
99 WHERE
100 acctstoptime > v_start OR
101 acctstoptime IS NULL
102 GROUP BY
103 username
104 ) AS s
105 ON CONFLICT ON CONSTRAINT data_usage_by_period_pkey
106 DO UPDATE
107 SET
108 acctinputoctets = data_usage_by_period.acctinputoctets + EXCLUDED.acctinputoctets,
109 acctoutputoctets = data_usage_by_period.acctoutputoctets + EXCLUDED.acctoutputoctets,
110 period_end = v_end;
111
112 --
113 -- Create an open-ended "next period" for all ongoing sessions and carry a
114 -- negative value of their data usage to avoid double-accounting when we
115 -- process the next period. Their current data usage has already been
116 -- allocated to the current and possibly previous periods.
117 --
118 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
119 SELECT *
120 FROM (
121 SELECT
122 username,
123 v_end + INTERVAL '1 SECOND',
124 NULL::timestamp,
125 0 - SUM(acctinputoctets),
126 0 - SUM(acctoutputoctets)
127 FROM
128 radacct
129 WHERE
130 acctstoptime IS NULL
131 GROUP BY
132 username
133 ) AS s;
134
135 END
136 $$;
3737 #sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-none}}"
3838
3939 sql_user_name = "%{User-Name}"
40
41 #######################################################################
42 # Query config: Event-Timestamp
43 #######################################################################
44 # event_timestamp_epoch is the basis for the time inserted into
45 # accounting records. Typically this will be the Event-Timestamp of the
46 # accounting request, which is usually provided by a NAS.
47 #
48 # Uncomment the next line, if you want the timestamp to be based on the
49 # request reception time recorded by this server, for example if you
50 # distrust the provided Event-Timestamp.
51 #event_timestamp_epoch = "%l"
52
53 event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
54
55 # event_timestamp is the SQL snippet for converting an epoch timestamp
56 # to an SQL date.
57
58 event_timestamp = "TO_TIMESTAMP(${event_timestamp_epoch})"
4059
4160 #######################################################################
4261 # Default profile
263282 query = "\
264283 UPDATE ${....acct_table1} \
265284 SET \
266 AcctStopTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
267 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
268 AcctSessionTime = (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM(AcctStartTime))), \
285 AcctStopTime = ${....event_timestamp}, \
286 AcctUpdateTime = ${....event_timestamp}, \
287 AcctSessionTime = (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM(AcctStartTime))), \
269288 AcctTerminateCause = '%{%{Acct-Terminate-Cause}:-NAS-Reboot}' \
270289 WHERE AcctStopTime IS NULL \
271290 AND NASIPAddress= '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}' \
272 AND AcctStartTime <= '%S'::timestamp"
291 AND AcctStartTime <= ${....event_timestamp}"
273292 }
274293
275294 accounting-off {
295314 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
296315 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
297316 '%{NAS-Port-Type}', \
298 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
317 ${....event_timestamp}, \
299318 NULL, \
300319 NULL, \
301320 0, \
318337 query = "\
319338 UPDATE ${....acct_table1} \
320339 SET \
321 AcctStartTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
322 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
340 AcctStartTime = ${....event_timestamp}, \
341 AcctUpdateTime = ${....event_timestamp}, \
323342 ConnectInfo_start = '%{Connect-Info}', \
324343 AcctSessionId = '%{Acct-Session-Id}' \
325344 WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}' \
338357 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
339358 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
340359 '%{NAS-Port-Type}', \
341 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
342 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
360 ${....event_timestamp}, \
361 ${....event_timestamp}, \
343362 NULL, \
344363 0, \
345364 '%{Acct-Authentic}', \
360379 ON CONFLICT (AcctUniqueId) \
361380 DO UPDATE \
362381 SET \
363 AcctStartTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
364 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
382 AcctStartTime = ${....event_timestamp}, \
383 AcctUpdateTime = ${....event_timestamp}, \
365384 ConnectInfo_start = '%{Connect-Info}' \
366385 WHERE ${....acct_table1}.AcctUniqueId = '%{Acct-Unique-Session-Id}' \
367386 AND ${....acct_table1}.AcctStopTime IS NULL"
389408 FramedIPv6Prefix = NULLIF('%{Framed-IPv6-Prefix}', '')::inet, \
390409 FramedInterfaceId = NULLIF('%{Framed-Interface-Id}', ''), \
391410 DelegatedIPv6Prefix = NULLIF('%{Delegated-IPv6-Prefix}', '')::inet, \
392 AcctStartTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
393 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}) \
411 AcctStartTime = ${....event_timestamp}, \
412 AcctUpdateTime = ${....event_timestamp} \
394413 WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}' \
395414 AND AcctStopTime IS NULL"
396415
398417 query = "\
399418 UPDATE ${....acct_table1} \
400419 SET \
401 AcctStartTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
402 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
420 AcctStartTime = ${....event_timestamp}, \
421 AcctUpdateTime = ${....event_timestamp}, \
403422 ConnectInfo_start = '%{Connect-Info}' \
404423 WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'"
405424 }
414433 FramedInterfaceId = NULLIF('%{Framed-Interface-Id}', ''), \
415434 DelegatedIPv6Prefix = NULLIF('%{Delegated-IPv6-Prefix}', '')::inet, \
416435 AcctSessionTime = %{%{Acct-Session-Time}:-NULL}, \
417 AcctInterval = (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM (COALESCE(AcctUpdateTime, AcctStartTime)))), \
418 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
436 AcctInterval = (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM (COALESCE(AcctUpdateTime, AcctStartTime)))), \
437 AcctUpdateTime = ${....event_timestamp}, \
419438 AcctInputOctets = (('%{%{Acct-Input-Gigawords}:-0}'::bigint << 32) + \
420439 '%{%{Acct-Input-Octets}:-0}'::bigint), \
421440 AcctOutputOctets = (('%{%{Acct-Output-Gigawords}:-0}'::bigint << 32) + \
434453 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
435454 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
436455 '%{NAS-Port-Type}', \
437 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
438 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
456 ${....event_timestamp}, \
457 ${....event_timestamp}, \
439458 NULL, \
440459 %{%{Acct-Session-Time}:-NULL}, \
441460 '%{Acct-Authentic}', \
481500 FramedIPv6Prefix = NULLIF('%{Framed-IPv6-Prefix}', '')::inet, \
482501 FramedInterfaceId = NULLIF('%{Framed-Interface-Id}', ''), \
483502 DelegatedIPv6Prefix = NULLIF('%{Delegated-IPv6-Prefix}', '')::inet, \
484 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
485 AcctSessionTime = COALESCE(%{%{Acct-Session-Time}:-NULL}, \
486 (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
503 AcctUpdateTime = ${....event_timestamp}, \
504 AcctSessionTime = COALESCE(%{%{Acct-Session-Time}:-NULL},
505 (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
487506 AcctInputOctets = (('%{%{Acct-Input-Gigawords}:-0}'::bigint << 32) + \
488507 '%{%{Acct-Input-Octets}:-0}'::bigint), \
489508 AcctOutputOctets = (('%{%{Acct-Output-Gigawords}:-0}'::bigint << 32) + \
496515 query = "\
497516 UPDATE ${....acct_table2} \
498517 SET \
499 AcctStopTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
500 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
518 AcctStopTime = ${....event_timestamp}, \
519 AcctUpdateTime = ${....event_timestamp}, \
501520 AcctSessionTime = COALESCE(%{%{Acct-Session-Time}:-NULL}, \
502 (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
521 (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
503522 AcctInputOctets = (('%{%{Acct-Input-Gigawords}:-0}'::bigint << 32) + \
504523 '%{%{Acct-Input-Octets}:-0}'::bigint), \
505524 AcctOutputOctets = (('%{%{Acct-Output-Gigawords}:-0}'::bigint << 32) + \
525544 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
526545 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
527546 '%{NAS-Port-Type}', \
528 TO_TIMESTAMP(%{integer:Event-Timestamp} - %{%{Acct-Session-Time}:-0}), \
529 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
530 TO_TIMESTAMP(%{integer:Event-Timestamp}), \
547 TO_TIMESTAMP(${....event_timestamp_epoch} - %{%{Acct-Session-Time}:-0}), \
548 ${....event_timestamp}, \
549 ${....event_timestamp}, \
531550 NULLIF('%{Acct-Session-Time}', '')::bigint, \
532551 '%{Acct-Authentic}', \
533552 '%{Connect-Info}', \
572591 FramedIPv6Prefix = NULLIF('%{Framed-IPv6-Prefix}', '')::inet, \
573592 FramedInterfaceId = NULLIF('%{Framed-Interface-Id}', ''), \
574593 DelegatedIPv6Prefix = NULLIF('%{Delegated-IPv6-Prefix}', '')::inet, \
575 AcctStopTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
576 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
594 AcctStopTime = ${....event_timestamp}, \
595 AcctUpdateTime = ${....event_timestamp}, \
577596 AcctSessionTime = COALESCE(%{%{Acct-Session-Time}:-NULL}, \
578 (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
597 (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
579598 AcctInputOctets = (('%{%{Acct-Input-Gigawords}:-0}'::bigint << 32) + \
580599 '%{%{Acct-Input-Octets}:-0}'::bigint), \
581600 AcctOutputOctets = (('%{%{Acct-Output-Gigawords}:-0}'::bigint << 32) + \
589608 query = "\
590609 UPDATE ${....acct_table2} \
591610 SET \
592 AcctStopTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
593 AcctUpdateTime = TO_TIMESTAMP(%{integer:Event-Timestamp}), \
611 AcctStopTime = ${....event_timestamp}, \
612 AcctUpdateTime = ${....event_timestamp}, \
594613 AcctSessionTime = COALESCE(%{%{Acct-Session-Time}:-NULL}, \
595 (%{integer:Event-Timestamp} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
614 (${....event_timestamp_epoch} - EXTRACT(EPOCH FROM(AcctStartTime)))), \
596615 AcctInputOctets = (('%{%{Acct-Input-Gigawords}:-0}'::bigint << 32) + \
597616 '%{%{Acct-Input-Octets}:-0}'::bigint), \
598617 AcctOutputOctets = (('%{%{Acct-Output-Gigawords}:-0}'::bigint << 32) + \
635654 '%{User-Name}', \
636655 '%{%{User-Password}:-%{Chap-Password}}', \
637656 '%{reply:Packet-Type}', \
638 NOW())"
657 '%S.%M')"
639658 }
0 #!/bin/sh
1 #
2 # main/sqlite/process-radacct-refresh.sh -- Schema extensions and script for processing radacct entries
3 #
4 # $Id$
5
6 #
7 # See process-radacct-schema.sql for details.
8 #
9
10 if [ "$#" -ne 1 ]; then
11 echo "Usage: process-radacct-refresh.sh SQLITE_DB_FILE" 2>&1
12 exit 1
13 fi
14
15 if [ ! -r "$1" ]; then
16 echo "The SQLite database must exist: $1" 1>&2
17 exit 1
18 fi
19
20 cat <<EOF | sqlite3 "$1"
21
22 --
23 -- SQLite doesn't have a concept of session variables so we fake it.
24 --
25 DROP TABLE IF EXISTS vars;
26 CREATE TEMPORARY TABLE vars (
27 key text,
28 value text,
29 PRIMARY KEY (key)
30 );
31
32 INSERT INTO vars SELECT 'v_start', COALESCE(MAX(period_start), DATETIME(0, 'unixepoch')) FROM data_usage_by_period;
33 INSERT INTO vars SELECT 'v_end', CURRENT_TIMESTAMP;
34
35
36 --
37 -- Make of copy of the sessions that were active during this period to
38 -- avoid having to execute a potentially long transaction that might hold a
39 -- global database lock.
40 --
41 DROP TABLE IF EXISTS radacct_sessions;
42 CREATE TEMPORARY TABLE radacct_sessions (
43 username text,
44 acctstarttime datetime,
45 acctstoptime datetime,
46 acctinputoctets bigint,
47 acctoutputoctets bigint
48 );
49 CREATE INDEX temp.idx_radacct_sessions_username ON radacct_sessions(username);
50 CREATE INDEX temp.idx_radacct_sessions_acctstoptime ON radacct_sessions(acctstoptime);
51
52 INSERT INTO radacct_sessions
53 SELECT
54 username,
55 acctstarttime,
56 acctstoptime,
57 acctinputoctets,
58 acctoutputoctets
59 FROM
60 radacct
61 WHERE
62 acctstoptime > (SELECT value FROM vars WHERE key='v_start') OR
63 acctstoptime IS NULL;
64
65
66 --
67 -- Add the data usage for the sessions that were active in the current
68 -- period to the table. Include all sessions that finished since the start
69 -- of this period as well as those still ongoing.
70 --
71 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
72 SELECT
73 username,
74 (SELECT value FROM vars WHERE key='v_start'),
75 (SELECT value FROM vars WHERE key='v_end'),
76 SUM(acctinputoctets) AS acctinputoctets,
77 SUM(acctoutputoctets) AS acctoutputoctets
78 FROM
79 radacct_sessions
80 GROUP BY
81 username
82 ON CONFLICT(username,period_start) DO UPDATE
83 SET
84 acctinputoctets = data_usage_by_period.acctinputoctets + EXCLUDED.acctinputoctets,
85 acctoutputoctets = data_usage_by_period.acctoutputoctets + EXCLUDED.acctoutputoctets,
86 period_end = (SELECT value FROM vars WHERE key='v_end');
87
88 --
89 -- Create an open-ended "next period" for all ongoing sessions and carry a
90 -- negative value of their data usage to avoid double-accounting when we
91 -- process the next period. Their current data usage has already been
92 -- allocated to the current and possibly previous periods.
93 --
94 INSERT INTO data_usage_by_period (username, period_start, period_end, acctinputoctets, acctoutputoctets)
95 SELECT
96 username,
97 (SELECT DATETIME(value, '+1 seconds') FROM vars WHERE key='v_end'),
98 NULL,
99 0 - SUM(acctinputoctets),
100 0 - SUM(acctoutputoctets)
101 FROM
102 radacct_sessions
103 WHERE
104 acctstoptime IS NULL
105 GROUP BY
106 username;
107
108 DROP TABLE vars;
109 DROP TABLE radacct_sessions;
110
111 EOF
0 # -*- text -*-
1 #
2 # main/sqlite/process-radacct.sql -- Schema extensions and script for processing radacct entries
3 #
4 # $Id$
5
6 -- ---------------------------------
7 -- - Per-user data usage over time -
8 -- ---------------------------------
9 --
10 -- An extension to the standard schema to hold per-user data usage statistics
11 -- for arbitrary periods.
12 --
13 -- The data_usage_by_period table is populated by periodically calling the
14 -- process-radacct-refresh.sh script.
15 --
16 -- This table can be queried in various ways to produce reports of aggregate
17 -- data use over time. For example, if the refresh script is invoked once per
18 -- day just after midnight, to produce usage data with daily granularity, then
19 -- a reasonably accurate monthly bandwidth summary for a given user could be
20 -- obtained by queriing this table with:
21 --
22 -- SELECT
23 -- STRFTIME('%Y-%m',CURRENT_TIMESTAMP) AS month,
24 -- SUM(acctinputoctets)*1.0/1000/1000/1000 AS gb_in,
25 -- SUM(acctoutputoctets)*1.0/1000/1000/1000 AS gb_out
26 -- FROM
27 -- data_usage_by_period
28 -- WHERE
29 -- username='bob' AND
30 -- period_end IS NOT NULL
31 -- GROUP BY
32 -- month;
33 --
34 -- 2019-07|5.782279231|50.545664824
35 -- 2019-08|4.230543344|48.523096424
36 -- 2019-09|4.847360599|48.631835488
37 -- 2019-10|6.456763254|51.686231937
38 -- 2019-11|6.362537735|52.385710572
39 -- 2019-12|4.301524442|50.762240277
40 -- 2020-01|5.436280545|49.067775286
41 --
42 CREATE TABLE data_usage_by_period (
43 username text,
44 period_start datetime,
45 period_end datetime,
46 acctinputoctets bigint,
47 acctoutputoctets bigint,
48 PRIMARY KEY (username, period_start)
49 );
50 CREATE INDEX idx_data_usage_by_period_period_start ON data_usage_by_period(period_start);
2424 #sql_user_name = "%{%{Stripped-User-Name}:-%{%{User-Name}:-DEFAULT}}"
2525 #
2626 sql_user_name = "%{User-Name}"
27
28 #######################################################################
29 # Query config: Event-Timestamp
30 #######################################################################
31 # event_timestamp_epoch is the basis for the time inserted into
32 # accounting records. Typically this will be the Event-Timestamp of the
33 # accounting request, which is usually provided by a NAS.
34 #
35 # Uncomment the next line, if you want the timestamp to be based on the
36 # request reception time recorded by this server, for example if you
37 # distrust the provided Event-Timestamp.
38 #event_timestamp_epoch = "%l"
39
40 event_timestamp_epoch = "%{%{integer:Event-Timestamp}:-%l}"
41
42 # event_timestamp is the SQL snippet for converting an epoch timestamp
43 # to an SQL date.
44
45 event_timestamp = "${event_timestamp_epoch}"
46
47 # NOTE: Recent SQLite versions allow proper arithmetic with dates
48 # stored as strings including comparison using an index, so we keep
49 # these variables differentiated in preparation for switching away from
50 # integer storage.
2751
2852 #######################################################################
2953 # Default profile
221245 query = "\
222246 UPDATE ${....acct_table1} \
223247 SET \
224 acctstoptime = %{%{integer:Event-Timestamp}:-date('now')}, \
248 acctstoptime = ${....event_timestamp}, \
225249 acctsessiontime = \
226 (%{%{integer:Event-Timestamp}:-strftime('%%s', 'now')} \
227 - strftime('%%s', acctstarttime)), \
250 (${....event_timestamp_epoch} \
251 - acctstarttime), \
228252 acctterminatecause = '%{Acct-Terminate-Cause}' \
229253 WHERE acctstoptime IS NULL \
230254 AND nasipaddress = '%{NAS-IP-Address}' \
231 AND acctstarttime <= %{integer:Event-Timestamp}"
255 AND acctstarttime <= ${....event_timestamp}"
232256 }
233257
234258 accounting-off {
254278 '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}', \
255279 NULLIF('%{%{NAS-Port-ID}:-%{NAS-Port}}', ''), \
256280 '%{NAS-Port-Type}', \
257 %{%{integer:Event-Timestamp}:-date('now')}, \
281 ${....event_timestamp}, \
258282 NULL, \
259283 NULL, \
260284 0, \
276300
277301 query = "\
278302 UPDATE ${....acct_table1} SET \
279 AcctStartTime = %{%{integer:Event-Timestamp}:-date('now')}, \
280 AcctUpdateTime = %{%{integer:Event-Timestamp}:-date('now')}, \
303 AcctStartTime = ${....event_timestamp}, \
304 AcctUpdateTime = ${....event_timestamp}, \
281305 ConnectInfo_start = '%{Connect-Info}', \
282306 AcctSessionId = '%{Acct-Session-Id}' \
283307 WHERE UserName = '%{SQL-User-Name}' \
302326 '%{NAS-IP-Address}', \
303327 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
304328 '%{NAS-Port-Type}', \
305 %{%{integer:Event-Timestamp}:-date('now')}, \
306 %{%{integer:Event-Timestamp}:-date('now')}, \
329 ${....event_timestamp}, \
330 ${....event_timestamp}, \
307331 NULL, \
308332 '0', \
309333 '%{Acct-Authentic}', \
345369 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
346370 framedinterfaceid = '%{Framed-Interface-Id}', \
347371 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
348 AcctStartTime = %{%{integer:Event-Timestamp}:-date('now')}, \
349 AcctUpdateTime = %{%{integer:Event-Timestamp}:-date('now')} \
372 AcctStartTime = ${....event_timestamp}, \
373 AcctUpdateTime = ${....event_timestamp} \
350374 WHERE UserName = '%{SQL-User-Name}' \
351375 AND NASIPAddress = '%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}}' \
352376 AND NASPortId = '%{%{NAS-Port-ID}:-%{NAS-Port}}' \
359383 #
360384 query = "\
361385 UPDATE ${....acct_table1} SET \
362 acctstarttime = %{%{integer:Event-Timestamp}:-date('now')}, \
363 acctupdatetime = %{%{integer:Event-Timestamp}:-date('now')}, \
386 acctstarttime = ${....event_timestamp}, \
387 acctupdatetime = ${....event_timestamp}, \
364388 connectinfo_start = '%{Connect-Info}' \
365389 WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'"
366390 }
374398 query = "\
375399 UPDATE ${....acct_table1} \
376400 SET \
377 acctupdatetime = %{%{integer:Event-Timestamp}:-date('now')}, \
401 acctupdatetime = ${....event_timestamp}, \
378402 acctinterval = 0, \
379403 framedipaddress = '%{Framed-IP-Address}', \
380404 framedipv6address = '%{Framed-IPv6-Address}', \
403427 '%{NAS-IP-Address}', \
404428 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
405429 '%{NAS-Port-Type}', \
406 (%{%{integer:Event-Timestamp}:-strftime('%%s', 'now')} - %{%{Acct-Session-Time}:-0}), \
407 %{%{integer:Event-Timestamp}:-date('now')}, \
430 (${....event_timestamp_epoch} - %{%{Acct-Session-Time}:-0}), \
431 ${....event_timestamp}, \
408432 NULL, \
409433 %{%{Acct-Session-Time}:-NULL}, \
410434 '%{Acct-Authentic}', \
448472 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
449473 framedinterfaceid = '%{Framed-Interface-Id}', \
450474 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
451 AcctUpdateTime = %{%{integer:Event-Timestamp}:-date('now')}, \
475 AcctUpdateTime = ${....event_timestamp}, \
452476 AcctSessionTime = %{%{Acct-Session-Time}:-NULL}, \
453477 AcctInputOctets = '%{%{Acct-Input-Gigawords}:-0}' \
454478 << 32 | '%{%{Acct-Input-Octets}:-0}', \
468492 #
469493 query = "\
470494 UPDATE ${....acct_table2} SET \
471 acctstoptime = %{%{integer:Event-Timestamp}:-date('now')}, \
495 acctstoptime = ${....event_timestamp}, \
472496 acctsessiontime = %{%{Acct-Session-Time}:-NULL}, \
473497 acctinputoctets = %{%{Acct-Input-Gigawords}:-0} \
474498 << 32 | %{%{Acct-Input-Octets}:-0}, \
493517 '%{NAS-IP-Address}', \
494518 '%{%{NAS-Port-ID}:-%{NAS-Port}}', \
495519 '%{NAS-Port-Type}', \
496 (%{%{integer:Event-Timestamp}:-strftime('%%s', 'now')} - %{%{Acct-Session-Time}:-0}), \
497 %{%{integer:Event-Timestamp}:-date('now')}, \
498 %{%{integer:Event-Timestamp}:-date('now')}, \
520 (${....event_timestamp_epoch} - %{%{Acct-Session-Time}:-0}), \
521 ${....event_timestamp}, \
522 ${....event_timestamp}, \
499523 %{%{Acct-Session-Time}:-NULL}, \
500524 '%{Acct-Authentic}', \
501525 '', \
538562 framedipv6prefix = '%{Framed-IPv6-Prefix}', \
539563 framedinterfaceid = '%{Framed-Interface-Id}', \
540564 delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
541 AcctStopTime = %{%{integer:Event-Timestamp}:-date('now')}, \
542 AcctUpdateTime = %{%{integer:Event-Timestamp}:-date('now')}, \
565 AcctStopTime = ${....event_timestamp}, \
566 AcctUpdateTime = ${....event_timestamp}, \
543567 AcctSessionTime = %{%{Acct-Session-Time}:-NULL}, \
544568 AcctInputOctets = '%{%{Acct-Input-Gigawords}:-0}' \
545569 << 32 | '%{%{Acct-Input-Octets}:-0}', \
583607 '%{SQL-User-Name}', \
584608 '%{%{User-Password}:-%{Chap-Password}}', \
585609 '%{reply:Packet-Type}', \
586 '%S')"
610 '%S.%M')"
587611 }
1616 username varchar(64) NOT NULL default '',
1717 realm varchar(64) default '',
1818 nasipaddress varchar(15) NOT NULL default '',
19 nasportid varchar(15) default NULL,
19 nasportid varchar(32) default NULL,
2020 nasporttype varchar(32) default NULL,
2121 acctstarttime datetime NULL default NULL,
2222 acctupdatetime datetime NULL default NULL,
637637 # sradutmp
638638
639639 # Return an address to the IP Pool when we see a stop record.
640 # main_pool
640 # sqlippool
641641
642642 #
643643 # Log traffic to an SQL database.
726726 &reply: += &session-state:
727727 }
728728
729 # Get an address from the IP Pool.
730 # main_pool
729 # Refresh leases when we see a start or alive. Return an address to
730 # the IP Pool when we see a stop record.
731 # sqlippool
731732
732733
733734 # Create the CUI value and add the attribute to Access-Accept.
768769 # you will need to define the WiMAX NAI, usually via
769770 #
770771 # update request {
771 # WiMAX-MN-NAI = "%{User-Name}"
772 # &WiMAX-MN-NAI = "%{User-Name}"
772773 # }
773774 #
774775 # If you want various keys to be calculated, you will need to
777778 # taken from the cryptographic calculations. e.g.
778779 #
779780 # update reply {
780 # WiMAX-FA-RK-Key = 0x00
781 # WiMAX-MSK = "%{EAP-MSK}"
781 # &WiMAX-FA-RK-Key = 0x00
782 # &WiMAX-MSK = "%{reply:EAP-MSK}"
782783 # }
783784 #
784785 # You may want to delete the MS-MPPE-*-Keys from the reply,
2323 #
2424 # Will return "yes" if the connection has TLS enabled. It will
2525 # return "no" if TLS is not enabled for a particular listen section.
26 #
27 # A number of TLS-Client-Cert-.. attributes holds X509v3 extensions
28 # data, attributes named the way OpenSSL names them. It is possible
29 # to extract data for an extension not known to OpenSSL by defining
30 # a custom string attribute which contains extension OID in it's
31 # name after 'TLS-Client-Cert-' prefix. E.g.:
32 #
33 # ATTRIBUTE TLS-Client-Cert-1.3.6.1.4.1.311.21.7 3002 string
34 #
35 # which will yield something simmilar to:
36 #
37 # (0) eap_tls: TLS - Creating attributes from certificate OIDs
38 # (0) eap_tls: TLS-Client-Cert-1.3.6.1.4.1.311.21.7 += "0x302e06"
39 # ...
2640 #
2741 ######################################################################
2842
2727
2828 Summary: High-performance and highly configurable free RADIUS server
2929 Name: freeradius
30 Version: 3.0.20
30 Version: 3.0.21
3131 Release: 1%{?dist}
3232 License: GPLv2+ and LGPLv2+
3333 Group: System Environment/Daemons
266266 %endif
267267 %endif
268268
269 %if %{?el6:0}%{!?el6:1}
269270 %package redis
270271 Summary: Redis support for FreeRADIUS
271272 Group: System Environment/Daemons
275276
276277 %description redis
277278 This plugin provides Redis support for the FreeRADIUS server project.
279 %endif
278280
279281 %package rest
280282 Summary: REST support for FreeRADIUS
730732 # freetds
731733 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/mods-config/sql/main/mssql
732734 %attr(640,root,radiusd) %config(noreplace) %{_sysconfdir}/raddb/mods-config/sql/main/mssql/*
735 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/mods-config/sql/ippool/mssql
736 %attr(640,root,radiusd) %config(noreplace) %{_sysconfdir}/raddb/mods-config/sql/ippool/mssql/*
733737 # oracle
734738 %if %{?_with_rlm_sql_oracle:1}%{!?_with_rlm_sql_oracle:0}
735739 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/mods-config/sql
797801 %defattr(-,root,root)
798802 %{_libdir}/freeradius/rlm_sql_unixodbc.so
799803
804 %if %{?el6:0}%{!?el6:1}
800805 %files redis
801806 %defattr(-,root,root)
802807 %{_libdir}/freeradius/rlm_redis.so
803808 %{_libdir}/freeradius/rlm_rediswho.so
809 %endif
804810
805811 %files rest
806812 %defattr(-,root,root)
2929 ExecStart=/usr/sbin/radiusd -f $FREERADIUS_OPTIONS
3030 Restart=on-failure
3131 RestartSec=5
32 ExecReload=/usr/sbin/radiusd $FREERADIUS_OPTIONS -Cxm -lstdout
33 ExecReload=/bin/kill -HUP $MAINPID
3234
3335 # Don't elevate privileges after starting
3436 NoNewPrivileges=true
0 # Crossbuild
1
2 ## Summary
3
4 The "crossbuild" system is a way to build FreeRADIUS for multiple
5 different operating systems, using Docker.
6
7 The primary purpose is for developers to easily test FreeRADIUS on
8 different systems.
9
10
11 ## Common Usage
12
13 The systems supported can be listed with
14
15 make crossbuild.info
16
17 A reminder of the make targets may be seen with
18
19 make crossbuild.help
20
21 To make all the known systems (this may take quite a while, at
22 least on the first run):
23
24 make crossbuild
25
26 or for the most common systems (Debian, Ubuntu, CentOS):
27
28 make crossbuild.common
29
30
31 ## General operation
32
33 The system works by building and then starting up Docker
34 containers for the systems. When a build is triggered (either
35 generally, as above, or for a specific OS) the current git commits
36 are copied into the image and then `make test` run.
37
38 The Docker containers are left running, and may be stopped with
39
40 make crossbuild.down
41
42 The system tries to be as efficient as possible, so will not
43 rebuild from scratch every time.
44
45
46 ## Global make targets
47
48 The following targets will operate on the crossbuild system
49 globally, or on all images (unless otherwise stated):
50
51
52 ### `make crossbuild`
53
54 Create all docker images (if required), start them, build and test
55 FreeRADIUS.
56
57
58 ### `make crossbuild.common`
59
60 As `make crossbuild`, but only build and test the most common
61 systems.
62
63
64 ### `make crossbuild.info`
65
66 List all systems, together with the expected state. See
67 `crossbuild.reset`.
68
69
70 ### `make crossbuild.down`
71
72 Stop all containers.
73
74
75 ### `make crossbuild.reset`
76
77 If containers are stopped or started outside Docker, crossbuild
78 may get confused. This will clear the internal state which should
79 try and start everything from be beginning again.
80
81
82 ### `make crossbuild.clean`
83
84 Bring down all containers, clear state. This is a general "tidy
85 up".
86
87
88 ### `make crossbuild.wipe`
89
90 Don't just stop, but destroy all crossbuild docker images. This
91 will mean they need to be recreated again upon next use.
92
93
94 ## Per-image make targets
95
96 The following make targets may be used on a per-image basis:
97
98 * `make crossbuild.IMAGE`: build and test image
99 * `make crossbuild.IMAGE.log`: show latest build log
100 * `make crossbuild.IMAGE.up`: start container
101 * `make crossbuild.IMAGE.down`: stop container
102 * `make crossbuild.IMAGE.sh`: shell in container
103 * `make crossbuild.IMAGE.refresh`: push latest commits into container
104 * `make crossbuild.IMAGE.clean`: stop container and tidy up
105 * `make crossbuild.IMAGE.wipe`: remove Docker image
106
107 For example, `make crossbuild.debian10` to create, build and test
108 FreeRADIUS on Debian 10. `make crossbuild.debian10.down` will then
109 stop the container.
110
111
112 ## Docker image and container names
113
114 Docker images will be created with names in the form:
115
116 freeradius-build/debian10
117
118 whil containers will have names like:
119
120 fr-crossbuild-debian10
121
0 build.*
1 configure.*
2 log.*
3 stamp-*
0 #
1 # Include crossbuild targets, to test building on lots of
2 # different OSes. Uses Docker.
3 #
4 ifeq ($(shell which docker 2> /dev/null),)
5 .PHONY: crossbuild crossbuild.help
6 crossbuild crossbuild.help :
7 @echo crossbuild requires Docker to be installed
8 else
9
10 #
11 # Short list of common builds
12 #
13 CB_COMMON:=centos7 debian10 ubuntu18
14
15 # Where the docker directories are
16 DT:=scripts/crossbuild/docker
17
18 # Where to put stamp files (subdirectory of where this makefile is)
19 DD:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))/build
20
21 # List of all the docker images (sorted for "crossbuild.info")
22 CB_IMAGES:=$(sort $(patsubst $(DT)/%,%,$(wildcard $(DT)/*)))
23
24 # Location of the .git dir (may be different for e.g. submodules)
25 GITDIR:=$(shell perl -MCwd -e 'print Cwd::abs_path shift' $$(git rev-parse --git-dir))
26
27 CB_CPREFIX:=fr-crossbuild-
28 CB_IPREFIX:=freeradius-build
29
30 #
31 # This Makefile is included in-line, and not via the "boilermake"
32 # wrapper. But it's still useful to use the same process for
33 # seeing commands that are run.
34 #
35 ifeq "${VERBOSE}" ""
36 Q=@
37 else
38 Q=
39 endif
40
41 #
42 # Enter here: This builds everything
43 #
44 .PHONY: crossbuild crossbuild.common
45 crossbuild: crossbuild.info $(foreach IMG,${CB_IMAGES},crossbuild.${IMG})
46 crossbuild.common: crossbuild.info $(foreach IMG,${CB_COMMON},crossbuild.${IMG})
47
48 #
49 # Dump out some useful information on what images we're going to test
50 #
51 .PHONY: crossbuild.info crossbuild.info_header crossbuild.help
52 crossbuild.info: crossbuild.info_header $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.status)
53 @echo Common images: $(CB_COMMON)
54
55 crossbuild.info_header:
56 @echo Images:
57
58 crossbuild.help: crossbuild.info
59 @echo ""
60 @echo "Make targets:"
61 @echo " crossbuild - build and test all images"
62 @echo " crossbuild.common - build and test common images"
63 @echo " crossbuild.info - list images"
64 @echo " crossbuild.down - stop all containers"
65 @echo " crossbuild.reset - remove cache of docker state"
66 @echo " crossbuild.clean - down and reset all targets"
67 @echo " crossbuild.wipe - destroy all crossbuild Docker images"
68 @echo ""
69 @echo "Per-image targets:"
70 @echo " crossbuild.IMAGE - build and test image <IMAGE>"
71 @echo " crossbuild.IMAGE.log - show latest build log"
72 @echo " crossbuild.IMAGE.up - start container"
73 @echo " crossbuild.IMAGE.down - stop container"
74 @echo " crossbuild.IMAGE.sh - shell in container"
75 @echo " crossbuild.IMAGE.refresh - push latest commits into container"
76 @echo " crossbuild.IMAGE.reset - remove cache of docker state"
77 @echo " crossbuild.IMAGE.clean - stop container and tidy up"
78 @echo " crossbuild.IMAGE.wipe - remove Docker image"
79
80 #
81 # Remove stamp files, so that we try and create images again
82 #
83 crossbuild.reset: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.reset)
84
85 #
86 # Stop all containers
87 #
88 crossbuild.down: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.down)
89
90 #
91 # Clean up: stop all containers, do a reset
92 #
93 crossbuild.clean: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.clean)
94
95 #
96 # Remove all images
97 #
98 crossbuild.wipe: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.wipe)
99
100 #
101 # Define rules for building a particular image
102 #
103 define CROSSBUILD_IMAGE_RULE
104 #
105 # Show status (based on stamp files)
106 #
107 .PHONY: crossbuild.${1}.status
108 crossbuild.${1}.status:
109 ${Q}echo -n "`echo \" ${1} \" | cut -c 1-20`"
110 ${Q}if [ -e "$(DD)/stamp-up.${1}" ]; then echo "running"; \
111 elif [ -e "$(DD)/stamp-image.${1}" ]; then echo "built"; \
112 else echo "-"; fi
113 #
114 # Build the docker image
115 #
116 $(DD)/stamp-image.${1}:
117 ${Q}echo "BUILD ${1} ($(CB_IPREFIX)/${1}) > $(DD)/build.${1}"
118 ${Q}docker build $(DT)/${1} -f $(DT)/${1}/Dockerfile -t $(CB_IPREFIX)/${1} >$(DD)/build.${1} 2>&1
119 ${Q}touch $(DD)/stamp-image.${1}
120
121 #
122 # Start up the docker container
123 #
124 .PHONY: $(DD)/docker.up.${1}
125 $(DD)/docker.up.${1}: $(DD)/stamp-image.${1}
126 ${Q}echo "START ${1} ($(CB_CPREFIX)${1})"
127 ${Q}docker container inspect $(CB_CPREFIX)${1} >/dev/null 2>&1 || \
128 docker run -d --rm \
129 --privileged --cap-add=ALL \
130 --mount=type=bind,source="$(GITDIR)",destination=/srv/src,ro \
131 --name $(CB_CPREFIX)${1} $(CB_IPREFIX)/${1} \
132 /bin/sh -c 'while true; do sleep 60; done' >/dev/null
133
134 $(DD)/stamp-up.${1}: $(DD)/docker.up.${1}
135 ${Q}touch $(DD)/stamp-up.${1}
136
137 .PHONY: crossbuild.${1}.up
138 crossbuild.${1}.up: $(DD)/stamp-up.${1}
139
140 #
141 # Run tests in the container
142 #
143 .PHONY: $(DD)/docker.refresh.${1}
144 $(DD)/docker.refresh.${1}: $(DD)/stamp-up.${1}
145 ${Q}echo "REFRESH ${1}"
146 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c 'rsync -a /srv/src/ /srv/local-src/'
147 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c 'git config -f /srv/local-src/config core.bare true'
148 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c 'git config -f /srv/local-src/config --unset core.worktree || true'
149 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c '[ -d /srv/build ] || git clone /srv/local-src /srv/build'
150 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c '(cd /srv/build && git pull --rebase)'
151 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c '[ -e /srv/build/config.log ] || echo CONFIGURE ${1}'
152 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c '[ -e /srv/build/config.log ] || (cd /srv/build && ./configure -C)' > $(DD)/configure.${1} 2>&1
153
154 .PHONY: $(DD)/docker.run.${1}
155 $(DD)/docker.run.${1}: $(DD)/docker.refresh.${1}
156 ${Q}echo "TEST ${1} > $(DD)/log.${1}"
157 ${Q}docker container exec $(CB_CPREFIX)${1} sh -c '(cd /srv/build && make && make test)' > $(DD)/log.${1} 2>&1 || echo FAIL ${1}
158
159 #
160 # Stop the docker container
161 #
162 .PHONY: crossbuild.${1}.down
163 crossbuild.${1}.down:
164 @echo STOP ${1}
165 ${Q}docker container kill $(CB_CPREFIX)${1} || true
166 @rm -f $(DD)/stamp-up.${1}
167
168 .PHONY: crossbuild.${1}.clean
169 crossbuild.${1}.clean: crossbuild.${1}.down crossbuild.${1}.reset
170
171 #
172 # Shell into container. cd to root first (will always succeed),
173 # then try to change to build dir, which might not exist, then
174 # run bash. (Default cwd is the wrong freeradius source in
175 # /usr/local, which would be confusing)
176 #
177 .PHONY: crossbuild.${1}.sh
178 crossbuild.${1}.sh: crossbuild.${1}.up
179 ${Q}docker exec -it $(CB_CPREFIX)${1} sh -c 'cd / ; cd /srv/build 2>/dev/null; bash' || true
180
181 #
182 # Show last build logs. Try and use the most sensible pager.
183 #
184 .PHONY: crossbuild.${1}.log
185 crossbuild.${1}.log:
186 @if which less >/dev/null; then \
187 less +G $(DD)/log.${1};\
188 elif which more >/dev/null; then \
189 more $(DD)/log.${1};\
190 else cat $(DD)/log.${1}; fi
191
192 #
193 # Tidy up stamp files. This means on next run we'll do
194 # everything. Required if e.g. system has been rebooted, so
195 # containers are stopped, but the stamp file still exists.
196 #
197 .PHONY: crossbuild.${1}.reset
198 crossbuild.${1}.reset:
199 ${Q}echo RESET ${1}
200 ${Q}rm -f $(DD)/stamp-up.${1}
201 ${Q}rm -f $(DD)/stamp-image.${1}
202
203 #
204 # Clean down images. Means on next run we'll rebuild the
205 # container (rather than just starting it).
206 #
207 .PHONY: crossbuild.${1}.wipe
208 crossbuild.${1}.wipe:
209 ${Q}echo CLEAN ${1}
210 ${Q}docker image rm $(CB_IPREFIX)/${1} >/dev/null 2>&1 || true
211 ${Q}rm -f $(DD)/stamp-image.${1}
212
213 #
214 # Refresh git repository within the docker image
215 #
216 .PHONY: crossbuild.${1}.refresh
217 crossbuild.${1}.refresh: $(DD)/docker.refresh.${1}
218
219 #
220 # Run the build test
221 #
222 .PHONY: crossbuild.${1}
223 crossbuild.${1}: $(DD)/docker.run.${1}
224
225 endef
226
227 #
228 # Add all the image building rules
229 #
230 $(foreach IMAGE,$(CB_IMAGES),\
231 $(eval $(call CROSSBUILD_IMAGE_RULE,$(IMAGE))))
232
233
234 # if docker is defined
235 endif
0 FROM centos:centos7
1
2 #
3 # Install devtools like make and git and the EPEL
4 # repository for freetds and hiredis
5 #
6 RUN yum update -y
7 RUN yum install -y rpmdevtools openssl epel-release git yum-utils rsync
8
9 #
10 # Install GCC that has the requisite support for C11 keywords and atomics
11 #
12 RUN yum install -y centos-release-scl
13 RUN yum install -y devtoolset-8-gcc devtoolset-8-gcc-c++
14 ENV CC=/opt/rh/devtoolset-8/root/usr/bin/gcc
15
16 #
17 # Remove the CentOS-SCLo repo which is apparently not valid?
18 # See: https://bugs.centos.org/view.php?id=14773
19 #
20 RUN rm /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
21 RUN rm /etc/yum.repos.d/CentOS-SCLo-scl.repo
22
23 #
24 # Documentation build dependecies
25 #
26
27 # - doxygen & JSON.pm
28 RUN yum install -y doxygen graphviz perl-JSON
29 # - antora (npm needed)
30 RUN curl -sL https://rpm.nodesource.com/setup_8.x | bash -
31 RUN yum install -y nodejs
32 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
33 # - pandoc
34 RUN curl -o - -L $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*tar.gz" | cut -d '"' -f 4) | tar xzvf - -C /tmp/
35 RUN mv /tmp/pandoc-*/bin/* /usr/local/bin
36 # - asciidoctor
37 RUN yum install -y rubygems-devel
38 RUN gem install asciidoctor
39
40 #
41 # Setup a src dir in /usr/local
42 #
43 RUN mkdir -p /usr/local/src/repositories
44 WORKDIR /usr/local/src/repositories
45
46 #
47 # Use LTB's openldap packages intead of the distribution version to avoid linking against NSS
48 #
49 RUN echo $'[ltb-project]\n\
50 name=LTB project packages\n\
51 baseurl=https://ltb-project.org/rpm/$releasever/$basearch\n\
52 enabled=1\n\
53 gpgcheck=1\n\
54 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-LTB-project'\
55 > /etc/yum.repos.d/ltb-project.repo
56 RUN rpm --import https://ltb-project.org/lib/RPM-GPG-KEY-LTB-project
57
58 #
59 # Shallow clone the FreeRADIUS source
60 #
61 WORKDIR /usr/local/src/repositories
62 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
63 RUN git clone --depth 1 --no-single-branch ${source}
64
65 #
66 # Install build dependencies for all branches from v3 onwards
67 #
68 WORKDIR freeradius-server
69 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^(v[3-9]*\.[0-9x]*\.x|master)$");\
70 do \
71 git checkout $i; \
72 [ -e redhat/freeradius.spec ] && yum-builddep -y redhat/freeradius.spec; \
73 done
74
75 #
76 # Which is required by fixture setup utilities
77 #
78 RUN yum install -y which
79
80 #
81 # Explicitly install libnl3-devel which is required for the EAP tests
82 #
83 RUN yum install -y libnl3-devel
84
85 #
86 # Create the RPM build tree
87 #
88 ENV BUILDDIR=/root/rpmbuild
89 RUN rpmdev-setuptree
0 FROM debian:buster
1
2 ARG gccver=8
3 ARG clangver=8
4 ARG osname=buster
5
6 ARG DEBIAN_FRONTEND=noninteractive
7
8 #
9 # Install add-apt-repository
10 #
11 RUN apt-get update && \
12 apt-get install -y software-properties-common gnupg2 procps && \
13 apt-get clean && \
14 rm -r /var/lib/apt/lists/*
15
16 # For clang
17 RUN add-apt-repository -y "deb http://apt.llvm.org/${osname}/ llvm-toolchain-${osname}-${clangver} main" && \
18 apt-key adv --fetch-keys http://apt.llvm.org/llvm-snapshot.gpg.key
19
20 RUN apt-get update && \
21 # Development utilities
22 apt-get install -y devscripts equivs git quilt rsync && \
23 # Compilers
24 apt-get install -y g++-${gccver} llvm-${clangver} clang-${clangver} lldb-${clangver} && \
25 # eapol_test dependencies
26 apt-get install -y libnl-3-dev libnl-genl-3-dev
27
28 #
29 # Documentation build dependecies
30 #
31
32 # - doxygen & JSON.pm
33 RUN apt-get install -y doxygen graphviz libjson-perl
34 # - antora (npm needed)
35 RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
36 RUN apt-get install -y nodejs
37 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
38 # - pandoc
39 WORKDIR /tmp
40 RUN curl -OL $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4)
41 RUN apt-get install -y ./pandoc-*.deb
42 # - asciidoctor
43 RUN apt-get install -y ruby-dev
44 RUN gem install asciidoctor
45
46 # set default things
47 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${gccver} 50 \
48 --slave /usr/bin/g++ g++ /usr/bin/g++-${gccver} && \
49 update-alternatives --config gcc
50
51 RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clangver} 60 && \
52 update-alternatives --config clang
53
54 RUN update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${clangver} 60 && \
55 update-alternatives --config lldb
56
57
58 #
59 # Setup a src dir in /usr/local
60 #
61 RUN mkdir -p /usr/local/src/repositories
62 WORKDIR /usr/local/src/repositories
63
64
65 #
66 # Shallow clone the FreeRADIUS source
67 #
68 WORKDIR /usr/local/src/repositories
69 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
70 RUN git clone --depth 1 --no-single-branch ${source}
71
72
73 #
74 # Install build dependencies for all v3 branches
75 #
76 WORKDIR freeradius-server
77 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^v3\..*\.x");\
78 do \
79 git checkout $i; \
80 if [ -e ./debian/control.in ] ; then \
81 debian/rules debian/control ; \
82 fi ; \
83 echo Installing dependencies for $i ; \
84 mk-build-deps debian/control ; \
85 apt-get --no-install-recommends -y -V install ./freeradius-build-deps*.deb || true ; \
86 apt-get -y -f remove freeradius-build-deps libiodbc2-dev || true ; \
87 rm ./freeradius-build-deps*.deb ; \
88 done
0 FROM debian:jessie
1
2 ARG gccver=4.9
3 ARG clangver=5.0
4 ARG osname=jessie
5
6 ARG DEBIAN_FRONTEND=noninteractive
7
8 #
9 # Install add-apt-repository
10 #
11 RUN apt-get update && \
12 apt-get install -y software-properties-common && \
13 apt-get clean && \
14 rm -r /var/lib/apt/lists/*
15
16 # Requires GCC-4.9 as it has support for C11 keywords and atomics
17
18 # For clang
19 RUN add-apt-repository -y "deb http://apt.llvm.org/${osname}/ llvm-toolchain-${osname}-${clangver} main" && \
20 apt-key adv --fetch-keys http://apt.llvm.org/llvm-snapshot.gpg.key
21
22 RUN apt-get update && \
23 # Development utilities
24 apt-get install -y devscripts equivs git quilt rsync && \
25 # Compilers
26 apt-get install -y g++-${gccver} llvm-${clangver} clang-${clangver} lldb-${clangver} && \
27 # eapol_test dependencies
28 apt-get install -y libnl-3-dev libnl-genl-3-dev
29
30 #
31 # Documentation build dependecies
32 #
33
34 # - doxygen & JSON.pm
35 RUN apt-get install -y doxygen graphviz libjson-perl
36 # - antora (npm needed)
37 RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
38 RUN apt-get install -y nodejs
39 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
40 # - pandoc
41 WORKDIR /tmp
42 RUN curl -OL $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4)
43 RUN dpkg -i ./pandoc-*.deb
44 RUN apt-get install -fy
45 # - asciidoctor
46 RUN apt-get install -y ruby
47 RUN gem install asciidoctor
48
49 # set default things
50 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${gccver} 50 \
51 --slave /usr/bin/g++ g++ /usr/bin/g++-${gccver} && \
52 update-alternatives --config gcc
53
54 RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clangver} 60 && \
55 update-alternatives --config clang
56
57 RUN update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${clangver} 60 && \
58 update-alternatives --config lldb
59
60
61 #
62 # Setup a src dir in /usr/local
63 #
64 RUN mkdir -p /usr/local/src/repositories
65 WORKDIR /usr/local/src/repositories
66
67 #
68 # Shallow clone the FreeRADIUS source
69 #
70 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
71 RUN git clone --depth 1 --no-single-branch ${source}
72
73 #
74 # Install build dependencies for all branches from v3 onwards
75 #
76 WORKDIR freeradius-server
77 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^(v[3-9]*\.[0-9x]*\.x|master)$");\
78 do \
79 git checkout $i; \
80 if [ -e ./debian/control.in ] ; then debian/rules debian/control ; fi ; echo 'y' | mk-build-deps -irt'apt-get -yV' debian/control ; \
81 done
0 FROM debian:stretch
1
2 ARG gccver=6
3 ARG clangver=5.0
4 ARG osname=stretch
5
6 ARG DEBIAN_FRONTEND=noninteractive
7
8 #
9 # Install add-apt-repository
10 #
11 RUN apt-get update && \
12 apt-get install -y software-properties-common gnupg2 && \
13 apt-get clean && \
14 rm -r /var/lib/apt/lists/*
15
16 # Stretch uses GCC-6.3 by default, so it doesn't need to be updated to get C11 functionality.
17
18 # For clang
19 RUN add-apt-repository -y "deb http://apt.llvm.org/${osname}/ llvm-toolchain-${osname}-${clangver} main" && \
20 apt-key adv --fetch-keys http://apt.llvm.org/llvm-snapshot.gpg.key
21
22 RUN apt-get update && \
23 # Development utilities
24 apt-get install -y devscripts equivs git quilt rsync && \
25 # Compilers
26 apt-get install -y g++-${gccver} llvm-${clangver} clang-${clangver} lldb-${clangver} && \
27 # eapol_test dependencies
28 apt-get install -y libnl-3-dev libnl-genl-3-dev
29
30 #
31 # Documentation build dependecies
32 #
33
34 # - doxygen & JSON.pm
35 RUN apt-get install -y doxygen graphviz libjson-perl
36 # - antora (npm needed)
37 RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
38 RUN apt-get install -y npm
39 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
40 # - pandoc
41 WORKDIR /tmp
42 RUN curl -OL $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4)
43 RUN apt-get install -y ./pandoc-*.deb
44 # - asciidoctor
45 RUN apt-get install -y ruby-dev
46 RUN gem install asciidoctor
47
48 # set default things
49 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${gccver} 50 \
50 --slave /usr/bin/g++ g++ /usr/bin/g++-${gccver} && \
51 update-alternatives --config gcc
52
53 RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clangver} 60 && \
54 update-alternatives --config clang
55
56 RUN update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${clangver} 60 && \
57 update-alternatives --config lldb
58
59
60 #
61 # Setup a src dir in /usr/local
62 #
63 RUN mkdir -p /usr/local/src/repositories
64 WORKDIR /usr/local/src/repositories
65
66
67 #
68 # Shallow clone the FreeRADIUS source
69 #
70 WORKDIR /usr/local/src/repositories
71 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
72 RUN git clone --depth 1 --no-single-branch ${source}
73
74 #
75 # Install build dependencies for all branches from v3 onwards
76 #
77 WORKDIR freeradius-server
78 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^(v[3-9]*\.[0-9x]*\.x|master)$");\
79 do \
80 git checkout $i; \
81 if [ -e ./debian/control.in ] ; then debian/rules debian/control ; fi ; echo 'y' | mk-build-deps -irt'apt-get -yV' debian/control ; \
82 done
0
1 Build source image
2
3 docker build . -f Dockerfile.source -t freeradius:debian9-source
4
5 Then either build and run jenkins image
6
7 docker build . -f Dockerfile.jenkins -t freeradius:debian9-jenkins
8 docker run -d -p 2222:22 freeradius:debian9-jenkins
9
10 or build and run the server
11
12 docker build . -t freeradius:debian9
13 docker run -d -p 1812:1812/udp -p 1813:1813/udp freeradius:debian9
14
0 FROM ubuntu:16.04
1
2 ARG gccver=4.9
3 ARG clangver=5.0
4 ARG osname=xenial
5
6 ARG DEBIAN_FRONTEND=noninteractive
7
8 #
9 # Install add-apt-repository
10 #
11 RUN apt-get update && \
12 apt-get install -y software-properties-common python-software-properties && \
13 apt-get clean && \
14 rm -r /var/lib/apt/lists/*
15
16 # Requires GCC-4.9 as it has support for C11 keywords and atomics
17
18 # For clang
19 RUN add-apt-repository -y "deb http://apt.llvm.org/${osname}/ llvm-toolchain-${osname}-${clangver} main" && \
20 apt-key adv --fetch-keys http://apt.llvm.org/llvm-snapshot.gpg.key && \
21 # For GCC
22 add-apt-repository -y ppa:ubuntu-toolchain-r/test
23
24 RUN apt-get update && \
25 # Development utilities
26 apt-get install -y devscripts equivs git quilt rsync && \
27 # Compilers
28 apt-get install -y g++-${gccver} llvm-${clangver} clang-${clangver} lldb-${clangver} && \
29 # eapol_test dependencies
30 apt-get install -y libnl-3-dev libnl-genl-3-dev
31
32 #
33 # Documentation build dependecies
34 #
35
36 # - doxygen & JSON.pm
37 RUN apt-get install -y doxygen graphviz libjson-perl
38 # - antora (npm needed)
39 RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
40 RUN apt-get install -y nodejs
41 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
42 # - pandoc
43 WORKDIR /tmp
44 RUN curl -OL $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4)
45 RUN apt-get install -y ./pandoc-*.deb
46 # - asciidoctor
47 RUN apt-get install -y ruby-dev
48 RUN gem install asciidoctor
49
50 # set default things
51 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${gccver} 50 \
52 --slave /usr/bin/g++ g++ /usr/bin/g++-${gccver} && \
53 update-alternatives --config gcc
54
55 RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clangver} 60 && \
56 update-alternatives --config clang
57
58 RUN update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${clangver} 60 && \
59 update-alternatives --config lldb
60
61
62 #
63 # Setup a src dir in /usr/local
64 #
65 RUN mkdir -p /usr/local/src/repositories
66 WORKDIR /usr/local/src/repositories
67
68
69 #
70 # Shallow clone the FreeRADIUS source
71 #
72 WORKDIR /usr/local/src/repositories
73 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
74 RUN git clone --depth 1 --no-single-branch ${source}
75
76 #
77 # Install build dependencies for all branches from v3 onwards
78 #
79 WORKDIR freeradius-server
80 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^(v[3-9]*\.[0-9x]*\.x|master)$");\
81 do \
82 git checkout $i; \
83 if [ -e ./debian/control.in ] ; then debian/rules debian/control ; fi ; echo 'y' | mk-build-deps -irt'apt-get -yV' debian/control ; \
84 done
0 FROM ubuntu:18.04
1
2 ARG gccver=4.9
3 ARG clangver=5.0
4 ARG osname=bionic
5
6 ARG DEBIAN_FRONTEND=noninteractive
7
8 #
9 # Install add-apt-repository
10 #
11 RUN apt-get update && \
12 apt-get install -y software-properties-common && \
13 apt-get clean && \
14 rm -r /var/lib/apt/lists/*
15
16 RUN apt-get update && \
17 # Development utilities
18 apt-get install -y devscripts equivs git quilt rsync && \
19 # Compilers
20 apt-get install -y g++ llvm clang lldb && \
21 # eapol_test dependencies
22 apt-get install -y libnl-3-dev libnl-genl-3-dev
23
24 #
25 # Documentation build dependecies
26 #
27
28 # - doxygen & JSON.pm
29 RUN apt-get install -y doxygen graphviz libjson-perl
30 # - antora (npm needed)
31 RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
32 RUN apt-get install -y nodejs
33 RUN npm i -g @antora/cli@2.1 @antora/site-generator-default@2.1
34 # - pandoc
35 WORKDIR /tmp
36 RUN curl -OL $(curl -s https://api.github.com/repos/jgm/pandoc/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4)
37 RUN apt-get install -y ./pandoc-*.deb
38 # - asciidoctor
39 RUN apt-get install -y ruby-dev
40 RUN gem install asciidoctor
41
42 #
43 # Setup a src dir in /usr/local
44 #
45 RUN mkdir -p /usr/local/src/repositories
46 WORKDIR /usr/local/src/repositories
47
48
49 #
50 # Shallow clone the FreeRADIUS source
51 #
52 WORKDIR /usr/local/src/repositories
53 ARG source=https://github.com/FreeRADIUS/freeradius-server.git
54 RUN git clone --depth 1 --no-single-branch ${source}
55
56 #
57 # Install build dependencies for all branches from v3 onwards
58 #
59 WORKDIR freeradius-server
60 RUN for i in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin 2>/dev/null | sed -e 's#origin/##' | egrep "^(v[3-9]*\.[0-9x]*\.x|master)$");\
61 do \
62 git checkout $i; \
63 if [ -e ./debian/control.in ] ; then debian/rules debian/control ; fi ; echo 'y' | mk-build-deps -irt'apt-get -yV' debian/control ; \
64 done
0 #
1 # Docker-related targets
2 #
3 # Intended for internal use to publish Docker images to docker hub. Likely need to run
4 # "docker login" before any push commands.
5 #
6 # Examples:
7 #
8 # Publish to Dockerhub "freeradius-server"
9 # make DOCKER_VERSION=3.0.20 DOCKER_BUILD_ARGS="--no-cache" docker-publish
10 #
11 # Build and push "freeradius-dev" image to Dockerhub (e.g. CI on every commit):
12 # make DOCKER_VERSION=latest DOCKER_COMMIT=v3.0.x DOCKER_TAG="freeradius-dev" DOCKER_BUILD_ARGS="--no-cache" docker-push
13 #
14 # Push to local repository:
15 # make DOCKER_VERSION=3.0.20 DOCKER_TAG="our-freeradius-build" DOCKER_REGISTRY="docker.somewhere.example" docker-publish
16 #
17 # See what is going to happen:
18 # make Q=": " ...
19 #
20 #
21 # Variables:
22 #
23 # Which version to tag as, e.g. "3.0.20". If this is not an actual release
24 # version, DOCKER_COMMIT _must_ also be set.
25 DOCKER_VERSION := $(RADIUSD_VERSION_STRING)
26 #
27 # Commit hash/tag/branch to build, will be taken from VERSION above if not overridden, e.g. "release_3_0_20"
28 DOCKER_COMMIT := release_$(shell echo $(DOCKER_VERSION) | tr .- __)
29 #
30 # Build args, most likely "--no-cache"
31 DOCKER_BUILD_ARGS :=
32 #
33 # Tag name, likely "freeradius-server" for releases, or "freeradius-dev" for nightlies.
34 DOCKER_TAG := freeradius-server
35 #
36 # Repository name
37 DOCKER_REPO := freeradius
38 #
39 # Registry to push to
40 DOCKER_REGISTRY :=
41 #
42
43 ifneq "$(DOCKER_REPO)" ""
44 override DOCKER_REPO := $(DOCKER_REPO)/
45 endif
46
47 ifneq "$(DOCKER_REGISTRY)" ""
48 override DOCKER_REGISTRY := $(DOCKER_REGISTRY)/
49 endif
50
51
52 .PHONY: docker
53 docker:
54 @echo Building $(DOCKER_COMMIT)
55 $(Q)docker build $(DOCKER_BUILD_ARGS) scripts/docker/ubuntu18 --build-arg=release=$(DOCKER_COMMIT) -t $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION)
56 $(Q)docker build $(DOCKER_BUILD_ARGS) scripts/docker/alpine --build-arg=release=$(DOCKER_COMMIT) -t $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION)-alpine
57
58 .PHONY: docker-push
59 docker-push: docker
60 $(Q)docker push $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION)
61 $(Q)docker push $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION)-alpine
62
63 .PHONY: docker-tag-latest
64 docker-tag-latest: docker
65 $(Q)docker tag $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION) $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):latest
66 $(Q)docker tag $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):$(DOCKER_VERSION)-alpine $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):latest-alpine
67
68 .PHONY: docker-push-latest
69 docker-push-latest: docker-push docker-tag-latest
70 $(Q)docker push $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):latest
71 $(Q)docker push $(DOCKER_REGISTRY)$(DOCKER_REPO)$(DOCKER_TAG):latest-alpine
72
73 .PHONY: docker-publish
74 docker-publish: docker-push-latest
0 def platforms = ["ubuntu14", "ubuntu16", "ubuntu18", "centos7", "centos8", "debian8", "debian9", "debian10"]
0 def platforms = ["ubuntu14", "ubuntu16", "ubuntu18", "centos6", "centos7", "centos8", "debian8", "debian9", "debian10"]
11 def server_dir = "freeradius-server"
22 def artifacts = 'build-number, **/*.changes, **/*.buildinfo, **/*.deb, **/*.rpm'
33
6363 */
6464
6565 node {
66 cleanWs(patterns: [[pattern: '**/*.deb , **/*.changes , **/*.buildinfo , **/*.rpm', type: 'INCLUDE']])
66 def server_dir = "freeradius-server"
6767
68 def server_dir = "freeradius-server"
68 sh 'find . -type f \\( -name "*.deb" -o -name "*.changes" -o -name "*.buildinfo" -o -name "*.rpm" \\) -delete'
6969
7070 checkout([
7171 $class: 'GitSCM',
3636 #
3737 # Install build dependencies
3838 #
39 # RUN [ -e redhat/freeradius.spec ] && yum-builddep -y redhat/freeradius.spec
39 RUN [ -e redhat/freeradius.spec ] && yum-builddep -y redhat/freeradius.spec
4040
176176 #endif
177177
178178 #ifndef CC
179 #define CC "gcc"
179 #define CC "clang"
180180 #endif
181181
182182 #ifndef CXX
184184 #endif
185185
186186 #ifndef LINK_C
187 #define LINK_C "gcc"
187 #define LINK_C "clang"
188188 #endif
189189
190190 #ifndef LINK_CXX
412412
413413 out = malloc(size);
414414 if (!out) {
415 ERROR("Failed allocating %zu bytes, OOM", size);
415 ERROR("Failed allocating %zu bytes, OOM\n", size);
416416 exit(1);
417417 }
418418
10521052
10531053 newext = strrchr(newarg, '.');
10541054 if (!newext) {
1055 ERROR("Library path does not have an extension");
1055 ERROR("Library path does not have an extension\n");
10561056 free(newarg);
10571057
10581058 return NULL;
11441144 strcpy(newarg + newpathlen, arg + pathlen);
11451145 ext = strrchr(newarg, '.');
11461146 if (!ext) {
1147 ERROR("Error: Library path does not have an extension");
1147 ERROR("Error: Library path does not have an extension\n");
11481148 free(newarg);
11491149
11501150 return NULL;
22222222 {
22232223 char *l, libpath[PATH_MAX];
22242224
2225 if (!cmd->arglist->num) {
2226 ERROR("No command to execute.\n");
2227 rv = 1;
2228
2229 goto finish;
2230 }
2231
22252232 if (strlen(cmd->arglist->vals[0]) >= PATH_MAX) {
2226 ERROR("Libpath too long no buffer space");
2233 ERROR("Libpath too long no buffer space\n");
22272234 rv = 1;
22282235
22292236 goto finish;
22732280 }
22742281
22752282 if ((strlen(dirname) + 1 + sizeof(entry->d_name)) >= sizeof(fullname)) {
2276 ERROR("Dirname too long, out of buffer space");
2283 ERROR("Dirname too long, out of buffer space\n");
22772284
22782285 (void) closedir(dir);
22792286 return;
317317 args+=" -t \"$timeout\""
318318 args+=" -r \"$retries\""
319319 args+=" -p \"$parallel\""
320 args+=" -D \"$DICTPATH\""
320321 args+=" \"$target\""
321322 args+=" auto"
322323 args+=" \"$secret\""
323324
324 DEBUG "Executing: radclient $args"
325 eval radclient $args; ret=$?
325 DEBUG "Executing: $RADCLIENT $args"
326 eval $RADCLIENT $args; ret=$?
326327 INFO "(Parallelised tests)"
327328 INFO ""
328329
346347 args+=" -t \"$timeout\""
347348 args+=" -r \"$retries\""
348349 args+=" -p 1"
350 args+=" -D \"$DICTPATH\""
349351 args+=" \"$target\""
350352 args+=" auto"
351353 args+=" \"$secret\""
352354
353 DEBUG "Executing: radclient $args"
354 eval radclient $args; ret=$?
355 DEBUG "Executing: $RADCLIENT $args"
356 eval $RADCLIENT $args; ret=$?
355357 INFO "(Serialised tests)"
356358
357359 if [ $ret -ne 0 ]; then
251251 $INCLUDE dictionary.motorola
252252 $INCLUDE dictionary.motorola.wimax
253253 $INCLUDE dictionary.navini
254 $INCLUDE dictionary.net
254255 $INCLUDE dictionary.netscreen
255256 $INCLUDE dictionary.networkphysics
256257 $INCLUDE dictionary.nexans
263264 $INCLUDE dictionary.patton
264265 $INCLUDE dictionary.perle
265266 $INCLUDE dictionary.pfsense
267 $INCLUDE dictionary.pica8
266268 $INCLUDE dictionary.propel
267269 $INCLUDE dictionary.prosoft
268270 $INCLUDE dictionary.proxim
269271 $INCLUDE dictionary.purewave
270272 $INCLUDE dictionary.quiconnect
271273 $INCLUDE dictionary.quintum
274 $INCLUDE dictionary.rcntec
272275 $INCLUDE dictionary.redcreek
273276 $INCLUDE dictionary.riverbed
274277 $INCLUDE dictionary.riverstone
301304 $INCLUDE dictionary.usr
302305 $INCLUDE dictionary.utstarcom
303306 $INCLUDE dictionary.valemount
307 $INCLUDE dictionary.vasexperts
304308 $INCLUDE dictionary.verizon
305309 $INCLUDE dictionary.versanet
306310 $INCLUDE dictionary.walabi
11 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
22 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
33 #
4 # Aerohive
4 # Aerohive (now Extreme Networks, Inc.)
55 #
66 # $Id$
77 #
88 VENDOR Aerohive 26928
99
1010 BEGIN-VENDOR Aerohive
11 #BEGIN-VENDOR Extreme
1112
13 # Source: http://docs.aerohive.com/330000/docs/help/english/ng/Content/reference/docs/radius-dictionary.htm
14 # Last-updated-date 25-October-2017
15 # Extreme supports a small set of Vendor-Specific-Attributes for
16 # administrative access to HiveManager Classic, and a different set
17 # of Vendor-Specific-Attributes for HiveOS. Both are documented in
18 # this file.
19
20 # Most customer will wish to import this file in it’s entirety into
21 # their local RADIUS data store.
22
23 # Beginning of HiveManager Classic VSAs
1224 # The following ATTRIBUTE and VALUE definitions are required.
1325 ATTRIBUTE AH-HM-Admin-Group-Id 1 integer
1426 VALUE AH-HM-Admin-Group-Id Read-Only-Admin 0
1830 # The following is an example of an admin group that you can define.
1931 #VALUE AH-HM-Admin-Group-Id Admin-Group100 100
2032
33 # End of HiveManager Classic VSAs
34 # Beginning of HiveOS VSAs
35
36 ATTRIBUTE Extreme-User-Vlan 1 integer
37 ATTRIBUTE Extreme-Libsip-Patron-Info 3 octets encrypt=2
38 ATTRIBUTE Extreme-Libsip-Action 4 integer
39 ATTRIBUTE Extreme-Libsip-Additional-Message 5 octets
40 ATTRIBUTE Extreme-User-Profile-Attribute 6 integer
41 ATTRIBUTE Extreme-Data-Usage-Limit 7 octets
42 ATTRIBUTE Extreme-AVPair 8 string
43 ATTRIBUTE Extreme-Radius-Code 9 integer
44 ATTRIBUTE Extreme-PPSK-Request 201 octets
45 ATTRIBUTE Extreme-PPSK-PMK 202 octets
46 ATTRIBUTE Extreme-IDM-Message 203 integer
47 ATTRIBUTE Extreme-NT-Identity 204 integer
48 ATTRIBUTE Extreme-User-Language 205 string
49 ATTRIBUTE Extreme-Time-Zone-Offset 207 integer
50 ATTRIBUTE Extreme-Daylight-Saving-Offset 208 integer
51 ATTRIBUTE Extreme-Client-Monitor-Session 209 octets
52 ATTRIBUTE Extreme-Client-Monitor-Problem 210 integer
53 ATTRIBUTE Extreme-IDM-Redirect-URL 211 string
54 ATTRIBUTE Extreme-MGT-MAC-Address 212 string
55 ATTRIBUTE Extreme-Auth-Source 213 integer
56
57 #
58 # Integer Translations
59 #
60
61 # Extreme-Libsip-Action Values
62 VALUE Extreme-Libsip-Action Permit 0
63 VALUE Extreme-Libsip-Action Restricted 1
64 VALUE Extreme-Libsip-Action Deny 2
65
66 # Extreme-Radius-Code Values
67 VALUE Extreme-Radius-Code Disconnect-Request 1
68 VALUE Extreme-Radius-Code COA-Request 2
69
70 # Extreme-Auth-Source
71 VALUE Extreme-Auth-Source Service 1
72 VALUE Extreme-Auth-Source Non-Service 2
73
2174 END-VENDOR Aerohive
00 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
1 # Copyright (C) 2020 The FreeRADIUS Server project and contributors
22 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 #
3 # Version $Id$
44 ##############################################################################
55 #
66 # Arista VSAs
7 # https://eos.arista.com/common-aaa-requirements/
78 #
89 ##############################################################################
910
1415 ATTRIBUTE Arista-User-Priv-Level 2 integer
1516 ATTRIBUTE Arista-User-Role 3 string
1617 ATTRIBUTE Arista-CVP-Role 4 string
18 ATTRIBUTE Arista-Command 5 string
19 ATTRIBUTE Arista-WebAuth 6 integer
20 ATTRIBUTE Arista-BlockMac 7 string
21 ATTRIBUTE Arista-UnblockMac 8 string
22 ATTRIBUTE Arista-PortFlap 9 integer
23
24 VALUE Arista-WebAuth start 0
25 VALUE Arista-WebAuth complete 1
1726
1827 END-VENDOR Arista
00 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
1 # Copyright (C) 2020 The FreeRADIUS Server project and contributors
22 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 # Version $Id$
34 #
45 # Version: $Id$
56 #
4142 ATTRIBUTE Aruba-WorkSpace-App-Name 31 string
4243 ATTRIBUTE Aruba-Mdps-Provisioning-Settings 32 string
4344 ATTRIBUTE Aruba-Mdps-Device-Profile 33 string
44
4545 ATTRIBUTE Aruba-AP-IP-Address 34 ipaddr
46
4746 ATTRIBUTE Aruba-AirGroup-Shared-Group 35 string
4847 ATTRIBUTE Aruba-User-Group 36 string
4948 ATTRIBUTE Aruba-Network-SSO-Token 37 string
5049 ATTRIBUTE Aruba-AirGroup-Version 38 integer
51
50 ATTRIBUTE Aruba-Auth-SurvMethod 39 integer
5251 ATTRIBUTE Aruba-Port-Bounce-Host 40 integer
5352
5453 ATTRIBUTE Aruba-Calea-Server-Ip 41 ipaddr
55
5654 ATTRIBUTE Aruba-Admin-Path 42 string
5755 ATTRIBUTE Aruba-Captive-Portal-URL 43 string
5856 ATTRIBUTE Aruba-MPSK-Passphrase 44 octets encrypt=2
5957 ATTRIBUTE Aruba-ACL-Server-Query-Info 45 string
6058 ATTRIBUTE Aruba-Command-String 46 string
59 ATTRIBUTE Aruba-Network-Profile 47 string
60 ATTRIBUTE Aruba-Admin-Device-Group 48 string
61 ATTRIBUTE Aruba-PoE-Priority 49 integer
62 ATTRIBUTE Aruba-Port-Auth-Mode 50 integer
63
64 ATTRIBUTE Aruba-NAS-Filter-Rule 51 string
65 ATTRIBUTE Aruba-QoS-Trust-Mode 52 integer
66 ATTRIBUTE Aruba-UBT-Gateway-Role 53 string
67 ATTRIBUTE Aruba-Gateway-Zone 54 string
6168
6269 VALUE Aruba-AirGroup-Device-Type Personal-Device 1
6370 VALUE Aruba-AirGroup-Device-Type Shared-Device 2
6673 VALUE Aruba-AirGroup-Version AirGroup-v1 1
6774 VALUE Aruba-AirGroup-Version AirGroup-v2 2
6875
76 VALUE Aruba-PoE-Priority Critical 0
77 VALUE Aruba-PoE-Priority High 1
78 VALUE Aruba-PoE-Priority Low 2
79
80 VALUE Aruba-Port-Auth-Mode Infrastructure-Mode 1
81 VALUE Aruba-Port-Auth-Mode Client-Mode 2
82
83 VALUE Aruba-QoS-Trust-Mode DSCP 0
84 VALUE Aruba-QoS-Trust-Mode QoS 1
85 VALUE Aruba-QoS-Trust-Mode None 2
86
6987 END-VENDOR Aruba
00 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
1 # Copyright (C) 2020 The FreeRADIUS Server project and contributors
22 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 # Version $Id$
34 #
45 # Juniper's (was Unisphere's) broadband RAS
56 # From Terje Krogdahl <tekr@nextra.com>
227228 ATTRIBUTE ERX-Client-Profile-Name 174 string
228229 ATTRIBUTE ERX-Redirect-GW-Address 175 ipaddr
229230 ATTRIBUTE ERX-APN-Name 176 string
231 ATTRIBUTE ERX-Cos-Shaping-Rate 177 string
230232
231233 ATTRIBUTE ERX-Service-Volume-Gigawords 179 integer
232234 ATTRIBUTE ERX-Update-Service 180 string
258260 ATTRIBUTE ERX-DHCPv6-Header 209 octets
259261 ATTRIBUTE ERX-Acct-Request-Reason 210 integer
260262
263 ATTRIBUTE ERX-Inner-Tag-Protocol-Id 211 octets
264 ATTRIBUTE ERX-Routing-Services 212 integer
265 ATTRIBUTE ERX-Interface-Set-Targeting-Weight 213 integer
266 ATTRIBUTE ERX-Interface-Targeting-Weight 214 integer
267 ATTRIBUTE ERX-Hybrid-Access-DSL-Downstream-Speed 216 integer
268 ATTRIBUTE ERX-Hybrid-Access-LTE-Downstream-Speed 217 integer
269
270 ATTRIBUTE ERX-PON-Access-Type 219 integer
271 ATTRIBUTE ERX-ONT-ONU-Average-Data-Rate-Downstream 220 integer
272 ATTRIBUTE ERX-ONT-ONU-Peak-Data-Rate-Downstream 221 integer
273 ATTRIBUTE ERX-ONT-ONU-Maximum-Data-Rate-Upstream 222 integer
274 ATTRIBUTE ERX-ONT-ONU-Assured-Data-Rate-Upstream 223 integer
275 ATTRIBUTE ERX-PON-Tree-Maximum-Data-Rate-Upstream 224 integer
276 ATTRIBUTE ERX-PON-Tree-Maximum-Data-Rate-Downstream 225 integer
277
278 ATTRIBUTE ERX-Expected-Throughput-Upstream 226 integer
279 ATTRIBUTE ERX-Expected-Throughput-Downstream 227 integer
280 ATTRIBUTE ERX-Attainable-Expected-Throughput-Upstream 228 integer
281 ATTRIBUTE ERX-Attainable-Expected-Throughput-Downstream 229 integer
282 ATTRIBUTE ERX-Gamma-Data-Rate-Upstream 230 integer
283 ATTRIBUTE ERX-Gamma-Data-Rate-Downstream 231 integer
284 ATTRIBUTE ERX-Attainable-Gamma-Data-Rate-Upstream 232 integer
285 ATTRIBUTE ERX-Attainable-Gamma-Data-Rate-Downstream 233 integer
286
261287 #
262288 # Values Attribute Name Number
263289 #
392418 VALUE ERX-Acct-Request-Reason Address-Assignment-Change 512
393419 VALUE ERX-Acct-Request-Reason CoA-Complete 1024
394420
421 VALUE ERX-Routing-Services disabled 0
422 VALUE ERX-Routing-Services enabled 1
423
424 VALUE ERX-PON-Access-Type Other 0
425 VALUE ERX-PON-Access-Type GPON 1
426 VALUE ERX-PON-Access-Type XG-PON1 2
427 VALUE ERX-PON-Access-Type TWDM-PON 3
428 VALUE ERX-PON-Access-Type XGS-PON 4
429 VALUE ERX-PON-Access-Type WDM-PON 5
430 VALUE ERX-PON-Access-Type UNKNOWN 7
431
395432 END-VENDOR ERX
44 ##############################################################################
55 #
66 # Fortinet's VSA's
7 # As posted to the list by Richie Lee.
7 #
8 # 2019-0502
89 #
910 # $Id$
1011 #
2324 ATTRIBUTE Fortinet-Client-IPv6-Address 4 octets
2425 ATTRIBUTE Fortinet-Interface-Name 5 string
2526 ATTRIBUTE Fortinet-Access-Profile 6 string
26
27 #
28 # Integer Translations
29 #
27 ATTRIBUTE Fortinet-SSID 7 string
28 ATTRIBUTE Fortinet-AP-Name 8 string
29 ATTRIBUTE Fortinet-FAC-Auth-Status 11 string
30 ATTRIBUTE Fortinet-FAC-Token-ID 12 string
31 ATTRIBUTE Fortinet-FAC-Challenge-Code 15 string
32 ATTRIBUTE Fortinet-Webfilter-Category-Allow 16 octets
33 ATTRIBUTE Fortinet-Webfilter-Category-Block 17 octets
34 ATTRIBUTE Fortinet-Webfilter-Category-Monitor 18 octets
35 ATTRIBUTE Fortinet-AppCtrl-Category-Allow 19 octets
36 ATTRIBUTE Fortinet-AppCtrl-Category-Block 20 octets
37 ATTRIBUTE Fortinet-AppCtrl-Risk-Allow 21 octets
38 ATTRIBUTE Fortinet-AppCtrl-Risk-Block 22 octets
39 ATTRIBUTE Fortinet-WirelessController-Device-MAC 23 ether
40 ATTRIBUTE Fortinet-WirelessController-WTP-ID 24 string
41 ATTRIBUTE Fortinet-WirelessController-Assoc-Time 25 date
42 ATTRIBUTE Fortinet-FortiWAN-AVPair 26 string
43 ATTRIBUTE Fortinet-FDD-Access-Profile 30 string
44 ATTRIBUTE Fortinet-FDD-Trusted-Hosts 31 string
45 ATTRIBUTE Fortinet-FDD-SPP-Name 32 string
46 ATTRIBUTE Fortinet-FDD-Is-System-Admin 33 string
47 ATTRIBUTE Fortinet-FDD-Is-SPP-Admin 34 string
48 ATTRIBUTE Fortinet-FDD-SPP-Policy-Group 35 string
49 ATTRIBUTE Fortinet-FDD-Allow-API-Access 36 string
50 ATTRIBUTE Fortinet-Fpc-User-Role 40 string
51 ATTRIBUTE Fortinet-Tenant-Identification 41 string
3052
3153 END-VENDOR Fortinet
524524 ATTRIBUTE TLS-Cert-Subject-Alt-Name-Email 1915 string
525525 ATTRIBUTE TLS-Cert-Subject-Alt-Name-Dns 1916 string
526526 ATTRIBUTE TLS-Cert-Subject-Alt-Name-Upn 1917 string
527 # 1918 - 1919: reserved for future cert attributes
527 ATTRIBUTE TLS-Cert-Valid-Since 1918 string
528 # 1919: reserved for future cert attribute
528529 ATTRIBUTE TLS-Client-Cert-Serial 1920 string
529530 ATTRIBUTE TLS-Client-Cert-Expiration 1921 string
530531 ATTRIBUTE TLS-Client-Cert-Issuer 1922 string
540541 ATTRIBUTE TLS-Client-Cert-Subject-Alt-Name-Upn 1932 string
541542 ATTRIBUTE TLS-PSK-Identity 1933 string
542543 ATTRIBUTE TLS-Client-Cert-X509v3-Extended-Key-Usage-OID 1936 string
543
544 # 1937 - 1939: reserved for future cert attributes
544 ATTRIBUTE TLS-Client-Cert-Valid-Since 1937 string
545
546 # 1938 - 1939: reserved for future cert attributes
545547
546548 # 1940 - 1949: reserved for TLS session caching, mostly in 4.0
547549
0 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
2 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 #
4 # From https://support.sonus.net/display/UXDOC50/Vendor+Specific+Attributes+Reference
5
6 VENDOR NET 177
7
8 BEGIN-VENDOR NET
9
10 # MSC/Media related attributes
11 ATTRIBUTE NET-Fwd-Flow-In-Realm 11 string # unsupported
12 ATTRIBUTE NET-Fwd-Flow-In-Src-Addr 12 string
13 ATTRIBUTE NET-Fwd-Flow-In-Src-Port 13 integer
14 ATTRIBUTE NET-Fwd-Flow-In-Dst-Addr 14 string
15 ATTRIBUTE NET-Fwd-Flow-In-Dst-Port 15 integer
16 ATTRIBUTE NET-Fwd-Flow-Out-Realm 16 string # unsupported
17 ATTRIBUTE NET-Fwd-Flow-Out-Src-Addr 17 string
18 ATTRIBUTE NET-Fwd-Flow-Out-Src-Port 18 integer
19 ATTRIBUTE NET-Fwd-Flow-Out-Dst-Addr 19 string
20 ATTRIBUTE NET-Fwd-Flow-Out-Dst-Port 20 integer
21 ATTRIBUTE NET-Bwd-Flow-In-Realm 21 string # unsupported
22 ATTRIBUTE NET-Bwd-Flow-In-Src-Addr 22 string
23 ATTRIBUTE NET-Bwd-Flow-In-Src-Port 23 integer
24 ATTRIBUTE NET-Bwd-Flow-In-Dst-Addr 24 string
25 ATTRIBUTE NET-Bwd-Flow-In-Dst-Port 25 integer
26 ATTRIBUTE NET-Bwd-Flow-Out-Realm 26 string # unsupported
27 ATTRIBUTE NET-Bwd-Flow-Out-Src-Addr 27 string
28 ATTRIBUTE NET-Bwd-Flow-Out-Src-Port 28 integer
29 ATTRIBUTE NET-Bwd-Flow-Out-Dst-Addr 29 string
30 ATTRIBUTE NET-Bwd-Flow-Out-Dst-Port 30 integer
31 ATTRIBUTE NET-Fwd-Flow-Media-Type 31 string
32 ATTRIBUTE NET-Fwd-Flow-PTime 32 integer
33 ATTRIBUTE NET-Fwd-Octets 33 integer
34 ATTRIBUTE NET-Fwd-Packets 34 integer
35 ATTRIBUTE NET-Fwd-RTCP-Packets-Lost 35 integer # future
36 ATTRIBUTE NET-Fwd-RTCP-Avg-Jitter 36 integer # future
37 ATTRIBUTE NET-Fwd-RTP-Avg-Latency 37 integer
38 ATTRIBUTE NET-Fwd-RTCP-MaxJitter 38 integer # future
39 ATTRIBUTE NET-Fwd-RTP-MaxLatency 39 integer
40 ATTRIBUTE NET-Fwd-RTP-Packets-Lost 40 integer
41 ATTRIBUTE NET-Fwd-RTP-Avg-Jitter 41 integer
42 ATTRIBUTE NET-Fwd-RTP-MaxJitter 42 integer
43 ATTRIBUTE NET-Bwd-Octets 43 integer
44 ATTRIBUTE NET-Bwd-Packets 44 integer
45 ATTRIBUTE NET-Bwd-RTCP-Packets-Lost 45 integer # future
46 ATTRIBUTE NET-Bwd-RTCP-Avg-Jitter 46 integer # future
47 ATTRIBUTE NET-Bwd-RTP-Avg-Latency 47 integer
48 ATTRIBUTE NET-Bwd-RTCP-MaxJitter 48 integer # future
49 ATTRIBUTE NET-Bwd-RTP-MaxLatency 49 integer
50 ATTRIBUTE NET-Bwd-RTP-Packets-Lost 50 integer
51 ATTRIBUTE NET-Bwd-RTP-Avg-Jitter 51 integer
52 ATTRIBUTE NET-Bwd-RTP-MaxJitter 52 integer
53
54 # Generic Session and Signaling Group related metrics
55 ATTRIBUTE NET-Session-Ingress-CallId 60 integer
56 ATTRIBUTE NET-Session-Egress-CallId 61 integer
57 ATTRIBUTE NET-Session-Generic-Id 62 integer
58 ATTRIBUTE NET-Routing-Table-Number 63 integer
59 ATTRIBUTE NET-Ingress-Signaling-Group 64 integer
60 ATTRIBUTE NET-Egress-Signaling-Group 65 integer
61 ATTRIBUTE NET-Primary-Routing-Number 66 string
62 ATTRIBUTE NET-Egress-Final-Routing-Num 67 string
63 ATTRIBUTE NET-Ingress-Channel-Number 68 integer
64 ATTRIBUTE NET-Egress-Channel-Number 69 integer
65 ATTRIBUTE NET-Call-Type 70 integer
66 ATTRIBUTE NET-Call-Origin 71 integer
67 ATTRIBUTE NET-Calling-Number 72 string
68 ATTRIBUTE NET-Called-Number 73 string
69 ATTRIBUTE NET-Calling-Name 74 string
70 ATTRIBUTE NET-Disconnect-Cause 75 integer
71 ATTRIBUTE NET-Abort-Cause 76 integer
72 ATTRIBUTE NET-Ingress-Channel-Id 77 string
73 ATTRIBUTE NET-Egress-Channel-Id 78 string
74 ATTRIBUTE NET-Call-Priority 79 string
75
76 # Generic Call related attributes
77 ATTRIBUTE NET-Call-Number-Type 90 string
78 ATTRIBUTE NET-Call-Plan 91 string
79 ATTRIBUTE NET-Original-Called-Number 92 string
80 ATTRIBUTE NET-Original-Called-Type 93 string
81 ATTRIBUTE NET-Original-Called-Plan 94 string
82 ATTRIBUTE NET-Called-Name 95 string
83 ATTRIBUTE NET-Namespace 96 string
84 ATTRIBUTE NET-Precedence 97 string
85 ATTRIBUTE NET-Presentation 98 string
86 ATTRIBUTE NET-Screening 99 string
87 ATTRIBUTE NET-Transfer-Capability 100 string
88 ATTRIBUTE NET-Transfer-Mode 101 string
89 ATTRIBUTE NET-Transfer-Rate 102 string
90 ATTRIBUTE NET-User-Rate 103 string
91
92 # Generic time related attributes
93 ATTRIBUTE NET-Setup-Time 110 string
94 ATTRIBUTE NET-Alert-Time 111 string
95 ATTRIBUTE NET-Connect-Time 112 string
96 ATTRIBUTE NET-Disconnect-Time 113 string
97 ATTRIBUTE NET-Inbound-Seize-Time 114 string
98 ATTRIBUTE NET-Outbound-Seize-Time 115 string
99 ATTRIBUTE NET-Call-Duration 116 integer
100 ATTRIBUTE NET-Post-Dial-Delay 117 integer
101 ATTRIBUTE NET-Disconnect-Initiator 118 integer
102
103 # SIP related
104 ATTRIBUTE NET-P-Asserted-ID 130 string
105 ATTRIBUTE NET-SIP-Diversion 131 string
106 ATTRIBUTE NET-Ingress-Local-Addr 132 string
107 ATTRIBUTE NET-Ingress-Remote-Addr 133 string
108 ATTRIBUTE NET-Egress-Local-Addr 134 string
109 ATTRIBUTE NET-Egress-Remote-Addr 135 string
110 ATTRIBUTE NET-Ingress-Net-Interface-Id 136 integer
111 ATTRIBUTE NET-Egress-Net-Interface-Id 137 integer
112 ATTRIBUTE NET-Refer-Call-Transfer-Id 138 string
113 ATTRIBUTE NET-Session-Forked-Call-Id 139 string
114 ATTRIBUTE NET-Redirect-Number 140 string
115 ATTRIBUTE NET-Redirect-Ip-Address 141 string
116 ATTRIBUTE NET-Session-Ingress-Realm 142 string
117 ATTRIBUTE NET-Session-Egress-Realm 143 string
118 ATTRIBUTE NET-Ingress-Signaling-Port-Num 144 integer
119 ATTRIBUTE NET-Egress-Signaling-Port-Num 145 integer
120 ATTRIBUTE NET-Transport-Type 146 integer
121 ATTRIBUTE NET-P-Preferred-ID 147 string
122 ATTRIBUTE NET-Replaced-Header 148 string
123
124 # Generic parameters
125 ATTRIBUTE NET-Firmware-Version 160 string
126 ATTRIBUTE NET-Local-Time-Zone 161 string
127 ATTRIBUTE NET-Gw-Id 162 string
128 ATTRIBUTE NET-Time-And-Day 163 string
129 ATTRIBUTE NET-Log-Time 164 string
130
131 END-VENDOR NET
0 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
2 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 # Version $Id$
4 #
5 # Pica8 RADIUS attributes
6 # For general information please visit:
7 # http://www.pica8.com
8 #
9
10 VENDOR Pica8 35098
11
12 BEGIN-VENDOR Pica8
13
14 ATTRIBUTE Pica8-AVPair 1 string
15 ATTRIBUTE Pica8-IP-Downloadable-ACL-Rule 2 string
16 ATTRIBUTE Pica8-IP-Downloadable-ACL-Name 3 string
17 ATTRIBUTE Pica8-Redirect-URL 4 string
18
19 END-VENDOR Pica8
0 # -*- text -*-
1 # Copyright (C) 2019 The FreeRADIUS Server project and contributors
2 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 # Version $Id$
4 ###########################################################
5 # Resilient Cloud Network Technologies (RCNTEC)
6 # Dictionary for RCNTEC's RPCM hardware, https://rpcm.pro
7 # Contributed by Sergey Minakov <ser@rcntec.com>
8 #
9 #
10 ###########################################################
11
12 VENDOR RCNTEC 46235
13 BEGIN-VENDOR RCNTEC
14
15 ATTRIBUTE RCNTEC-RPCM-Group 1 string
16 ATTRIBUTE RCNTEC-RPCM-Session-Expire 2 integer
17
18 END-VENDOR RCNTEC
0 # -*- text -*-
1 # Copyright (C) 2020 The FreeRADIUS Server project and contributors
2 # This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
3 # Version $Id$
4 #
5 # VAS Experts dictionary
6 #
7 VENDOR VasExperts 43823
8
9 BEGIN-VENDOR VasExperts
10
11 ATTRIBUTE VasExperts-Policing-Profile 1 string
12 ATTRIBUTE VasExperts-Service-Profile 2 string
13 ATTRIBUTE VasExperts-Enable-Service 3 string
14 ATTRIBUTE VasExperts-Multi-IP-User 4 integer
15 ATTRIBUTE VasExperts-UserName 5 string
16 ATTRIBUTE VasExperts-Service-Type 6 integer
17 ATTRIBUTE VasExperts-Restrict-User 7 integer
18 ATTRIBUTE VasExperts-Enable-Interconnect 8 integer
19 ATTRIBUTE VasExperts-OutVLAN 9 integer
20 ATTRIBUTE VasExperts-Command-Code 10 integer # CoA command code
21 ATTRIBUTE VasExperts-OutMAC 11 string
22
23 VALUE VasExperts-Service-Type Auth 0 # L3-authorization, known IP
24 VALUE VasExperts-Service-Type DHCP 1 # DHCP
25 VALUE VasExperts-Service-Type PAP 2 # PAP authorization
26 VALUE VasExperts-Service-Type CHAP 3 # CHAP authorization
27 VALUE VasExperts-Service-Type MS_CHAPv2 4 # MS-CHAPv2 authorization
28 VALUE VasExperts-Service-Type MAC_QinQ 5 # MAC/QinQ authorization
29 VALUE VasExperts-Service-Type ARP 6 # ARP
30 VALUE VasExperts-Service-Type DHCPv6 7 # DHCPv6
31
32 VALUE VasExperts-Command-Code Check-Acct 1 # Check Accounting session for Framed-IP-Address
33
34 # Accounting
35 ATTRIBUTE VasExperts-Acct-Traffic-Class-Name 16 string
36 ATTRIBUTE VasExperts-Acct-Traffic-Class-Input-Octets 17 integer64
37 ATTRIBUTE VasExperts-Acct-Traffic-Class-Output-Octets 18 integer64
38 ATTRIBUTE VasExperts-Acct-Traffic-Class-Input-Packets 19 integer64
39 ATTRIBUTE VasExperts-Acct-Traffic-Class-Output-Packets 20 integer64
40 ATTRIBUTE VasExperts-NAT-IP 21 ipaddr # NAT 1:1 white address
41
42 # DHCP -> Radius attributes
43 ATTRIBUTE VasExperts-DHCP-Hostname 32 octets # DHCP Opt12
44 ATTRIBUTE VasExperts-DHCP-ClientId 33 octets # DHCP Opt61
45 ATTRIBUTE VasExperts-DHCP-ClassId 34 octets # DHCP Opt60
46 ATTRIBUTE VasExperts-DHCP-RelayInfo 35 octets # DHCP Opt82
47 ATTRIBUTE VasExperts-DHCP-ClientIP 36 ipaddr # DHCP Opt50
48 ATTRIBUTE VasExperts-DHCP-Request 37 integer
49 ATTRIBUTE VasExperts-DHCP-RelayRemoteId 38 octets # DHCP Opt82 subopt 2
50 ATTRIBUTE VasExperts-DHCP-RelayCircuitId 39 octets # DHCP Opt82 subopt 1
51
52 VALUE VasExperts-DHCP-Request Discover 0
53 VALUE VasExperts-DHCP-Request Inform 1
54 VALUE VasExperts-DHCP-Request Request 2
55
56 # Radius -> DHCP (Access-Accept, Access-Reject)
57 ATTRIBUTE VasExperts-DHCP-Option 40 octets # Any DHCP option in binary form
58 ATTRIBUTE VasExperts-DHCP-DNS 41 ipaddr # DNS IP address
59 ATTRIBUTE VasExperts-DHCP-Gateway 42 ipaddr # Gateway IP address
60 ATTRIBUTE VasExperts-BOOTP-SName 43 string # BOOTP SName
61 ATTRIBUTE VasExperts-BOOTP-File 44 string # BOOTP File
62 ATTRIBUTE VasExperts-DHCP-Option-IP 45 string # IPv4 option: "opt:192.168.6.90", for example: "42:192.168.6.90"
63 ATTRIBUTE VasExperts-DHCP-Option-Num 46 string # Numeric option: "opt:1500", for example: "58:3600"
64 ATTRIBUTE VasExperts-DHCP-Option-String 47 string # String option: "opt:text", for example: "56:Hello from DHCP!"
65 ATTRIBUTE VasExperts-DHCP-Option-Bin 48 string # Binary option in hex form: "opt:xxxxxxxx", for example: "58:100E"
66
67 ATTRIBUTE VasExperts-ARP-SourceIP 60 ipaddr # ARP source IP
68 ATTRIBUTE VasExperts-ARP-TargetIP 61 ipaddr # ARP target IP
69
70 # DHCPv6 -> Radius attributes
71 ATTRIBUTE VasExperts-DHCPv6-Request 70 integer # DHCPv6 request type
72 ATTRIBUTE VasExperts-DHCPv6-UserClass 71 octets # DHCPv6 User Class option
73 ATTRIBUTE VasExperts-DHCPv6-VendorClass 72 octets # DHCPv6 Vendor Class option
74 ATTRIBUTE VasExperts-DHCPv6-RemoteId 73 octets # DHCPv6 RemoteId option [RFC 4649]
75 ATTRIBUTE VasExperts-DHCPv6-SubsId 74 octets # DHCPv6 SubscriberId option [RFC 4580]
76 ATTRIBUTE VasExperts-DHCPv6-Delegated 75 integer # DHCPv6 flag: (1) - CPE requests delegated prefix, (0) - does not
77
78 # Radius -> DHCPv6 attributes
79 ATTRIBUTE VasExperts-DHCP-Option-IPv6 80 string # IPv6 option: "opt:2001:fde3::709", for example: "22:2001:fde3::709"
80 ATTRIBUTE VasExperts-DHCP-Option-IPv6-Prefix 81 string # IPv6 prefix option: "opt:2001:fde3/64"
81 ATTRIBUTE VasExperts-DHCP6-Option-Num 82 string # DHCPv6 numeric option: "opt:1500", for example: "58:3600"
82 ATTRIBUTE VasExperts-DHCP6-Option-String 83 string # DHCPv6 string option: "opt:text", for example: "56:Hello from DHCP!"
83 ATTRIBUTE VasExperts-DHCP6-Option-Bin 84 string # DHCPv6 binary option in hex form: "opt:xxxxxxxx", for example: "58:100E"
84
85 VALUE VasExperts-DHCPv6-Request Solicit 1
86 VALUE VasExperts-DHCPv6-Request Request 3
87 VALUE VasExperts-DHCPv6-Request Renew 5
88 VALUE VasExperts-DHCPv6-Request Rebind 6
89
90 # Attributes 250 - 255 are dedicated to the customer's private use and are not used (ignored) by pcrf
91
92 END-VENDOR VasExperts
6666 ATTRIBUTE WiMAX-Accounting-Capabilities 1.2 byte
6767 ATTRIBUTE WiMAX-Hotlining-Capabilities 1.3 byte
6868 ATTRIBUTE WiMAX-Idle-Mode-Notification-Cap 1.4 byte
69 ATTRIBUTE WiMAX-ASN-IP-Service-Capabilities 1.5 byte
70 ATTRIBUTE WiMAX-VCSN-IP-Service-Capabilities 1.6 byte
71 ATTRIBUTE WiMAX-Authorized-IP-Services 1.7 byte
72 ATTRIBUTE WiMAX-Authorized-Anchor-Locations 1.8 byte
73 ATTRIBUTE WiMAX-ASN-Ethernet-Service-Capabilities 1.9 byte
74 ATTRIBUTE WiMAX-VCSN-Ethernet-Service-Capabilities 1.10 byte
75 ATTRIBUTE WiMAX-Authorized-Ethernet-Services 1.11 byte
6976
7077 # This is really a bitmap
7178 VALUE WiMAX-Accounting-Capabilities No-Accounting 0
8188
8289 VALUE WiMAX-Idle-Mode-Notification-Cap Not-Supported 0
8390 VALUE WiMAX-Idle-Mode-Notification-Cap Supported 1
91
92 VALUE WiMAX-ASN-IP-Service-Capabilities DHCP-Relay 1
93 VALUE WiMAX-ASN-IP-Service-Capabilities DHCP-Proxy 2
94 VALUE WiMAX-ASN-IP-Service-Capabilities FA 4
95 VALUE WiMAX-ASN-IP-Service-Capabilities PMIP-Client 8
96
97 VALUE WiMAX-ASN-Ethernet-Service-Capabilities eAFF-IPv4-Transport 1
98 VALUE WiMAX-ASN-Ethernet-Service-Capabilities eAFF-IPv6-Transport 2
99 VALUE WiMAX-ASN-Ethernet-Service-Capabilities eFA 4
100
101 VALUE WiMAX-VCSN-Ethernet-Service-Capabilities eCFF-IPv4-Transport 1
102 VALUE WiMAX-VCSN-Ethernet-Service-Capabilities eCFF-IPv6-Transport 2
103 VALUE WiMAX-VCSN-Ethernet-Service-Capabilities eHAv4 4
104 VALUE WiMAX-VCSN-Ethernet-Service-Capabilities eHAv6 8
84105
85106 ATTRIBUTE WiMAX-Device-Authentication-Indicator 2 byte
86107 ATTRIBUTE WiMAX-GMT-Timezone-offset 3 signed
502502
503503 /* Define to 1 if you have the <sys/prctl.h> header file. */
504504 #undef HAVE_SYS_PRCTL_H
505
506 /* Define to 1 if you have the <sys/procctl.h> header file. */
507 #undef HAVE_SYS_PROCCTL_H
505508
506509 /* Define to 1 if you have the <sys/ptrace.h> header file. */
507510 #undef HAVE_SYS_PTRACE_H
1212 #define SRADUTMP LOGDIR "/sradutmp"
1313 #define RADWTMP LOGDIR "/radwtmp"
1414 #define SRADWTMP LOGDIR "/sradwtmp"
15
16 #ifdef __APPLE__
17 # define LT_SHREXT ".dylib"
18 #elif defined (WIN32)
19 # define LT_SHREXT ".dll"
20 #else
21 # define LT_SHREXT ".so"
22 #endif
415415 int rad_expand_xlat(REQUEST *request, char const *cmd,
416416 int max_argc, char const *argv[], bool can_fail,
417417 size_t argv_buflen, char *argv_buf);
418 void rad_tv_sub(struct timeval const *end, struct timeval const *start, struct timeval *elapsed);
418419
419420 void verify_request(char const *file, int line, REQUEST *request); /* only for special debug builds */
420421 void rad_mode_to_str(char out[10], mode_t mode);
3939
4040 #ifdef HAVE_SYS_PRCTL_H
4141 # include <sys/prctl.h>
42 #endif
43
44 #ifdef HAVE_SYS_PROCCTL_H
45 # include <sys/procctl.h>
4246 #endif
4347
4448 #ifdef HAVE_SYS_PTRACE_H
246250 return ret;
247251 }
248252 }
253 #elif defined(HAVE_SYS_PROCCTL_H)
254 static int fr_get_debug_state(void)
255 {
256 int status;
257
258 if (procctl(P_PID, getpid(), PROC_TRACE_STATUS, &status) == -1) {
259 fr_strerror_printf("Cannot get dumpable flag: procctl(PROC_TRACE_STATUS) failed: %s", fr_syserror(errno));
260 return DEBUG_STATE_UNKNOWN;
261 }
262
263 /*
264 * As FreeBSD docs say about "PROC_TRACE_STATUS":
265 *
266 * Returns the current tracing status for the specified process in the
267 * integer variable pointed to by data. If tracing is disabled, data
268 * is set to -1. If tracing is enabled, but no debugger is attached by
269 * the ptrace(2) syscall, data is set to 0. If a debugger is attached,
270 * data is set to the pid of the debugger process.
271 */
272 if (status <= 0) return DEBUG_STATE_NOT_ATTACHED;
273
274 return DEBUG_STATE_ATTACHED;
275 }
249276 #else
250277 static int fr_get_debug_state(void)
251278 {
473500
474501 return 0;
475502 }
503 #elif defined(HAVE_SYS_PROCCTL_H)
504 static int fr_set_dumpable_flag(bool dumpable)
505 {
506 int mode = dumpable ? PROC_TRACE_CTL_ENABLE : PROC_TRACE_CTL_DISABLE;
507
508 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &mode) == -1) {
509 fr_strerror_printf("Cannot re-enable core dumps: procctl(PROC_TRACE_CTL) failed: %s",
510 fr_syserror(errno));
511 return -1;
512 }
513
514 return 0;
515 }
476516 #else
477517 static int fr_set_dumpable_flag(UNUSED bool dumpable)
478518 {
499539 * Linux is crazy and prctl sometimes returns 2 for disabled
500540 */
501541 if (ret != 1) return 0;
542 return 1;
543 }
544 #elif defined(HAVE_SYS_PROCCTL_H)
545 static int fr_get_dumpable_flag(void)
546 {
547 int status;
548
549 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &status) == -1) {
550 fr_strerror_printf("Cannot get dumpable flag: procctl(PROC_TRACE_CTL) failed: %s", fr_syserror(errno));
551 return -1;
552 }
553
554 /*
555 * There are a few different kinds of disabled, but only
556 * one ENABLE.
557 */
558 if (status != PROC_TRACE_CTL_ENABLE) return 0;
559
502560 return 1;
503561 }
504562 #else
25352535 * BEGIN-VENDOR foo format=Foo-Encapsulation-Attr
25362536 */
25372537 if (argc > 2) {
2538 if (strncmp(argv[2], "format=", 7) != 0) {
2538 if ((strncmp(argv[2], "format=", 7) != 0) &&
2539 (strncmp(argv[2], "parent=", 7) != 0)) {
25392540 fr_strerror_printf(
25402541 "dict_init: %s[%d]: Invalid format %s",
25412542 fn, line, argv[2]);
100100 }
101101
102102 if ((str[0] >= 0xf1) && /* 6 */
103 (str[1] <= 0xf3) &&
103 (str[0] <= 0xf3) &&
104104 (str[1] >= 0x80) &&
105105 (str[1] <= 0xbf) &&
106106 (str[2] >= 0x80) &&
209209 * to the global client list.
210210 */
211211 subcs = cf_section_sub_find(cs, "listen");
212 if (!subcs) goto global_clients;
212 if (!subcs) {
213 DEBUG("No 'listen' section in virtual server %s. Adding client to global client list",
214 client->server);
215 goto global_clients;
216 }
213217
214218 /*
215219 * If the client list already exists, use that.
285289 }
286290
287291 ERROR("Failed to add duplicate client %s", client->shortname);
288 client_free(client);
289292 return false;
290293 }
291294 #undef namecmp
294297 * Other error adding client: likely is fatal.
295298 */
296299 if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) {
297 client_free(client);
298300 return false;
299301 }
300302
26722672 #ifdef WITH_STATS
26732673 static fr_command_table_t command_table_stats[] = {
26742674 { "client", FR_READ,
2675 "stats client [auth/acct] <ipaddr> [udp|tcp] [listen <ipaddr> <port>] "
2675 "stats client [auth/acct/coa] <ipaddr> [udp|tcp] [listen <ipaddr> <port>] "
26762676 "- show statistics for given client, or for all clients (auth or acct)",
26772677 command_stats_client, NULL },
26782678
122122 char const *filename;
123123 CONF_SECTION *cs;
124124 struct stat buf;
125 bool from_dir;
125126 } cf_file_t;
126127
127128 CONF_SECTION *root_config = NULL;
328329 if (stat(filename, &my_file.buf) < 0) goto error;
329330
330331 file = rbtree_finddata(tree, &my_file);
331 if (file) return 0;
332 if (file && !file->from_dir) return 0;
332333 }
333334
334335 DEBUG2("including configuration file %s", filename);
4343 #endif
4444
4545 #define MAX_ARGV (256)
46
47 #define USEC 1000000
48 static void tv_sub(struct timeval *end, struct timeval *start,
49 struct timeval *elapsed)
50 {
51 elapsed->tv_sec = end->tv_sec - start->tv_sec;
52 if (elapsed->tv_sec > 0) {
53 elapsed->tv_sec--;
54 elapsed->tv_usec = USEC;
55 } else {
56 elapsed->tv_usec = 0;
57 }
58 elapsed->tv_usec += end->tv_usec;
59 elapsed->tv_usec -= start->tv_usec;
60
61 if (elapsed->tv_usec >= USEC) {
62 elapsed->tv_usec -= USEC;
63 elapsed->tv_sec++;
64 }
65 }
66
6746
6847 /** Start a process
6948 *
426405 FD_SET(fd, &fds);
427406
428407 gettimeofday(&when, NULL);
429 tv_sub(&when, &start, &elapsed);
408 rad_tv_sub(&when, &start, &elapsed);
430409 if (elapsed.tv_sec >= timeout) goto too_long;
431410
432411 when.tv_sec = timeout;
433412 when.tv_usec = 0;
434 tv_sub(&when, &elapsed, &wake);
413 rad_tv_sub(&when, &elapsed, &wake);
435414
436415 rcode = select(fd + 1, &fds, NULL, NULL, &wake);
437416 if (rcode == 0) {
426426 }
427427
428428 if (len < sizeof(buffer)) {
429 len += vsnprintf(buffer + len, sizeof(buffer) - len - 1, msg, ap);
429 vsnprintf(buffer + len, sizeof(buffer) - len - 1, msg, ap);
430 len += strlen(buffer + len);
430431 }
431432
432433 /*
9494 #define RTLD_LOCAL (0)
9595 #endif
9696
97 #ifdef __APPLE__
98 # define LT_SHREXT ".dylib"
99 #elif defined (WIN32)
100 # define LT_SHREXT ".dll"
101 #else
102 # define LT_SHREXT ".so"
103 #endif
104
10597 /** Check if the magic number in the module matches the one in the library
10698 *
10799 * This is used to detect potential ABI issues caused by running with modules which
5656 rad_assert(bufsize > 0);
5757
5858 next:
59 rad_assert(p < end);
60
5961 if (!c) {
62 p[0] = '\0';
63 return 0;
64 }
65
66 /*
67 * Don't overflow the output buffer.
68 */
69 if ((end - p) < 2) {
6070 p[0] = '\0';
6171 return 0;
6272 }
6979 case COND_TYPE_EXISTS:
7080 rad_assert(c->data.vpt != NULL);
7181 if (c->cast) {
72 len = snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
73 c->cast->type, "??"));
74 p += len;
82 snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
83 c->cast->type, "??"));
84 p += strlen(p);
7585 }
7686
7787 len = tmpl_prints(p, end - p, c->data.vpt, NULL);
8494 *(p++) = '['; /* for extra-clear debugging */
8595 #endif
8696 if (c->cast) {
87 len = snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
88 c->cast->type, "??"));
89 p += len;
97 snprintf(p, end - p, "<%s>", fr_int2str(dict_attr_types,
98 c->cast->type, "??"));
99 p += strlen(p);
90100 }
91101
92102 len = map_prints(p, end - p, c->data.map);
24732473 }
24742474
24752475 old_server = request->server;
2476 rad_assert(request->home_server != NULL);
24772476
24782477 /*
24792478 * If the home server is virtual, just run pre_proxy from
24802479 * that section.
24812480 */
2482 if (request->home_server->server) {
2481 if (request->home_server && request->home_server->server) {
24832482 request->server = request->home_server->server;
24842483
24852484 } else {
31803179 }
31813180
31823181 old_server = request->server;
3183 rad_assert(request->home_server != NULL);
31843182
31853183 /*
31863184 * If the home server is virtual, just run pre_proxy from
31873185 * that section.
31883186 */
3189 if (request->home_server->server) {
3187 if (request->home_server && request->home_server->server) {
31903188 request->server = request->home_server->server;
31913189
31923190 } else {
123123 if (!cap) {
124124 RDEBUG4("No subcapture data found");
125125 *out = NULL;
126 return 1;
126 return -1;
127127 }
128128
129129 ret = pcre_get_substring(cap->value, (int *)cap->rxmatch, (int)cap->nmatch, num, &p);
181181 if (!cap) {
182182 RDEBUG4("No subcapture data found");
183183 *out = NULL;
184 return 1;
184 return -1;
185185 }
186186
187187 ret = pcre_get_named_substring(cap->preg->compiled, cap->value,
5757 #endif
5858 #endif
5959
60 static void tv_sub(struct timeval *end, struct timeval *start,
61 struct timeval *elapsed)
62 {
63 elapsed->tv_sec = end->tv_sec - start->tv_sec;
64 if (elapsed->tv_sec > 0) {
65 elapsed->tv_sec--;
66 elapsed->tv_usec = USEC;
67 } else {
68 elapsed->tv_usec = 0;
69 }
70 elapsed->tv_usec += end->tv_usec;
71 elapsed->tv_usec -= start->tv_usec;
72
73 if (elapsed->tv_usec >= USEC) {
74 elapsed->tv_usec -= USEC;
75 elapsed->tv_sec++;
76 }
77 }
78
7960 static void stats_time(fr_stats_t *stats, struct timeval *start,
8061 struct timeval *end)
8162 {
8566 if ((start->tv_sec == 0) || (end->tv_sec == 0) ||
8667 (end->tv_sec < start->tv_sec)) return;
8768
88 tv_sub(end, start, &diff);
69 rad_tv_sub(end, start, &diff);
8970
9071 if (diff.tv_sec >= 10) {
9172 stats->elapsed[7]++;
15641564 return 0;
15651565 }
15661566
1567 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
1567 #if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
15681568 static SSL_SESSION *cbtls_get_session(SSL *ssl, unsigned char *data, int len, int *copy)
15691569 #else
15701570 static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int len, int *copy)
20642064 /*
20652065 * For creating certificate attributes.
20662066 */
2067 static char const *cert_attr_names[8][2] = {
2067 static char const *cert_attr_names[9][2] = {
20682068 { "TLS-Client-Cert-Serial", "TLS-Cert-Serial" },
20692069 { "TLS-Client-Cert-Expiration", "TLS-Cert-Expiration" },
20702070 { "TLS-Client-Cert-Subject", "TLS-Cert-Subject" },
20722072 { "TLS-Client-Cert-Common-Name", "TLS-Cert-Common-Name" },
20732073 { "TLS-Client-Cert-Subject-Alt-Name-Email", "TLS-Cert-Subject-Alt-Name-Email" },
20742074 { "TLS-Client-Cert-Subject-Alt-Name-Dns", "TLS-Cert-Subject-Alt-Name-Dns" },
2075 { "TLS-Client-Cert-Subject-Alt-Name-Upn", "TLS-Cert-Subject-Alt-Name-Upn" }
2075 { "TLS-Client-Cert-Subject-Alt-Name-Upn", "TLS-Cert-Subject-Alt-Name-Upn" },
2076 { "TLS-Client-Cert-Valid-Since", "TLS-Cert-Valid-Since" }
20762077 };
20772078
20782079 #define FR_TLS_SERIAL (0)
20832084 #define FR_TLS_SAN_EMAIL (5)
20842085 #define FR_TLS_SAN_DNS (6)
20852086 #define FR_TLS_SAN_UPN (7)
2087 #define FR_TLS_VALID_SINCE (8)
20862088
20872089 /*
20882090 * Before trusting a certificate, you must make sure that the
22102212 memcpy(buf, (char*) asn_time->data, asn_time->length);
22112213 buf[asn_time->length] = '\0';
22122214 vp = fr_pair_make(talloc_ctx, certs, cert_attr_names[FR_TLS_EXPIRATION][lookup], buf, T_OP_SET);
2215 rdebug_pair(L_DBG_LVL_2, request, vp, NULL);
2216 }
2217
2218 /*
2219 * Get the Valid Since Date
2220 */
2221 buf[0] = '\0';
2222 asn_time = X509_get_notBefore(client_cert);
2223 if (certs && (lookup <= 1) && asn_time &&
2224 (asn_time->length < (int) sizeof(buf))) {
2225 memcpy(buf, (char*) asn_time->data, asn_time->length);
2226 buf[asn_time->length] = '\0';
2227 vp = fr_pair_make(talloc_ctx, certs, cert_attr_names[FR_TLS_VALID_SINCE][lookup], buf, T_OP_SET);
22132228 rdebug_pair(L_DBG_LVL_2, request, vp, NULL);
22142229 }
22152230
23592374 if (*p == ' ') *p = '-';
23602375 }
23612376
2362 X509V3_EXT_print(out, ext, 0, 0);
2363 len = BIO_read(out, value , sizeof(value) - 1);
2364 if (len <= 0) continue;
2365
2366 value[len] = '\0';
2377 if (X509V3_EXT_get(ext)) { /* Known extension, converting value into plain string */
2378 X509V3_EXT_print(out, ext, 0, 0);
2379 len = BIO_read(out, value, sizeof(value) - 1);
2380 if (len <= 0) continue;
2381 value[len] = '\0';
2382 } else {
2383 /*
2384 * An extension not known to OpenSSL, dump it's value as a value of an unknown attribute.
2385 */
2386 value[0] = '0';
2387 value[1] = 'x';
2388 const unsigned char *srcp;
2389 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
2390 const ASN1_STRING *srcasn1p;
2391 srcasn1p = X509_EXTENSION_get_data(ext);
2392 srcp = ASN1_STRING_get0_data(srcasn1p);
2393 #else
2394 ASN1_STRING *srcasn1p;
2395 srcasn1p = X509_EXTENSION_get_data(ext);
2396 srcp = ASN1_STRING_data(srcasn1p);
2397 #endif
2398 int asn1len = ASN1_STRING_length(srcasn1p);
2399 /* 3 comes from '0x' + \0 */
2400 if ((size_t)(asn1len << 1) >= sizeof(value) - 3) {
2401 RDEBUG("Value of '%s' attribute is too long to be stored, it will be truncated", attribute);
2402 asn1len = (sizeof(value) - 3) >> 1;
2403 }
2404 fr_bin2hex(value + 2, srcp, asn1len);
2405 }
2406
23672407
23682408 vp = fr_pair_make(talloc_ctx, certs, attribute, value, T_OP_ADD);
23692409 if (!vp) {
31703210
31713211 if (rad_debug_lvl && insecure_tls_version) {
31723212 WARN("The configuration allows TLS 1.0 and/or TLS 1.1. We STRONGLY recommned using only TLS 1.2 for security");
3173 WARN("Please set: min_tls_version = \"1.2\"");
3213 WARN("Please set: tls_min_version = \"1.2\"");
31743214 }
31753215 }
31763216
33933433 */
33943434 SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size);
33953435
3396 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
3436 #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
33973437 SSL_CTX_set_num_tickets(ctx, 1);
33983438 #endif
33993439
34003440 } else {
34013441 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
34023442
3403 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
3443 #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
34043444 /*
34053445 * This controls the number of stateful or stateless tickets
34063446 * generated with TLS 1.3. In OpenSSL 1.1.1 it's also
17051705 }
17061706 return 0;
17071707 }
1708
1709 /** Determine the elapsed time between two timevals
1710 *
1711 * @param end timeval nearest to the present
1712 * @param start timeval furthest from the present
1713 * @param elapsed Where to write the elapsed time
1714 */
1715 void rad_tv_sub(struct timeval const *end, struct timeval const *start, struct timeval *elapsed)
1716 {
1717 elapsed->tv_sec = end->tv_sec - start->tv_sec;
1718 if (elapsed->tv_sec > 0) {
1719 elapsed->tv_sec--;
1720 elapsed->tv_usec = USEC;
1721 } else {
1722 elapsed->tv_usec = 0;
1723 }
1724 elapsed->tv_usec += end->tv_usec;
1725 elapsed->tv_usec -= start->tv_usec;
1726
1727 if (elapsed->tv_usec >= USEC) {
1728 elapsed->tv_usec -= USEC;
1729 elapsed->tv_sec++;
1730 }
1731 }
485485 type++;
486486 }
487487 }
488 REXDENT();
488489
489490 *out = '\0';
490491 return 0;
14671468 ssize_t slen;
14681469 xlat_exp_t *next;
14691470
1470 if (!p[1] || !strchr("%}delmntDGHIMSTYv", p[1])) {
1471 if (!p[1] || !strchr("%}cdelmntCDGHIMSTYv", p[1])) {
14711472 talloc_free(node);
14721473 *error = "Invalid variable expansion";
14731474 p++;
21312132 str[1] = '\0';
21322133 break;
21332134
2135 case 'c': /* current epoch time seconds */
2136 snprintf(str, freespace, "%" PRIu64, (uint64_t) time(NULL));
2137 break;
2138
21342139 case 'd': /* request day */
21352140 if (!localtime_r(&when, &ts)) goto error;
21362141 strftime(str, freespace, "%d", &ts);
21602165 CTIME_R(&when, str, freespace);
21612166 nl = strchr(str, '\n');
21622167 if (nl) *nl = '\0';
2168 break;
2169
2170 case 'C': /* current epoch time microseconds */
2171 {
2172 struct timeval tv;
2173
2174 gettimeofday(&tv, NULL);
2175
2176 snprintf(str, freespace, "%" PRIu64, (uint64_t) tv.tv_usec);
2177 }
21632178 break;
21642179
21652180 case 'D': /* request date */
4343 {
4444 const EVP_CIPHER *c;
4545 const EVP_MD *h;
46 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
46 #if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
4747 int md_size;
4848
4949 if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL ||
313313 RINDENT();
314314 RDEBUG2("Stepbuf server challenge : ");
315315 for (t = 0; t < challenge->vp_length; t++) {
316 fprintf(stderr, "%02x", challenge->vp_strvalue[t]);
316 fprintf(stderr, "%02x", (unsigned int) challenge->vp_strvalue[t]);
317317 }
318318 fprintf(stderr, "\n");
319319 #endif
329329 #ifndef NDEBUG
330330 RDEBUG2("Stepbuf peer challenge : ");
331331 for (t = 2; t < 18; t++) {
332 fprintf(stderr, "%02x", response->vp_strvalue[t]);
332 fprintf(stderr, "%02x", (unsigned int) response->vp_strvalue[t]);
333333 }
334334 fprintf(stderr, "\n");
335335 #endif
346346 RDEBUG2("Stepbuf p24 : ");
347347 REXDENT();
348348 for (t = 26; t < 50; t++) {
349 fprintf(stderr, "%02x", response->vp_strvalue[t]);
349 fprintf(stderr, "%02x", (unsigned int) response->vp_strvalue[t]);
350350 }
351351 fprintf(stderr, "\n");
352352 #endif
11181118 * No password: can't do authentication.
11191119 */
11201120 if (!password) {
1121 REDEBUG("FAILED: No NT/LM-Password. Cannot perform authentication");
1121 REDEBUG("FAILED: No NT-Password. Cannot perform authentication");
11221122 return -1;
11231123 }
11241124
3434 #include <freeradius-devel/rad_assert.h>
3535
3636 #include <Python.h>
37 #include <frameobject.h> /* Python header not pulled in by default. */
3738 #include <dlfcn.h>
3839 #ifdef HAVE_DL_ITERATE_PHDR
3940 #include <link.h>
4041 #endif
4142
4243 #define LIBPYTHON_LINKER_NAME \
43 "libpython" STRINGIFY(PY_MAJOR_VERSION) "." STRINGIFY(PY_MINOR_VERSION) ".so"
44 "libpython" STRINGIFY(PY_MAJOR_VERSION) "." STRINGIFY(PY_MINOR_VERSION) LT_SHREXT
4445
4546 static uint32_t python_instances = 0;
4647 static void *python_dlhandle;
6970
7071 #if PY_VERSION_HEX > 0x03050000
7172 wchar_t *wide_name; //!< Special wide char encoding of radiusd name.
72 wchar_t *wide_path; //!< Special wide char encoding of radiusd path.
7373 #endif
7474 PyObject *module; //!< Local, interpreter specific module, containing
7575 //!< FreeRADIUS functions.
217217 */
218218 static void python_error_log(void)
219219 {
220 PyObject *pType = NULL, *pValue = NULL, *pTraceback = NULL, *pStr1 = NULL, *pStr2 = NULL;
221
222 PyErr_Fetch(&pType, &pValue, &pTraceback);
223 if (!pType || !pValue)
224 goto failed;
225 if (((pStr1 = PyObject_Str(pType)) == NULL) ||
226 ((pStr2 = PyObject_Str(pValue)) == NULL))
227 goto failed;
228
229 ERROR("%s (%s)", PyString_AsString(pStr1), PyString_AsString(pStr2));
220 PyObject *p_type = NULL, *p_value = NULL, *p_traceback = NULL, *p_str_1 = NULL, *p_str_2 = NULL;
221
222 PyErr_Fetch(&p_type, &p_value, &p_traceback);
223 PyErr_NormalizeException(&p_type, &p_value, &p_traceback);
224 if (!p_type || !p_value) goto failed;
225
226 if (((p_str_1 = PyObject_Str(p_type)) == NULL) || ((p_str_2 = PyObject_Str(p_value)) == NULL)) goto failed;
227
228 ERROR("%s (%s)", PyString_AsString(p_str_1), PyString_AsString(p_str_2));
229
230 if (p_traceback != Py_None) {
231 PyTracebackObject *ptb = (PyTracebackObject*)p_traceback;
232 size_t fnum = 0;
233
234 for (; ptb != NULL; ptb = ptb->tb_next, fnum++) {
235 PyFrameObject *cur_frame = ptb->tb_frame;
236
237 ERROR("[%ld] %s:%d at %s()",
238 fnum,
239 PyString_AsString(cur_frame->f_code->co_filename),
240 PyFrame_GetLineNumber(cur_frame),
241 PyString_AsString(cur_frame->f_code->co_name)
242 );
243 }
244 }
230245
231246 failed:
232 Py_XDECREF(pStr1);
233 Py_XDECREF(pStr2);
234 Py_XDECREF(pType);
235 Py_XDECREF(pValue);
236 Py_XDECREF(pTraceback);
247 Py_XDECREF(p_str_1);
248 Py_XDECREF(p_str_2);
249 Py_XDECREF(p_type);
250 Py_XDECREF(p_value);
251 Py_XDECREF(p_traceback);
237252 }
238253
239254 static void mod_vptuple(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, PyObject *pValue,
754769
755770 PyEval_RestoreThread(this_thread->state); /* Swap in our local thread state */
756771 ret = do_python_single(request, pFunc, funcname, inst->pass_all_vps, inst->pass_all_vps_dict);
772 if (ret == RLM_MODULE_FAIL) python_error_log();
757773 PyEval_SaveThread();
758774
759775 return ret;
10311047 * the lifetime of the module.
10321048 */
10331049 if (inst->python_path) {
1034 #if PY_VERSION_HEX > 0x03050000
1035 {
1036 inst->wide_path = Py_DecodeLocale(inst->python_path, strlen(inst->python_path));
1037 PySys_SetPath(inst->wide_path);
1050 char *p, *path;
1051 PyObject *sys = PyImport_ImportModule("sys");
1052 PyObject *sys_path = PyObject_GetAttrString(sys, "path");
1053
1054 memcpy(&p, &inst->python_path, sizeof(path));
1055
1056 for (path = strtok(p, ":"); path != NULL; path = strtok(NULL, ":")) {
1057 PyList_Append(sys_path, PyString_FromString(path));
10381058 }
1039 #else
1040 {
1041 char *path;
1042
1043 memcpy(&path, &inst->python_path, sizeof(path));
1044 PySys_SetPath(path);
1045 }
1046 #endif
1059
1060 PyObject_SetAttrString(sys, "path", sys_path);
1061 Py_DecRef(sys);
1062 Py_DecRef(sys_path);
10471063 }
10481064
10491065 /*
11541170 * Call the instantiate function.
11551171 */
11561172 code = do_python_single(NULL, inst->instantiate.function, "instantiate", inst->pass_all_vps, inst->pass_all_vps_dict);
1157 if (code < 0) {
1173 if (code == RLM_MODULE_FAIL) {
11581174 error:
11591175 python_error_log(); /* Needs valid thread with GIL */
11601176 PyEval_SaveThread();
11761192 PyEval_RestoreThread(inst->sub_interpreter);
11771193
11781194 ret = do_python_single(NULL, inst->detach.function, "detach", inst->pass_all_vps, inst->pass_all_vps_dict);
1195 if (ret == RLM_MODULE_FAIL) python_error_log();
11791196
11801197 #define PYTHON_FUNC_DESTROY(_x) python_function_destroy(&inst->_x)
11811198 PYTHON_FUNC_DESTROY(instantiate);
12121229
12131230 #if PY_VERSION_HEX > 0x03050000
12141231 if (inst->wide_name) PyMem_RawFree(inst->wide_name);
1215 if (inst->wide_path) PyMem_RawFree(inst->wide_path);
12161232 #endif
12171233 }
12181234
587587 targetname
588588 mod_cflags
589589 mod_ldflags
590 PYTHON3_BIN
590 PYTHON3_CONFIG_BIN
591591 CPP
592592 OBJEXT
593593 EXEEXT
637637 ac_subst_files=''
638638 ac_user_opts='
639639 enable_option_checking
640 with_rlm_python3_bin
641 with_rlm_python3_lib_dir
642 with_rlm_python3_include_dir
640 with_rlm_python3_config_bin
643641 '
644642 ac_precious_vars='build_alias
645643 host_alias
12561254 Optional Packages:
12571255 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
12581256 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
1259 --with-rlm-python3-bin=PATH Path to python3 binary
1260 --with-rlm-python3-lib-dir=DIR Directory for Python library files
1261 --with-rlm-python3-include-dir=DIR Directory for Python include files
1257 --with-rlm-python3-config-bin=PATH Path to python-config3 binary
12621258
12631259 Some influential environment variables:
12641260 CC C compiler command
14241420 as_fn_set_status $ac_retval
14251421
14261422 } # ac_fn_c_try_cpp
1427
1428 # ac_fn_c_try_link LINENO
1429 # -----------------------
1430 # Try to link conftest.$ac_ext, and return whether this succeeded.
1431 ac_fn_c_try_link ()
1432 {
1433 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1434 rm -f conftest.$ac_objext conftest$ac_exeext
1435 if { { ac_try="$ac_link"
1436 case "(($ac_try" in
1437 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1438 *) ac_try_echo=$ac_try;;
1439 esac
1440 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
1441 $as_echo "$ac_try_echo"; } >&5
1442 (eval "$ac_link") 2>conftest.err
1443 ac_status=$?
1444 if test -s conftest.err; then
1445 grep -v '^ *+' conftest.err >conftest.er1
1446 cat conftest.er1 >&5
1447 mv -f conftest.er1 conftest.err
1448 fi
1449 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1450 test $ac_status = 0; } && {
1451 test -z "$ac_c_werror_flag" ||
1452 test ! -s conftest.err
1453 } && test -s conftest$ac_exeext && {
1454 test "$cross_compiling" = yes ||
1455 test -x conftest$ac_exeext
1456 }; then :
1457 ac_retval=0
1458 else
1459 $as_echo "$as_me: failed program was:" >&5
1460 sed 's/^/| /' conftest.$ac_ext >&5
1461
1462 ac_retval=1
1463 fi
1464 # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
1465 # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
1466 # interfere with the next link command; also delete a directory that is
1467 # left behind by Apple's compiler. We do this before executing the actions.
1468 rm -rf conftest.dSYM conftest_ipa8_conftest.oo
1469 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
1470 as_fn_set_status $ac_retval
1471
1472 } # ac_fn_c_try_link
1473
1474 # ac_fn_c_check_func LINENO FUNC VAR
1475 # ----------------------------------
1476 # Tests whether FUNC exists, setting the cache variable VAR accordingly
1477 ac_fn_c_check_func ()
1478 {
1479 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1480 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
1481 $as_echo_n "checking for $2... " >&6; }
1482 if eval \${$3+:} false; then :
1483 $as_echo_n "(cached) " >&6
1484 else
1485 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
1486 /* end confdefs.h. */
1487 /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
1488 For example, HP-UX 11i <limits.h> declares gettimeofday. */
1489 #define $2 innocuous_$2
1490
1491 /* System header to define __stub macros and hopefully few prototypes,
1492 which can conflict with char $2 (); below.
1493 Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
1494 <limits.h> exists even on freestanding compilers. */
1495
1496 #ifdef __STDC__
1497 # include <limits.h>
1498 #else
1499 # include <assert.h>
1500 #endif
1501
1502 #undef $2
1503
1504 /* Override any GCC internal prototype to avoid an error.
1505 Use char because int might match the return type of a GCC
1506 builtin and then its argument prototype would still apply. */
1507 #ifdef __cplusplus
1508 extern "C"
1509 #endif
1510 char $2 ();
1511 /* The GNU C library defines this for functions which it implements
1512 to always fail with ENOSYS. Some functions are actually named
1513 something starting with __ and the normal name is an alias. */
1514 #if defined __stub_$2 || defined __stub___$2
1515 choke me
1516 #endif
1517
1518 int
1519 main ()
1520 {
1521 return $2 ();
1522 ;
1523 return 0;
1524 }
1525 _ACEOF
1526 if ac_fn_c_try_link "$LINENO"; then :
1527 eval "$3=yes"
1528 else
1529 eval "$3=no"
1530 fi
1531 rm -f core conftest.err conftest.$ac_objext \
1532 conftest$ac_exeext conftest.$ac_ext
1533 fi
1534 eval ac_res=\$$3
1535 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
1536 $as_echo "$ac_res" >&6; }
1537 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
1538
1539 } # ac_fn_c_check_func
15401423 cat >config.log <<_ACEOF
15411424 This file contains any messages produced by compilers while
15421425 running configure, to aid debugging if configure makes a mistake.
28212704 ac_compiler_gnu=$ac_cv_c_compiler_gnu
28222705
28232706
2824 PYTHON3_BIN=
2825
2826 # Check whether --with-rlm-python3-bin was given.
2827 if test "${with_rlm_python3_bin+set}" = set; then :
2828 withval=$with_rlm_python3_bin; case "$withval" in
2707 PYTHON3_CONFIG_BIN=
2708
2709 # Check whether --with-rlm-python3-config-bin was given.
2710 if test "${with_rlm_python3_config_bin+set}" = set; then :
2711 withval=$with_rlm_python3_config_bin; case "$withval" in
28292712 no)
2830 as_fn_error $? "Need rlm-python3-bin" "$LINENO" 5
2713 as_fn_error $? "Need rlm-python3-config-bin" "$LINENO" 5
28312714 ;;
28322715 yes)
28332716 ;;
28342717 *)
2835 PYTHON3_BIN="$withval"
2718 PYTHON3_CONFIG_BIN="$withval"
28362719 ;;
28372720 esac
28382721
28392722 fi
28402723
28412724
2842 if test "x$PYTHON3_BIN" = x; then
2843 for ac_prog in python3
2725 if test "x$PYTHON3_CONFIG_BIN" = x; then
2726 for ac_prog in python3-config
28442727 do
28452728 # Extract the first word of "$ac_prog", so it can be a program name with args.
28462729 set dummy $ac_prog; ac_word=$2
28472730 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
28482731 $as_echo_n "checking for $ac_word... " >&6; }
2849 if ${ac_cv_prog_PYTHON3_BIN+:} false; then :
2732 if ${ac_cv_prog_PYTHON3_CONFIG_BIN+:} false; then :
28502733 $as_echo_n "(cached) " >&6
28512734 else
2852 if test -n "$PYTHON3_BIN"; then
2853 ac_cv_prog_PYTHON3_BIN="$PYTHON3_BIN" # Let the user override the test.
2735 if test -n "$PYTHON3_CONFIG_BIN"; then
2736 ac_cv_prog_PYTHON3_CONFIG_BIN="$PYTHON3_CONFIG_BIN" # Let the user override the test.
28542737 else
28552738 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
28562739 as_dummy="${PATH}:/usr/bin:/usr/local/bin"
28602743 test -z "$as_dir" && as_dir=.
28612744 for ac_exec_ext in '' $ac_executable_extensions; do
28622745 if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
2863 ac_cv_prog_PYTHON3_BIN="$ac_prog"
2746 ac_cv_prog_PYTHON3_CONFIG_BIN="$ac_prog"
28642747 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
28652748 break 2
28662749 fi
28702753
28712754 fi
28722755 fi
2873 PYTHON3_BIN=$ac_cv_prog_PYTHON3_BIN
2874 if test -n "$PYTHON3_BIN"; then
2875 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3_BIN" >&5
2876 $as_echo "$PYTHON3_BIN" >&6; }
2756 PYTHON3_CONFIG_BIN=$ac_cv_prog_PYTHON3_CONFIG_BIN
2757 if test -n "$PYTHON3_CONFIG_BIN"; then
2758 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3_CONFIG_BIN" >&5
2759 $as_echo "$PYTHON3_CONFIG_BIN" >&6; }
28772760 else
28782761 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
28792762 $as_echo "no" >&6; }
28802763 fi
28812764
28822765
2883 test -n "$PYTHON3_BIN" && break
2766 test -n "$PYTHON3_CONFIG_BIN" && break
28842767 done
2885 test -n "$PYTHON3_BIN" || PYTHON3_BIN="not-found"
2768 test -n "$PYTHON3_CONFIG_BIN" || PYTHON3_CONFIG_BIN="not-found"
28862769
28872770 fi
28882771
2889 if test "x$PYTHON3_BIN" = "xnot-found"; then
2890 fail="python-binary"
2772 if test "x$PYTHON3_CONFIG_BIN" = xnot-found; then
2773 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: python3-config not found" >&5
2774 $as_echo "$as_me: WARNING: python3-config not found" >&2;}
2775 fail="$fail python3-config"
2776 else
2777 old_CFLAGS="$CFLAGS"
2778 unset CFLAGS
2779
2780 python3_cflags=`${PYTHON3_CONFIG_BIN} --cflags`
2781 { $as_echo "$as_me:${as_lineno-$LINENO}: ${PYTHON3_CONFIG_BIN}'s cflags were \"${python3_cflags}\"" >&5
2782 $as_echo "$as_me: ${PYTHON3_CONFIG_BIN}'s cflags were \"${python3_cflags}\"" >&6;}
2783
2784 mod_cflags=`echo $python3_cflags | sed -e '\
2785 s/-I/-isystem/g;\
2786 s/-isysroot[ =]\{0,1\}[^-]*//g;\
2787 s/-O[^[[:blank:]]]*//g;\
2788 s/-Wp,-D_FORTIFY_SOURCE=[[:digit:]]//g;\
2789 s/-g[^ ]*//g;\
2790 s/-W[^ ]*//g;\
2791 s/-DNDEBUG[[:blank:]]*//g;
2792 '`
2793 { $as_echo "$as_me:${as_lineno-$LINENO}: Sanitized cflags were \"${mod_cflags}\"" >&5
2794 $as_echo "$as_me: Sanitized cflags were \"${mod_cflags}\"" >&6;}
2795
2796 python3_ldflags=`${PYTHON3_CONFIG_BIN} --ldflags`
2797 { $as_echo "$as_me:${as_lineno-$LINENO}: ${PYTHON3_CONFIG_BIN}'s ldflags were \"$python3_ldflags}\"" >&5
2798 $as_echo "$as_me: ${PYTHON3_CONFIG_BIN}'s ldflags were \"$python3_ldflags}\"" >&6;}
2799
2800 mod_ldflags=`echo $python3_ldflags | sed -e '\
2801 s/-Wl,-O[[:digit:]][[:blank:]]*//g;\
2802 s/-Wl,-Bsymbolic-functions[[:blank:]]*//g;\
2803 s/-Xlinker -export-dynamic//g;\
2804 s/-Wl,-stack_size,[[:digit:]]*[[:blank:]]//g;
2805 '`
2806 { $as_echo "$as_me:${as_lineno-$LINENO}: Sanitized ldflags were \"${mod_ldflags}\"" >&5
2807 $as_echo "$as_me: Sanitized ldflags were \"${mod_ldflags}\"" >&6;}
2808
2809 CFLAGS=$old_CFLAGS
2810
2811 targetname="rlm_python3"
28912812 fi
2892
2893 PY_LIB_DIR=
2894
2895 # Check whether --with-rlm-python3-lib-dir was given.
2896 if test "${with_rlm_python3_lib_dir+set}" = set; then :
2897 withval=$with_rlm_python3_lib_dir; case "$withval" in
2898 no)
2899 as_fn_error $? "Need rlm-python3-lib-dir" "$LINENO" 5
2900 ;;
2901 yes)
2902 ;;
2903 *)
2904 PY_LIB_DIR="$withval"
2905 ;;
2906 esac
2907
2908 fi
2909
2910
2911 PY_INC_DIR=
2912
2913 # Check whether --with-rlm-python3-include-dir was given.
2914 if test "${with_rlm_python3_include_dir+set}" = set; then :
2915 withval=$with_rlm_python3_include_dir; case "$withval" in
2916 no)
2917 as_fn_error $? "Need rlm-python3-include-dir" "$LINENO" 5
2918 ;;
2919 yes)
2920 ;;
2921 *)
2922 PY_INC_DIR="$withval"
2923 ;;
2924 esac
2925
2926 fi
2927
2928
2929 if test x$fail = x; then
2930 PY_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.prefix)'`
2931 { $as_echo "$as_me:${as_lineno-$LINENO}: Python sys.prefix \"${PY_PREFIX}\"" >&5
2932 $as_echo "$as_me: Python sys.prefix \"${PY_PREFIX}\"" >&6;}
2933
2934 PY_EXEC_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.exec_prefix)'`
2935 { $as_echo "$as_me:${as_lineno-$LINENO}: Python sys.exec_prefix \"${PY_EXEC_PREFIX}\"" >&5
2936 $as_echo "$as_me: Python sys.exec_prefix \"${PY_EXEC_PREFIX}\"" >&6;}
2937
2938 PY_SYS_VERSION=`${PYTHON3_BIN} -c 'import sys ; print(sys.version[0:3])'`
2939 { $as_echo "$as_me:${as_lineno-$LINENO}: Python sys.version \"${PY_SYS_VERSION}\"" >&5
2940 $as_echo "$as_me: Python sys.version \"${PY_SYS_VERSION}\"" >&6;}
2941
2942 if test "x$PY_LIB_DIR" = "x"; then
2943 PY_LIB_DIR="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
2944 PY_LIB_LOC="-L$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
2945 fi
2946
2947 PY_MAKEFILE="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config/Makefile"
2948 if test -f ${PY_MAKEFILE}; then
2949 PY_LOCAL_MOD_LIBS=`sed -n -e 's/^LOCALMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[:blank:]]/ /g;s/^ *//;s/ *$//'`
2950 { $as_echo "$as_me:${as_lineno-$LINENO}: Python local_mod_libs \"${PY_LOCAL_MOD_LIBS}\"" >&5
2951 $as_echo "$as_me: Python local_mod_libs \"${PY_LOCAL_MOD_LIBS}\"" >&6;}
2952
2953 PY_BASE_MOD_LIBS=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[:blank:]]/ /g;s/^ *//;s/ *$//'`
2954 { $as_echo "$as_me:${as_lineno-$LINENO}: Python base_mod_libs \"${PY_BASE_MOD_LIBS}\"" >&5
2955 $as_echo "$as_me: Python base_mod_libs \"${PY_BASE_MOD_LIBS}\"" >&6;}
2956
2957 PY_OTHER_LIBS=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[:blank:]]/ /g;s/ / /g;s/^ *//;s/ *$//'`
2958 PY_OTHER_LDFLAGS=`sed -n -e 's/^LINKFORSHARED=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[:blank:]]/ /g;s/ / /g;s/^ *//;s/ *$//'`
2959 { $as_echo "$as_me:${as_lineno-$LINENO}: Python other_libs \"${PY_OTHER_LDFLAGS} ${PY_OTHER_LIBS}\"" >&5
2960 $as_echo "$as_me: Python other_libs \"${PY_OTHER_LDFLAGS} ${PY_OTHER_LIBS}\"" >&6;}
2961 fi
2962 PY_EXTRA_LIBS="$PY_LOCALMODLIBS $PY_BASE_MOD_LIBS $PY_OTHER_LIBS"
2963
2964 old_CFLAGS=$CFLAGS
2965 CFLAGS="$CFLAGS $PY_CFLAGS"
2966 smart_try_dir="$PY_PREFIX/include/python$PY_SYS_VERSION"
2967
2968
2969
2970 ac_safe=`echo "Python.h" | sed 'y%./+-%__pm%'`
2971 old_CPPFLAGS="$CPPFLAGS"
2972 smart_include=
2973 smart_include_dir="/usr/local/include /opt/include"
2974
2975 _smart_try_dir=
2976 _smart_include_dir=
2977
2978 for _prefix in $smart_prefix ""; do
2979 for _dir in $smart_try_dir; do
2980 _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
2981 done
2982
2983 for _dir in $smart_include_dir; do
2984 _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
2985 done
2986 done
2987
2988 if test "x$_smart_try_dir" != "x"; then
2989 for try in $_smart_try_dir; do
2990 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python.h in $try" >&5
2991 $as_echo_n "checking for Python.h in $try... " >&6; }
2992 CPPFLAGS="-isystem $try $old_CPPFLAGS"
2993 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
2994 /* end confdefs.h. */
2995
2996 #include <Python.h>
2997 int
2998 main ()
2999 {
3000 int a = 1;
3001 ;
3002 return 0;
3003 }
3004 _ACEOF
3005 if ac_fn_c_try_compile "$LINENO"; then :
3006
3007 smart_include="-isystem $try"
3008 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3009 $as_echo "yes" >&6; }
3010 break
3011
3012 else
3013
3014 smart_include=
3015 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3016 $as_echo "no" >&6; }
3017
3018 fi
3019 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
3020 done
3021 CPPFLAGS="$old_CPPFLAGS"
3022 fi
3023
3024 if test "x$smart_include" = "x"; then
3025 for _prefix in $smart_prefix; do
3026 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/Python.h" >&5
3027 $as_echo_n "checking for ${_prefix}/Python.h... " >&6; }
3028
3029 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3030 /* end confdefs.h. */
3031
3032 #include <Python.h>
3033 int
3034 main ()
3035 {
3036 int a = 1;
3037 ;
3038 return 0;
3039 }
3040 _ACEOF
3041 if ac_fn_c_try_compile "$LINENO"; then :
3042
3043 smart_include="-isystem ${_prefix}/"
3044 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3045 $as_echo "yes" >&6; }
3046 break
3047
3048 else
3049
3050 smart_include=
3051 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3052 $as_echo "no" >&6; }
3053
3054 fi
3055 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
3056 done
3057 fi
3058
3059 if test "x$smart_include" = "x"; then
3060 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python.h" >&5
3061 $as_echo_n "checking for Python.h... " >&6; }
3062
3063 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3064 /* end confdefs.h. */
3065
3066 #include <Python.h>
3067 int
3068 main ()
3069 {
3070 int a = 1;
3071 ;
3072 return 0;
3073 }
3074 _ACEOF
3075 if ac_fn_c_try_compile "$LINENO"; then :
3076
3077 smart_include=" "
3078 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3079 $as_echo "yes" >&6; }
3080 break
3081
3082 else
3083
3084 smart_include=
3085 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3086 $as_echo "no" >&6; }
3087
3088 fi
3089 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
3090 fi
3091
3092 if test "x$smart_include" = "x"; then
3093
3094 for prefix in $smart_prefix; do
3095
3096
3097 if test "x$LOCATE" != "x"; then
3098 DIRS=
3099 file="${_prefix}/${1}"
3100
3101 for x in `${LOCATE} $file 2>/dev/null`; do
3102 base=`echo $x | sed "s%/${file}%%"`
3103 if test "x$x" = "x$base"; then
3104 continue;
3105 fi
3106
3107 dir=`${DIRNAME} $x 2>/dev/null`
3108 exclude=`echo ${dir} | ${GREP} /home`
3109 if test "x$exclude" != "x"; then
3110 continue
3111 fi
3112
3113 already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
3114 if test "x$already" = "x"; then
3115 DIRS="$DIRS $dir"
3116 fi
3117 done
3118 fi
3119
3120 eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
3121
3122 done
3123
3124
3125 if test "x$LOCATE" != "x"; then
3126 DIRS=
3127 file=Python.h
3128
3129 for x in `${LOCATE} $file 2>/dev/null`; do
3130 base=`echo $x | sed "s%/${file}%%"`
3131 if test "x$x" = "x$base"; then
3132 continue;
3133 fi
3134
3135 dir=`${DIRNAME} $x 2>/dev/null`
3136 exclude=`echo ${dir} | ${GREP} /home`
3137 if test "x$exclude" != "x"; then
3138 continue
3139 fi
3140
3141 already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
3142 if test "x$already" = "x"; then
3143 DIRS="$DIRS $dir"
3144 fi
3145 done
3146 fi
3147
3148 eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
3149
3150
3151 for try in $_smart_include_dir; do
3152 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python.h in $try" >&5
3153 $as_echo_n "checking for Python.h in $try... " >&6; }
3154 CPPFLAGS="-isystem $try $old_CPPFLAGS"
3155 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3156 /* end confdefs.h. */
3157
3158 #include <Python.h>
3159 int
3160 main ()
3161 {
3162 int a = 1;
3163 ;
3164 return 0;
3165 }
3166 _ACEOF
3167 if ac_fn_c_try_compile "$LINENO"; then :
3168
3169 smart_include="-isystem $try"
3170 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3171 $as_echo "yes" >&6; }
3172 break
3173
3174 else
3175
3176 smart_include=
3177 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3178 $as_echo "no" >&6; }
3179
3180 fi
3181 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
3182 done
3183 CPPFLAGS="$old_CPPFLAGS"
3184 fi
3185
3186 if test "x$smart_include" != "x"; then
3187 eval "ac_cv_header_$ac_safe=yes"
3188 CPPFLAGS="$smart_include $old_CPPFLAGS"
3189 SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
3190 fi
3191
3192 smart_prefix=
3193
3194 CFLAGS=$old_CFLAGS
3195
3196 if test "x$ac_cv_header_Python_h" = "xyes"; then
3197 mod_cflags="$SMART_CPPFLAGS"
3198 else
3199 fail="$fail Python.h"
3200 targetname=
3201 fi
3202
3203 old_LIBS=$LIBS
3204 LIBS="$LIBS $PY_LIB_LOC $PY_EXTRA_LIBS -lm"
3205 smart_try_dir=$PY_LIB_DIR
3206
3207
3208 sm_lib_safe=`echo "python${PY_SYS_VERSION}" | sed 'y%./+-%__p_%'`
3209 sm_func_safe=`echo "Py_Initialize" | sed 'y%./+-%__p_%'`
3210
3211 old_LIBS="$LIBS"
3212 old_CPPFLAGS="$CPPFLAGS"
3213 smart_lib=
3214 smart_ldflags=
3215 smart_lib_dir=
3216
3217 if test "x$smart_try_dir" != "x"; then
3218 for try in $smart_try_dir; do
3219 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION} in $try" >&5
3220 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION} in $try... " >&6; }
3221 LIBS="-lpython${PY_SYS_VERSION} $old_LIBS"
3222 CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
3223 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3224 /* end confdefs.h. */
3225 extern char Py_Initialize();
3226 int
3227 main ()
3228 {
3229 Py_Initialize()
3230 ;
3231 return 0;
3232 }
3233 _ACEOF
3234 if ac_fn_c_try_link "$LINENO"; then :
3235
3236 smart_lib="-lpython${PY_SYS_VERSION}"
3237 smart_ldflags="-L$try -Wl,-rpath,$try"
3238 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3239 $as_echo "yes" >&6; }
3240 break
3241
3242 else
3243 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3244 $as_echo "no" >&6; }
3245 fi
3246 rm -f core conftest.err conftest.$ac_objext \
3247 conftest$ac_exeext conftest.$ac_ext
3248 done
3249 LIBS="$old_LIBS"
3250 CPPFLAGS="$old_CPPFLAGS"
3251 fi
3252
3253 if test "x$smart_lib" = "x"; then
3254 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION}" >&5
3255 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION}... " >&6; }
3256 LIBS="-lpython${PY_SYS_VERSION} $old_LIBS"
3257 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3258 /* end confdefs.h. */
3259 extern char Py_Initialize();
3260 int
3261 main ()
3262 {
3263 Py_Initialize()
3264 ;
3265 return 0;
3266 }
3267 _ACEOF
3268 if ac_fn_c_try_link "$LINENO"; then :
3269
3270 smart_lib="-lpython${PY_SYS_VERSION}"
3271 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3272 $as_echo "yes" >&6; }
3273
3274 else
3275 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3276 $as_echo "no" >&6; }
3277 fi
3278 rm -f core conftest.err conftest.$ac_objext \
3279 conftest$ac_exeext conftest.$ac_ext
3280 LIBS="$old_LIBS"
3281 fi
3282
3283 if test "x$smart_lib" = "x"; then
3284
3285
3286 if test "x$LOCATE" != "x"; then
3287 DIRS=
3288 file=libpython${PY_SYS_VERSION}${libltdl_cv_shlibext}
3289
3290 for x in `${LOCATE} $file 2>/dev/null`; do
3291 base=`echo $x | sed "s%/${file}%%"`
3292 if test "x$x" = "x$base"; then
3293 continue;
3294 fi
3295
3296 dir=`${DIRNAME} $x 2>/dev/null`
3297 exclude=`echo ${dir} | ${GREP} /home`
3298 if test "x$exclude" != "x"; then
3299 continue
3300 fi
3301
3302 already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
3303 if test "x$already" = "x"; then
3304 DIRS="$DIRS $dir"
3305 fi
3306 done
3307 fi
3308
3309 eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
3310
3311
3312
3313 if test "x$LOCATE" != "x"; then
3314 DIRS=
3315 file=libpython${PY_SYS_VERSION}.a
3316
3317 for x in `${LOCATE} $file 2>/dev/null`; do
3318 base=`echo $x | sed "s%/${file}%%"`
3319 if test "x$x" = "x$base"; then
3320 continue;
3321 fi
3322
3323 dir=`${DIRNAME} $x 2>/dev/null`
3324 exclude=`echo ${dir} | ${GREP} /home`
3325 if test "x$exclude" != "x"; then
3326 continue
3327 fi
3328
3329 already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
3330 if test "x$already" = "x"; then
3331 DIRS="$DIRS $dir"
3332 fi
3333 done
3334 fi
3335
3336 eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
3337
3338
3339 for try in $smart_lib_dir /usr/local/lib /opt/lib; do
3340 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION} in $try" >&5
3341 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION} in $try... " >&6; }
3342 LIBS="-lpython${PY_SYS_VERSION} $old_LIBS"
3343 CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
3344 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3345 /* end confdefs.h. */
3346 extern char Py_Initialize();
3347 int
3348 main ()
3349 {
3350 Py_Initialize()
3351 ;
3352 return 0;
3353 }
3354 _ACEOF
3355 if ac_fn_c_try_link "$LINENO"; then :
3356
3357 smart_lib="-lpython${PY_SYS_VERSION}"
3358 smart_ldflags="-L$try -Wl,-rpath,$try"
3359 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3360 $as_echo "yes" >&6; }
3361 break
3362
3363 else
3364 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3365 $as_echo "no" >&6; }
3366 fi
3367 rm -f core conftest.err conftest.$ac_objext \
3368 conftest$ac_exeext conftest.$ac_ext
3369 done
3370 LIBS="$old_LIBS"
3371 CPPFLAGS="$old_CPPFLAGS"
3372 fi
3373
3374 if test "x$smart_lib" != "x"; then
3375 eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
3376 LIBS="$smart_ldflags $smart_lib $old_LIBS"
3377 SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
3378 fi
3379
3380 LIBS=$old_LIBS
3381
3382 eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
3383 if test "x$t" = "xyes"; then
3384 mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
3385 targetname=rlm_python3
3386 else
3387
3388
3389 sm_lib_safe=`echo "python${PY_SYS_VERSION}m" | sed 'y%./+-%__p_%'`
3390 sm_func_safe=`echo "Py_Initialize" | sed 'y%./+-%__p_%'`
3391
3392 old_LIBS="$LIBS"
3393 old_CPPFLAGS="$CPPFLAGS"
3394 smart_lib=
3395 smart_ldflags=
3396 smart_lib_dir=
3397
3398 if test "x$smart_try_dir" != "x"; then
3399 for try in $smart_try_dir; do
3400 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION}m in $try" >&5
3401 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION}m in $try... " >&6; }
3402 LIBS="-lpython${PY_SYS_VERSION}m $old_LIBS"
3403 CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
3404 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3405 /* end confdefs.h. */
3406 extern char Py_Initialize();
3407 int
3408 main ()
3409 {
3410 Py_Initialize()
3411 ;
3412 return 0;
3413 }
3414 _ACEOF
3415 if ac_fn_c_try_link "$LINENO"; then :
3416
3417 smart_lib="-lpython${PY_SYS_VERSION}m"
3418 smart_ldflags="-L$try -Wl,-rpath,$try"
3419 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3420 $as_echo "yes" >&6; }
3421 break
3422
3423 else
3424 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3425 $as_echo "no" >&6; }
3426 fi
3427 rm -f core conftest.err conftest.$ac_objext \
3428 conftest$ac_exeext conftest.$ac_ext
3429 done
3430 LIBS="$old_LIBS"
3431 CPPFLAGS="$old_CPPFLAGS"
3432 fi
3433
3434 if test "x$smart_lib" = "x"; then
3435 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION}m" >&5
3436 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION}m... " >&6; }
3437 LIBS="-lpython${PY_SYS_VERSION}m $old_LIBS"
3438 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3439 /* end confdefs.h. */
3440 extern char Py_Initialize();
3441 int
3442 main ()
3443 {
3444 Py_Initialize()
3445 ;
3446 return 0;
3447 }
3448 _ACEOF
3449 if ac_fn_c_try_link "$LINENO"; then :
3450
3451 smart_lib="-lpython${PY_SYS_VERSION}m"
3452 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3453 $as_echo "yes" >&6; }
3454
3455 else
3456 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3457 $as_echo "no" >&6; }
3458 fi
3459 rm -f core conftest.err conftest.$ac_objext \
3460 conftest$ac_exeext conftest.$ac_ext
3461 LIBS="$old_LIBS"
3462 fi
3463
3464 if test "x$smart_lib" = "x"; then
3465
3466
3467 if test "x$LOCATE" != "x"; then
3468 DIRS=
3469 file=libpython${PY_SYS_VERSION}m${libltdl_cv_shlibext}
3470
3471 for x in `${LOCATE} $file 2>/dev/null`; do
3472 base=`echo $x | sed "s%/${file}%%"`
3473 if test "x$x" = "x$base"; then
3474 continue;
3475 fi
3476
3477 dir=`${DIRNAME} $x 2>/dev/null`
3478 exclude=`echo ${dir} | ${GREP} /home`
3479 if test "x$exclude" != "x"; then
3480 continue
3481 fi
3482
3483 already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
3484 if test "x$already" = "x"; then
3485 DIRS="$DIRS $dir"
3486 fi
3487 done
3488 fi
3489
3490 eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
3491
3492
3493
3494 if test "x$LOCATE" != "x"; then
3495 DIRS=
3496 file=libpython${PY_SYS_VERSION}m.a
3497
3498 for x in `${LOCATE} $file 2>/dev/null`; do
3499 base=`echo $x | sed "s%/${file}%%"`
3500 if test "x$x" = "x$base"; then
3501 continue;
3502 fi
3503
3504 dir=`${DIRNAME} $x 2>/dev/null`
3505 exclude=`echo ${dir} | ${GREP} /home`
3506 if test "x$exclude" != "x"; then
3507 continue
3508 fi
3509
3510 already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
3511 if test "x$already" = "x"; then
3512 DIRS="$DIRS $dir"
3513 fi
3514 done
3515 fi
3516
3517 eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
3518
3519
3520 for try in $smart_lib_dir /usr/local/lib /opt/lib; do
3521 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Py_Initialize in -lpython${PY_SYS_VERSION}m in $try" >&5
3522 $as_echo_n "checking for Py_Initialize in -lpython${PY_SYS_VERSION}m in $try... " >&6; }
3523 LIBS="-lpython${PY_SYS_VERSION}m $old_LIBS"
3524 CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
3525 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3526 /* end confdefs.h. */
3527 extern char Py_Initialize();
3528 int
3529 main ()
3530 {
3531 Py_Initialize()
3532 ;
3533 return 0;
3534 }
3535 _ACEOF
3536 if ac_fn_c_try_link "$LINENO"; then :
3537
3538 smart_lib="-lpython${PY_SYS_VERSION}m"
3539 smart_ldflags="-L$try -Wl,-rpath,$try"
3540 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
3541 $as_echo "yes" >&6; }
3542 break
3543
3544 else
3545 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3546 $as_echo "no" >&6; }
3547 fi
3548 rm -f core conftest.err conftest.$ac_objext \
3549 conftest$ac_exeext conftest.$ac_ext
3550 done
3551 LIBS="$old_LIBS"
3552 CPPFLAGS="$old_CPPFLAGS"
3553 fi
3554
3555 if test "x$smart_lib" != "x"; then
3556 eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
3557 LIBS="$smart_ldflags $smart_lib $old_LIBS"
3558 SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
3559 fi
3560
3561 eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
3562 if test "x$t" = "xyes"; then
3563 mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
3564 targetname=rlm_python3
3565 else
3566 targetname=
3567 fail="$fail libpython$PY_SYS_VERSION"
3568 fi
3569 fi
3570 fi
3571
3572 for ac_func in dl_iterate_phdr
3573 do :
3574 ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
3575 if test "x$ac_cv_func_dl_iterate_phdr" = xyes; then :
3576 cat >>confdefs.h <<_ACEOF
3577 #define HAVE_DL_ITERATE_PHDR 1
3578 _ACEOF
3579
3580 fi
3581 done
3582
35832813 else
35842814 targetname=
35852815 echo \*\*\* module rlm_python3 is disabled.
77 AC_PROG_CC
88 AC_PROG_CPP
99
10 dnl extra argument: --with-rlm-python3-bin
11 PYTHON3_BIN=
12 AC_ARG_WITH(rlm-python3-bin,
13 [ --with-rlm-python3-bin=PATH Path to python3 binary []],
10 dnl extra argument: --with-rlm-python3-config-bin
11 PYTHON3_CONFIG_BIN=
12 AC_ARG_WITH(rlm-python3-config-bin,
13 [ --with-rlm-python3-config-bin=PATH Path to python-config3 binary []],
1414 [ case "$withval" in
1515 no)
16 AC_MSG_ERROR(Need rlm-python3-bin)
16 AC_MSG_ERROR(Need rlm-python3-config-bin)
1717 ;;
1818 yes)
1919 ;;
2020 *)
21 PYTHON3_BIN="$withval"
21 PYTHON3_CONFIG_BIN="$withval"
2222 ;;
2323 esac ]
2424 )
2525
26 if test "x$PYTHON3_BIN" = x; then
27 AC_CHECK_PROGS(PYTHON3_BIN, [ python3 ], not-found, [${PATH}:/usr/bin:/usr/local/bin])
26 if test "x$PYTHON3_CONFIG_BIN" = x; then
27 AC_CHECK_PROGS(PYTHON3_CONFIG_BIN, [ python3-config ], not-found, [${PATH}:/usr/bin:/usr/local/bin])
2828 fi
2929
30 if test "x$PYTHON3_BIN" = "xnot-found"; then
31 fail="python-binary"
32 fi
30 if test "x$PYTHON3_CONFIG_BIN" = xnot-found; then
31 fail="$fail python3-config"
32 else
33 dnl #
34 dnl # It is necessary due to a weird behavior with 'python3-config'
35 dnl #
36 old_CFLAGS="$CFLAGS"
37 unset CFLAGS
3338
34 dnl extra argument: --with-rlm-python3-lib-dir
35 PY_LIB_DIR=
36 AC_ARG_WITH(rlm-python3-lib-dir,
37 [ --with-rlm-python3-lib-dir=DIR Directory for Python library files []],
38 [ case "$withval" in
39 no)
40 AC_MSG_ERROR(Need rlm-python3-lib-dir)
41 ;;
42 yes)
43 ;;
44 *)
45 PY_LIB_DIR="$withval"
46 ;;
47 esac ]
48 )
39 python3_cflags=`${PYTHON3_CONFIG_BIN} --cflags`
40 AC_MSG_NOTICE([${PYTHON3_CONFIG_BIN}'s cflags were \"${python3_cflags}\"])
4941
50 dnl extra argument: --with-rlm-python3-include-dir
51 PY_INC_DIR=
52 AC_ARG_WITH(rlm-python3-include-dir,
53 [ --with-rlm-python3-include-dir=DIR Directory for Python include files []],
54 [ case "$withval" in
55 no)
56 AC_MSG_ERROR(Need rlm-python3-include-dir)
57 ;;
58 yes)
59 ;;
60 *)
61 PY_INC_DIR="$withval"
62 ;;
63 esac ]
64 )
42 dnl # Convert -I to -isystem to get rid of warnings about issues in Python headers
43 dnl # Strip -systemroot
44 dnl # Strip optimisation flags (-O[0-9]?). We decide our optimisation level, not python.
45 dnl # -D_FORTIFY_SOURCE needs -O.
46 dnl # Strip debug symbol flags (-g[0-9]?). We decide on debugging symbols, not python
47 dnl # Strip -W*, we decide what warnings are important
48 dnl # Strip -DNDEBUG
49 mod_cflags=`echo $python3_cflags | sed -e '\
50 s/-I/-isystem/g;\
51 s/-isysroot[[ =]]\{0,1\}[[^-]]*//g;\
52 s/-O[[^[[:blank:]]]]*//g;\
53 s/-Wp,-D_FORTIFY_SOURCE=[[[:digit:]]]//g;\
54 s/-g[[^ ]]*//g;\
55 s/-W[[^ ]]*//g;\
56 s/-DNDEBUG[[[:blank:]]]*//g;
57 '`
58 AC_MSG_NOTICE([Sanitized cflags were \"${mod_cflags}\"])
6559
66 if test x$fail = x; then
67 PY_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.prefix)'`
68 AC_MSG_NOTICE([Python sys.prefix \"${PY_PREFIX}\"])
60 python3_ldflags=`${PYTHON3_CONFIG_BIN} --ldflags`
61 AC_MSG_NOTICE([${PYTHON3_CONFIG_BIN}'s ldflags were \"$python3_ldflags}\"])
6962
70 PY_EXEC_PREFIX=`${PYTHON3_BIN} -c 'import sys ; print(sys.exec_prefix)'`
71 AC_MSG_NOTICE([Python sys.exec_prefix \"${PY_EXEC_PREFIX}\"])
63 dnl # Strip -Wl,-O1... Is -O even a valid linker flag??
64 dnl # Strip -Wl,-Bsymbolic-functions as thats not always supported or required
65 dnl # Strip -Xlinker -export-dynamic as it causes weird linking issues on Linux
66 dnl # See: https://bugs.python.org/issue36508
67 mod_ldflags=`echo $python3_ldflags | sed -e '\
68 s/-Wl,-O[[[:digit:]]][[[:blank:]]]*//g;\
69 s/-Wl,-Bsymbolic-functions[[[:blank:]]]*//g;\
70 s/-Xlinker -export-dynamic//g;\
71 s/-Wl,-stack_size,[[[:digit:]]]*[[[:blank:]]]//g;
72 '`
73 AC_MSG_NOTICE([Sanitized ldflags were \"${mod_ldflags}\"])
7274
73 PY_SYS_VERSION=`${PYTHON3_BIN} -c 'import sys ; print(sys.version[[0:3]])'`
74 AC_MSG_NOTICE([Python sys.version \"${PY_SYS_VERSION}\"])
75
76 if test "x$PY_LIB_DIR" = "x"; then
77 PY_LIB_DIR="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
78 PY_LIB_LOC="-L$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config"
79 fi
80
81 PY_MAKEFILE="$PY_EXEC_PREFIX/lib/python${PY_SYS_VERSION}/config/Makefile"
82 if test -f ${PY_MAKEFILE}; then
83 PY_LOCAL_MOD_LIBS=`sed -n -e 's/^LOCALMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/^ *//;s/ *$//'`
84 AC_MSG_NOTICE([Python local_mod_libs \"${PY_LOCAL_MOD_LIBS}\"])
85
86 PY_BASE_MOD_LIBS=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/^ *//;s/ *$//'`
87 AC_MSG_NOTICE([Python base_mod_libs \"${PY_BASE_MOD_LIBS}\"])
88
89 PY_OTHER_LIBS=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/ / /g;s/^ *//;s/ *$//'`
90 PY_OTHER_LDFLAGS=`sed -n -e 's/^LINKFORSHARED=\(.*\)/\1/p' $PY_MAKEFILE | sed -e 's/[[[:blank:]]]/ /g;s/ / /g;s/^ *//;s/ *$//'`
91 AC_MSG_NOTICE([Python other_libs \"${PY_OTHER_LDFLAGS} ${PY_OTHER_LIBS}\"])
92 fi
93 PY_EXTRA_LIBS="$PY_LOCALMODLIBS $PY_BASE_MOD_LIBS $PY_OTHER_LIBS"
94
95 old_CFLAGS=$CFLAGS
96 CFLAGS="$CFLAGS $PY_CFLAGS"
97 smart_try_dir="$PY_PREFIX/include/python$PY_SYS_VERSION"
98 FR_SMART_CHECK_INCLUDE(Python.h)
9975 CFLAGS=$old_CFLAGS
10076
101 if test "x$ac_cv_header_Python_h" = "xyes"; then
102 mod_cflags="$SMART_CPPFLAGS"
103 else
104 fail="$fail Python.h"
105 targetname=
106 fi
107
108 old_LIBS=$LIBS
109 LIBS="$LIBS $PY_LIB_LOC $PY_EXTRA_LIBS -lm"
110 smart_try_dir=$PY_LIB_DIR
111 FR_SMART_CHECK_LIB(python${PY_SYS_VERSION}, Py_Initialize)
112 LIBS=$old_LIBS
113
114 eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
115 if test "x$t" = "xyes"; then
116 mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
117 targetname=modname
118 else
119 FR_SMART_CHECK_LIB(python${PY_SYS_VERSION}m, Py_Initialize)
120 eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
121 if test "x$t" = "xyes"; then
122 mod_ldflags="$PY_LIB_LOC $PY_EXTRA_LIBS $SMART_LIBS -lm"
123 targetname=modname
124 else
125 targetname=
126 fail="$fail libpython$PY_SYS_VERSION"
127 fi
128 fi
77 targetname="rlm_python3"
12978 fi
130
131 AC_CHECK_FUNCS([dl_iterate_phdr])
13279 else
13380 targetname=
13481 echo \*\*\* module modname is disabled.
+0
-63
src/modules/rlm_python3/radiusd_test.py less more
0 #! /usr/bin/env python3
1 #
2 # Python module test
3 # Miguel A.L. Paraz <mparaz@mparaz.com>
4 #
5 # $Id$
6
7 import radiusd
8
9 def instantiate(p):
10 print "*** instantiate ***"
11 print p
12
13 def authorize(p):
14 print "*** authorize ***"
15 print
16 radiusd.radlog(radiusd.L_INFO, '*** radlog call in authorize ***')
17 print
18 print p
19 return radiusd.RLM_MODULE_OK
20
21 def preacct(p):
22 print "*** preacct ***"
23 print p
24 return radiusd.RLM_MODULE_OK
25
26 def accounting(p):
27 print "*** accounting ***"
28 radiusd.radlog(radiusd.L_INFO, '*** radlog call in accounting (0) ***')
29 print
30 print p
31 return radiusd.RLM_MODULE_OK
32
33 def pre_proxy(p):
34 print "*** pre_proxy ***"
35 print p
36 return radiusd.RLM_MODULE_OK
37
38 def post_proxy(p):
39 print "*** post_proxy ***"
40 print p
41 return radiusd.RLM_MODULE_OK
42
43 def post_auth(p):
44 print "*** post_auth ***"
45 print p
46 return radiusd.RLM_MODULE_OK
47
48 def recv_coa(p):
49 print "*** recv_coa ***"
50 print p
51 return radiusd.RLM_MODULE_OK
52
53 def send_coa(p):
54 print "*** send_coa ***"
55 print p
56 return radiusd.RLM_MODULE_OK
57
58
59 def detach():
60 print "*** goodbye from radiusd_test.py ***"
61 return radiusd.RLM_MODULE_OK
62
4141 #endif
4242
4343 #define LIBPYTHON_LINKER_NAME \
44 "libpython" STRINGIFY(PY_MAJOR_VERSION) "." STRINGIFY(PY_MINOR_VERSION) "m.so"
44 "libpython" STRINGIFY(PY_MAJOR_VERSION) "." STRINGIFY(PY_MINOR_VERSION) "m" LT_SHREXT
4545
4646 static uint32_t python_instances = 0;
4747 static void *python_dlhandle;
6666 A(preacct)
6767 A(accounting)
6868 A(checksimul)
69 #ifdef WITH_PROXY
6970 A(pre_proxy)
7071 A(post_proxy)
72 #endif
7173 A(post_auth)
7274 #ifdef WITH_COA
7375 A(recv_coa)
9799 A(L_AUTH)
98100 A(L_INFO)
99101 A(L_ERR)
102 #ifdef WITH_PROXY
100103 A(L_PROXY)
104 #endif
101105 A(L_ACCT)
102106 A(L_DBG_WARN)
103107 A(L_DBG_ERR)
185189
186190 if (!pExcType || !pExcValue) {
187191 ERROR("%s:%d, Unknown error", __func__, __LINE__);
188 if (pExcType) {
189 Py_DecRef(pExcType);
190 }
191 if (pExcValue) {
192 Py_DecRef(pExcValue);
193 }
192 Py_XDECREF(pExcType);
193 Py_XDECREF(pExcValue);
194194 return;
195195 }
196196
197197 if (((pStr1 = PyObject_Str(pExcType)) != NULL) &&
198198 ((pStr2 = PyObject_Str(pExcValue)) != NULL)) {
199199 ERROR("%s:%d, Exception type: %s, Exception value: %s", __func__, __LINE__, PyUnicode_AsUTF8(pStr1), PyUnicode_AsUTF8(pStr2));
200 Py_DECREF(pStr1);
201 Py_DECREF(pStr2);
200202 }
201203
202204 if (pExcTraceback) {
216218 char *str = PyBytes_AsString(pTraceString);
217219 ERROR("%s:%d, full_backtrace: %s", __func__, __LINE__, str);
218220
219 if (pyth_val) {
220 Py_DecRef(pyth_val);
221 }
222 if (pystr) {
223 Py_DecRef(pystr);
224 }
225 if (pTraceString) {
226 Py_DecRef(pTraceString);
227 }
221 Py_DECREF(pyth_val);
222 Py_DECREF(pystr);
223 Py_DECREF(pTraceString);
224 Py_DECREF(pyth_func);
228225 }
229 if (pyth_func) {
230 Py_DecRef(pyth_func);
231 }
232 Py_DecRef(pyth_module);
226 Py_DECREF(pyth_module);
233227 } else {
234228 ERROR("%s:%d, py_module is null, name: %p", __func__, __LINE__, module_name);
235229 }
236230
237 if (module_name) {
238 Py_DecRef(module_name);
239 }
240
241 Py_DecRef(pRepr);
242 }
243
244 if (pExcType) {
245 Py_DecRef(pExcType);
246 }
247 if (pExcValue) {
248 Py_DecRef(pExcValue);
249 }
250 if (pExcTraceback) {
251 Py_DecRef(pExcTraceback);
252 }
253 if (pStr1) {
254 Py_DecRef(pStr1);
255 }
256 if (pStr2) {
257 Py_DecRef(pStr2);
258 }
231 Py_DECREF(module_name);
232 Py_DECREF(pRepr);
233 Py_DECREF(pExcTraceback);
234 }
235
236 Py_DECREF(pExcType);
237 Py_DECREF(pExcValue);
259238 }
260239
261240 static void mod_vptuple(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, PyObject *pValue,
509488 goto finish;
510489 }
511490
491 #ifdef WITH_PROXY
512492 /* fill proxy vps */
513493 if (request->proxy) {
514494 if (!mod_populate_vps(pArgs, 4, request->proxy->vps)) {
516496 ret = RLM_MODULE_FAIL;
517497 goto finish;
518498 }
519 } else {
499 } else
500 #endif
501 {
520502 mod_populate_vps(pArgs, 4, NULL);
521503 }
522504
505 #ifdef WITH_PROXY
523506 /* fill proxy_reply vps */
524507 if (request->proxy_reply) {
525508 if (!mod_populate_vps(pArgs, 5, request->proxy_reply->vps)) {
527510 ret = RLM_MODULE_FAIL;
528511 goto finish;
529512 }
530 } else {
513 } else
514 #endif
515 {
531516 mod_populate_vps(pArgs, 5, NULL);
532517 }
533518
549534 PyDict_SetItemString(pDictInput, "request", PyTuple_GET_ITEM(pArgs, 0)) ||
550535 PyDict_SetItemString(pDictInput, "reply", PyTuple_GET_ITEM(pArgs, 1)) ||
551536 PyDict_SetItemString(pDictInput, "config", PyTuple_GET_ITEM(pArgs, 2)) ||
552 PyDict_SetItemString(pDictInput, "session-state", PyTuple_GET_ITEM(pArgs, 3)) ||
537 PyDict_SetItemString(pDictInput, "session-state", PyTuple_GET_ITEM(pArgs, 3))
538 #ifdef WITH_PROXY
539 ||
553540 PyDict_SetItemString(pDictInput, "proxy-request", PyTuple_GET_ITEM(pArgs, 4)) ||
554 PyDict_SetItemString(pDictInput, "proxy-reply", PyTuple_GET_ITEM(pArgs, 5))) {
541 PyDict_SetItemString(pDictInput, "proxy-reply", PyTuple_GET_ITEM(pArgs, 5))
542 #endif
543 ) {
544
555545 ERROR("%s:%d, %s - PyDict_SetItemString failed", __func__, __LINE__, funcname);
556546 ret = RLM_MODULE_FAIL;
557547 goto finish;
818808 MOD_FUNC(preacct)
819809 MOD_FUNC(accounting)
820810 MOD_FUNC(checksimul)
811 #ifdef WITH_PROXY
821812 MOD_FUNC(pre_proxy)
822813 MOD_FUNC(post_proxy)
814 #endif
823815 MOD_FUNC(post_auth)
824816 #ifdef WITH_COA
825817 MOD_FUNC(recv_coa)
11011093 python_dlhandle = dlopen_libpython(RTLD_NOW | RTLD_GLOBAL);
11021094 if (!python_dlhandle) WARN("Failed loading libpython symbols into global symbol table");
11031095
1104 #if PY_VERSION_HEX > 0x03050000
1096 #if PY_VERSION_HEX >= 0x03050000
11051097 {
11061098 wchar_t *name;
11071099
11081100 MEM(name = Py_DecodeLocale(main_config.name, NULL));
11091101 Py_SetProgramName(name); /* The value of argv[0] as a wide char string */
11101102 PyMem_RawFree(name);
1111 }
1112 #elif PY_VERSION_HEX > 0x0300000
1113 {
1114 wchar_t *name;
1115
1116 MEM(name = _Py_char2wchar(main_config.name, NULL));
1117 Py_SetProgramName(inst->wide_name); /* The value of argv[0] as a wide char string */
11181103 }
11191104 #else
11201105 {
11621147 * the lifetime of the module.
11631148 */
11641149 if (inst->python_path) {
1150 char *p, *path;
1151 PyObject *sys = PyImport_ImportModule("sys");
1152 PyObject *sys_path = PyObject_GetAttrString(sys, "path");
1153
1154 memcpy(&p, &inst->python_path, sizeof(path));
1155
1156 for (path = strtok(p, ":"); path != NULL; path = strtok(NULL, ":")) {
11651157 #if PY_VERSION_HEX > 0x03050000
1166 {
1167 wchar_t *path;
1168 PyObject* sys = PyImport_ImportModule("sys");
1169 PyObject* sys_path = PyObject_GetAttrString(sys,"path");
1170
1171 MEM(path = Py_DecodeLocale(inst->python_path, NULL));
1172 PyList_Append(sys_path, PyUnicode_FromWideChar(path,-1));
1173 PyObject_SetAttrString(sys,"path",sys_path);
1174 PyMem_RawFree(path);
1158 wchar_t *py_path;
1159
1160 MEM(py_path = Py_DecodeLocale(path, NULL));
1161 PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
1162 PyMem_RawFree(py_path);
1163 #elif PY_VERSION_HEX > 0x03000000
1164 wchar_t *py_path;
1165
1166 MEM(py_path = _Py_char2wchar(path, NULL));
1167 PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
1168 PyMem_RawFree(py_path);
1169 #else
1170 PyList_Append(sys_path, PyLong_FromString(path));
1171 #endif
11751172 }
1176 #elif PY_VERSION_HEX > 0x03000000
1177 {
1178 wchar_t *path;
1179 PyObject* sys = PyImport_ImportModule("sys");
1180 PyObject* sys_path = PyObject_GetAttrString(sys,"path");
1181
1182 MEM(path = _Py_char2wchar(inst->python_path, NULL));
1183 PyList_Append(sys_path, PyUnicode_FromWideChar(path,-1));
1184 PyObject_SetAttrString(sys,"path",sys_path);
1185 }
1186 #else
1187 {
1188 char *path;
1189
1190 memcpy(&path, &inst->python_path, sizeof(path));
1191 Py_SetPath(path);
1192 }
1193 #endif
1194 }
1195
1173
1174 PyObject_SetAttrString(sys, "path", sys_path);
1175 Py_DecRef(sys);
1176 Py_DecRef(sys_path);
1177 }
11961178 } else {
11971179 inst->module = main_module;
11981180 Py_IncRef(inst->module);
12191201 static int mod_instantiate(CONF_SECTION *conf, void *instance)
12201202 {
12211203 rlm_python_t *inst = instance;
1222 int code = 0;
1204 int code = RLM_MODULE_OK;
12231205
12241206 inst->name = cf_section_name2(conf);
12251207 if (!inst->name) inst->name = cf_section_name1(conf);
12441226 PYTHON_FUNC_LOAD(preacct);
12451227 PYTHON_FUNC_LOAD(accounting);
12461228 PYTHON_FUNC_LOAD(checksimul);
1229 #ifdef WITH_PROXY
12471230 PYTHON_FUNC_LOAD(pre_proxy);
12481231 PYTHON_FUNC_LOAD(post_proxy);
1232 #endif
12491233 PYTHON_FUNC_LOAD(post_auth);
12501234 #ifdef WITH_COA
12511235 PYTHON_FUNC_LOAD(recv_coa);
12561240 /*
12571241 * Call the instantiate function.
12581242 */
1259 code = do_python_single(NULL, inst->instantiate.function, "instantiate", inst->pass_all_vps, inst->pass_all_vps_dict);
1260 if (code < 0) {
1261 error:
1262 python_error_log(); /* Needs valid thread with GIL */
1263 PyEval_SaveThread();
1264 return -1;
1243 if (inst->instantiate.function) {
1244 code = do_python_single(NULL, inst->instantiate.function, "instantiate", inst->pass_all_vps, inst->pass_all_vps_dict);
1245 if (code < 0) {
1246 error:
1247 python_error_log(); /* Needs valid thread with GIL */
1248 PyEval_SaveThread();
1249 return -1;
1250 }
12651251 }
12661252 PyEval_SaveThread();
12671253
12711257 static int mod_detach(void *instance)
12721258 {
12731259 rlm_python_t *inst = instance;
1274 int ret;
1260 int ret = RLM_MODULE_OK;
12751261
12761262 /*
12771263 * Call module destructor
12781264 */
12791265 PyEval_RestoreThread(inst->sub_interpreter);
12801266
1281 ret = do_python_single(NULL, inst->detach.function, "detach", inst->pass_all_vps, inst->pass_all_vps_dict);
1267 if (inst->detach.function) ret = do_python_single(NULL, inst->detach.function, "detach", inst->pass_all_vps, inst->pass_all_vps_dict);
12821268
12831269 #define PYTHON_FUNC_DESTROY(_x) python_function_destroy(&inst->_x)
12841270 PYTHON_FUNC_DESTROY(instantiate);
1271 PYTHON_FUNC_DESTROY(authenticate);
12851272 PYTHON_FUNC_DESTROY(authorize);
1286 PYTHON_FUNC_DESTROY(authenticate);
12871273 PYTHON_FUNC_DESTROY(preacct);
12881274 PYTHON_FUNC_DESTROY(accounting);
12891275 PYTHON_FUNC_DESTROY(checksimul);
1276 #ifdef WITH_PROXY
1277 PYTHON_FUNC_DESTROY(pre_proxy);
1278 PYTHON_FUNC_DESTROY(post_proxy);
1279 #endif
1280 PYTHON_FUNC_DESTROY(post_auth);
1281 #ifdef WITH_COA
1282 PYTHON_FUNC_DESTROY(recv_coa);
1283 PYTHON_FUNC_DESTROY(send_coa);
1284 #endif
12901285 PYTHON_FUNC_DESTROY(detach);
12911286
12921287 Py_DecRef(inst->pythonconf_dict);
13121307 PyThreadState_Swap(main_interpreter); /* Swap to the main thread */
13131308 Py_Finalize();
13141309 dlclose(python_dlhandle);
1315
1316 #if PY_VERSION_HEX > 0x03050000
1317 //if (inst->wide_name) PyMem_RawFree(inst->wide_name);
1318 //if (inst->wide_path) PyMem_RawFree(inst->wide_path);
1319 #endif
1320 }
1321
1310 }
13221311
13231312 return ret;
13241313 }
13471336 [MOD_PREACCT] = mod_preacct,
13481337 [MOD_ACCOUNTING] = mod_accounting,
13491338 [MOD_SESSION] = mod_checksimul,
1339 #ifdef WITH_PROXY
13501340 [MOD_PRE_PROXY] = mod_pre_proxy,
13511341 [MOD_POST_PROXY] = mod_post_proxy,
1342 #endif
13521343 [MOD_POST_AUTH] = mod_post_auth,
13531344 #ifdef WITH_COA
13541345 [MOD_RECV_COA] = mod_recv_coa,
499499 static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
500500 {
501501 rlm_sql_freetds_conn_t *conn = handle->conn;
502 int num;
503
504 if (ct_res_info(conn->command, CS_ROW_COUNT, (CS_INT *)&num, CS_UNUSED, NULL) != CS_SUCCEED) {
502 CS_INT num;
503
504 if (ct_res_info(conn->command, CS_ROW_COUNT, &num, CS_UNUSED, NULL) != CS_SUCCEED) {
505505 ERROR("rlm_sql_freetds: error retrieving row count");
506506
507507 return RLM_SQL_ERROR;
303303 char const *query)
304304 {
305305 rlm_sql_postgres_conn_t *conn = handle->conn;
306 struct timeval timeout = {config->query_timeout, 0};
307 int sockfd, r;
308 fd_set read_fd;
306 struct timeval start;
307 int sockfd;
309308 ExecStatusType status;
310309 int numfields = 0;
311310 PGresult *tmp_result;
330329 * We try to avoid blocking by waiting until the driver indicates that
331330 * the result is ready or our timeout expires
332331 */
332 gettimeofday(&start, NULL);
333333 while (PQisBusy(conn->db)) {
334 int r;
335 fd_set read_fd;
336 struct timeval when, elapsed, wake;
337
334338 FD_ZERO(&read_fd);
335339 FD_SET(sockfd, &read_fd);
336 r = select(sockfd + 1, &read_fd, NULL, NULL, config->query_timeout ? &timeout : NULL);
340
341 if (config->query_timeout) {
342 gettimeofday(&when, NULL);
343 rad_tv_sub(&when, &start, &elapsed);
344 if (elapsed.tv_sec >= config->query_timeout) goto too_long;
345
346 when.tv_sec = config->query_timeout;
347 when.tv_usec = 0;
348 rad_tv_sub(&when, &elapsed, &wake);
349 }
350
351 r = select(sockfd + 1, &read_fd, NULL, NULL, config->query_timeout ? &wake : NULL);
337352 if (r == 0) {
353 too_long:
338354 ERROR("rlm_sql_postgresql: Socket read timeout after %d seconds", config->query_timeout);
339355 return RLM_SQL_RECONNECT;
340356 }
160160 conn->row = talloc_zero_array(conn, char *, colcount + 1); /* Space for pointers */
161161
162162 for (i = 1; i <= colcount; i++) {
163 SQLColAttributes(conn->stmt, ((SQLUSMALLINT) i), SQL_COLUMN_LENGTH, NULL, 0, NULL, &len);
163 len = 0;
164 SQLColAttributes(conn->stmt, ((SQLUSMALLINT) i), SQL_DESC_LENGTH, NULL, 0, NULL, &len);
164165 conn->row[i - 1] = talloc_array(conn->row, char, ++len);
165166 SQLBindCol(conn->stmt, i, SQL_C_CHAR, (SQLCHAR *)conn->row[i - 1], len, NULL);
166167 }
22 if ('${feature.regex-pcre}' == 'yes') {
33 update request {
44 Tmp-Integer-0 := '123456789'
5 Tmp-Integer-1 := 1
6 }
7
8 # Check failures when no previous capture
9 if ("%{regex:}" != "") {
10 update reply {
11 Filter-Id += 'Fail 0.1'
12 }
13 }
14
15 if ("%{regex:foo}" != "") {
16 update reply {
17 Filter-Id += 'Fail 0.2'
18 }
19 }
20
21 if ("%{regex:%{Tmp-Integer-1}}" != "") {
22 update reply {
23 Filter-Id += 'Fail 0.3'
24 }
25 }
26
27 if ("%{regex:1}" != "") {
28 update reply {
29 Filter-Id += 'Fail 0.4'
30 }
531 }
632
733 # uncompiled - ref - named capture groups
00 Name: freeradius-server
1 Version: 3.0.20
1 Version: 3.0.21
22 Release: 0
33 License: GPLv2 ; LGPLv2.1
44 Group: Productivity/Networking/Radius/Servers