The ‘raddb/sqlserver’ file configures the connection to SQL server.
The file uses simple line-oriented ‘keyword --- value’ format. Comments are introduced by ‘#’ character.
The ‘sqlserver’ statements can logically be subdivided into following groups: SQL Client Parameters, configuring the connection between SQL client and the server, Authentication Server Parameters, Authorization Parameters, and Accounting server parameters.
These parameters configure various aspects of connection between SQL client and the server.
interface iface-typeSpecifies the SQL interface to use. Currently supported values
for iface-type are mysql and postgres. Depending
on this, the default communication port number is set: it is 3306 for
interface mysql and 5432 for interface postgres. Use of
this statement is only meaningful when the package was configured with
both ‘--with-mysql’ and ‘--with-postgres’ option.
server stringSpecifies the hostname or IP address of the SQL server.
port numberSets the SQL communication port number. It can be omitted if your server uses the default port.
login stringSets the SQL user login name.
password passwordSets the SQL user password.
keepopen boolSpecify whether radiusd should try to keep the connection open.
When set to no (the default), radiusd will open new connection
before the transaction and close it right after finishing it.
We recommend setting keepopen to yes for heavily loaded
servers, since opening the new connection can take a substantial amount
of time and slow down the operation considerably.
idle_timeout numberSet idle timeout in seconds for an open SQL connection. The connection is closed if it remains inactive longer that this amount of time.
(This message will disappear, once this node revised.)
These parameters configure the SQL authentication. The general syntax is:
doauth boolWhen set to yes, enables authentication via SQL. All auth_
keywords are ignored if doauth is set to no.
auth_db stringSpecifies the name of the database containing authentication information.
auth_query stringSpecifies the SQL query to be used to obtain user's password from the database. The query should return exactly one string value — the password.
group_query stringSpecifies the query that retrieves the list of user groups the user
belongs to. This query is used when Group or Group-Name
attribute appears in the LHS of a user's or hint's profile.
auth_success_query stringThis query is executed when an authentication succeeds. See section Controlling Authentication Probes, for the detailed discussion of its purpose.
auth_failure_query stringThis query is executed upon an authentication failure. See section Controlling Authentication Probes, for the detailed discussion of its purpose.
Let's suppose the authentication information is kept in the tables
passwd and groups.
The passwd table contains user passwords. A user is allowed
to have different passwords for different services. The table structure
is:
CREATE TABLE passwd ( user_name varchar(32) binary default '' not null, service char(16) default 'Framed-PPP' not null, password char(64) );
Additionally, the table groups contains information about
user groups a particular user belongs to. Its structure is:
CREATE TABLE groups ( user_name char(32) binary default '' not null, user_group char(32) );
The queries used to retrieve the information from these tables will then look like:
auth_query SELECT password
FROM passwd
WHERE user_name = '%C{User-Name}'
AND service = '%C{Auth-Data}'
group_query SELECT user_group
FROM groups
WHERE user_name = '%C{User-Name}'
It is supposed, that the information about the particular service a
user is wishing to obtain, will be kept in Auth-Data attribute
in LHS of a user's profile.
These parameters define queries used to retrieve the authorization information from the SQL database. All the queries refer to the authentication database.
check_attr_query stringThis query must return a list of triplets:
attr-name, attr-value, opcode
The query is executed before comparing the request with the profile entry. The values returned by the query are added to LHS of the entry. opcode here means one of valid operation codes: ‘=’, ‘!=’, ‘<’, ‘>’, ‘<=’, ‘>=’.
reply_attr_query stringThis query must return pairs:
attr-name, attr-value
The query is executed after a successful match, the values it returns are added to the RHS list of the matched entry, and are therefore returned to the NAS in the reply packet.
Suppose your attribute information is stored in a SQL table of the following structure:
CREATE TABLE attrib (
user_name varchar(32) default '' not null,
attr char(32) default '' not null,
value char(128),
op enum("=", "!=", "<", ">", "<=", ">=") default null
);
Each row of the table contains the attribute-value pair for a given
user. If op field is NULL, the row describes RHS
(reply) pair. Otherwise, it describes a LHS (check) pair. The
authorization queries for this table will look as follows:
check_attr_query SELECT attr,value,op \ FROM attrib \ WHERE user_name='%u' \ AND op IS NOT NULL reply_attr_query SELECT attr,value \ FROM attrib \ WHERE user_name='%u' \ AND op IS NULL
Now, let's suppose the ‘raddb/users’ contains only one entry:
DEFAULT Auth-Type = SQL Service-Type = Framed-User
And the attrib table contains following rows:
user_name
attr
value
op
jsmith
NAS-IP-Address
10.10.10.1
=
jsmith
NAS-Port-Id
20
<=
jsmith
Framed-Protocol
PPP
NULL
jsmith
Framed-IP-Address
10.10.10.11
NULL
Then, when the user jsmith is trying to authenticate, the
following happens:
DEFAULT) in the
‘raddb/users’.
check_attr_query. The
triplets it returns are then added to the LHS of the profile
entry. Thus, the LHS will contain:
Auth-Type = SQL, NAS-IP-Address = 10.10.10.1, NAS-Port-Id <= 20
Auth-Type attributes itself
triggers execution of auth_query, described in the previous
section.
reply_attr_query, and adds its return to the list
of RHS pairs. The RHS pairs will then be:
Service-Type = Framed-User, Framed-Protocol = PPP, Framed-IP-Address = 10.10.10.11
This list is returned to the NAS along with the authentication accept packet.
Thus, this configuration allows the user jsmith to use only
NAS 10.10.10.1, ports from 1 to 20 inclusive. If the user meets
these conditions, he is allowed to use PPP service, and is
assigned IP address 10.10.10.11.
To perform the SQL accounting radiusd needs to know the
database where it is to store the accounting information. This
information is supplied by the following statements:
doacct boolWhen set to yes enables SQL accounting. All acct_
keywords are ignored if doacct is set to no.
acct_db stringSpecifies the name of the database where the accounting information is to be stored.
Further, radiusd needs to know which information it is
to store into the database and when. Each of five accounting request
types (see section Accounting Requests) has a SQL query associated with
it. Thus, when radius receives an accounting request, it determines
the query to use by the value of Acct-Status-Type attribute.
Following statements define the accounting queries:
acct_start_query stringSpecifies the SQL query to be used when Session Start Packet
is received. Typically, this would be some INSERT statement
(see section Writing SQL Accounting Query Templates).
acct_stop_query stringSpecifies the SQL query to be used when Session Stop Packet
is received. Typically, this would be some UPDATE statement.
acct_stop_query stringSpecifies the SQL query to be executed upon arrival of a
Keepalive Packet. Typically, this would be some UPDATE statement.
acct_nasup_query stringSpecifies the SQL query to be used upon arrival of an Accounting Off Packet.
acct_nasdown_query stringSpecifies the SQL query to be used when a NAS sends Accounting On Packet.
None of these queries should return any values.
Three queries are designed for use by multiple login checking mechanism (see section Multiple Login Checking):
mlc_user_query stringA query retrieving a list of sessions currently opened by the given user.
mlc_realm_query stringA query to retrieve a list of sessions currently open for the given realm.
mlc_stop_query stringA query to mark given record as hung.
Let's suppose you have an accounting table of the following structure:
CREATE TABLE calls ( status int(3), user_name char(32), event_date_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, nas_ip_address char(17), nas_port_id int(6), acct_session_id char(16) DEFAULT '' NOT NULL, acct_session_time int(11), acct_input_octets int(11), acct_output_octets int(11), connect_term_reason int(4), framed_ip_address char(17), called_station_id char(32), calling_station_id char(32) );
On receiving the Session Start Packet we would insert a record into this
table with status set to 1. At this point the columns
acct_session_time, acct_input_octets,
acct_output_octets as well as connect_term_reason are
unknown, so we will set them to 0:
# Query to be used on session start
acct_start_query INSERT INTO calls \
VALUES(%C{Acct-Status-Type},\
'%u',\
'%G',\
'%C{NAS-IP-Address}',\
%C{NAS-Port-Id},\
'%C{Acct-Session-Id}',\
0,\
0,\
0,\
0,\
'%C{Framed-IP-Address}',\
'%C{Called-Station-Id}',\
'%C{Calling-Station-Id}')
Then, when the Session Stop Packet request arrives we will look up
the record having status = 1, user_name matching the
value of User-Name attribute, and acct_session_id matching
that of Acct-Session-Id attribute. Once the record is found,
we will update it, setting
status = 2 acct_session_time = value of Acct-Session-Time attribute acct_input_octets = value of Acct-Input-Octets attribute acct_output_octets = value of Acct-Output-Octets attribute connect_term_reason = value of Acct-Terminate-Cause attribute
Thus, every record with status = 1 will represent the active
session and every record with status = 2 will represent
the finished and correctly closed record. The constructed
acct_stop_query is then:
# Query to be used on session end
acct_stop_query UPDATE calls \
SET status=%C{Acct-Status-Type},\
acct_session_time=%C{Acct-Session-Time},\
acct_input_octets=%C{Acct-Input-Octets},\
acct_output_octets=%C{Acct-Output-Octets},\
connect_term_reason=%C{Acct-Terminate-Cause} \
WHERE user_name='%C{User-Name}' \
AND status = 1 \
AND acct_session_id='%C{Acct-Session-Id}'
Upon receiving a Keepalive Packet we will update the information
stored with acct_start_query:
acct_alive_query UPDATE calls \
SET acct_session_time=%C{Acct-Session-Time},\
acct_input_octets=%C{Acct-Input-Octets},\
acct_output_octets=%C{Acct-Output-Octets},\
framed_ip_address=%C{Framed-IP-Address} \
WHERE user_name='%C{User-Name}' \
AND status = 1 \
AND acct_session_id='%C{Acct-Session-Id}'
Further, there may be times when it is necessary to bring some NAS
down. To correctly close the currently active sessions on this NAS
we will define a acct_nasdown_query so that it would
set status column to 2 and update acct_session_time
in all records having status = 1 and
nas_ip_address equal to IP address of the NAS. Thus, all
sessions on a given NAS will be closed correctly when it brought
down. The acct_session_time can be computed as difference
between the current time and the time stored in event_date_time
column:
# Query to be used when a NAS goes down, i.e. when it sends
# Accounting-Off packet
acct_nasdown_query UPDATE calls \
SET status=2,\
acct_session_time=unix_timestamp(now())-\
unix_timestamp(event_date_time) \
WHERE status=1 \
AND nas_ip_address='%C{NAS-IP-Address}'
We have not covered only one case: when a NAS crashes, e.g. due to
a power failure. In this case it does not have a time to send
Accounting-Off request and all its records remain open. But when
the power supply is restored, the NAS will send an
Accounting On packet, so we define a acct_nasup_query to
set status column to 3 and update acct_session_time
in all open records belonging to this NAS. Thus we will know that
each record having status = 3 represents a crashed session.
The query constructed will be:
# Query to be used when a NAS goes up, i.e. when it sends
# Accounting-On packet
acct_nasup_query UPDATE calls \
SET status=3,\
acct_session_time=unix_timestamp(now())-\
unix_timestamp(event_date_time) \
WHERE status=1 \
AND nas_ip_address='%C{NAS-IP-Address}'
If you plan to use SQL database for multiple login checking (see section Multiple Login Checking), you will have to supply at least two additional queries for retrieving the information about currently active sessions for a given user and realm (see section Retrieving Session Data). Each of these queries must return a list consisting of 5-element tuples:
user-name, nas-ip-address, nas-port-id, acct-session-id
For example, in our setup these queries will be:
mlc_user_query SELECT user_name,nas_ip_address,\
nas_port_id,acct_session_id \
FROM calls \
WHERE user_name='%C{User-Name}' \
AND status = 1
mlc_realm_query SELECT user_name,nas_ip_address,\
nas_port_id,acct_session_id \
FROM calls \
WHERE realm_name='%C{Realm-Name}'
While performing multiple login checking radiusd will
eventually need to close hung records, i.e. such records that are
marked as open in the database (status=1, in our setup), but
are actually not active (See section Verifying Active Sessions, for the
description of why it may be necessary). It will by default use
acct_stop_query for that, but it has a drawback that hung
records will be marked as if they were closed correctly. This may not
be suitable for accounting purposes. The special query
mlc_stop_query is provided to override
acct_stop_query. If we mark hung records with status=4,
then the mlc_stop_query will look as follows:
mlc_stop_query UPDATE calls \
SET status=4,\
acct_session_time=unix_timestamp(now())-\
unix_timestamp(event_date_time) \
WHERE user_name='%C{User-Name}' \
AND status = 1 \
AND acct_session_id='%C{Acct-Session-Id}'
This document was generated by Sergey Poznyakoff on December, 6 2008 using texi2html 1.78.