`REST-HTTP-Code` is now inserted into the `&request:` list instead of the `&reply:`
list, to be compliant with the [list usage](http://wiki.freeradius.org/contributing/List-Usage) guidelines.
+### rlm_sql
+
+Driver-specific options have moved from `mods-available/sql` to
+`mods-config/sql/driver/<drivername>`.
+
+#### rlm_sql_mysql
+
+Now calls `mysql_real_escape_string` and no longer produces
+`=<hexit><hexit>` escape sequences in expanded values.
+The `safe_characters` config item will have no effect when used with
+this driver.
+
+#### rlm_sql_postgresql
+
+Now calls `PQescapeStringConn` and no longer produces `=<hexit><hexit>`
+escape sequences in expanded values. The `safe_characters` config item will
+have no effect when used with this driver.
+
### rlm_sqlcounter
-### Attribute references
+Attribute references:
The following config items must now be defined as attribute references::
newer features in the server such as CoA, where reply_name can now be
`&coa:Session-Timeout`.
-### rlm_sql
+### rlm_sqlippool
-Driver-specific options have moved from `mods-available/sql` to
-`mods-config/sql/driver/<drivername>`.
+The `ipv6` configuration item has been deleted. It was deprecated in
+3.0.16.
-#### rlm_sql_mysql
-
-Now calls `mysql_real_escape_string` and no longer produces
-`=<hexit><hexit>` escape sequences in expanded values.
-The `safe_characters` config item will have no effect when used with
-this driver.
-
-#### rlm_sql_postgresql
-
-Now calls `PQescapeStringConn` and no longer produces `=<hexit><hexit>`
-escape sequences in expanded values. The `safe_characters` config item will
-have no effect when used with this driver.
+Instead, use `attribute-name`. See raddb/mods-available/sqlippool for
+more information.
## Deleted Modules
# IP lease duration. (Leases expire even if Acct Stop packet is lost)
lease_duration = 3600
- # protocol to use. The default is IPv4.
-# ipv6 = yes
+ # Attribute to use for querying / updating IP addresses.
+ # It MUST be a type which contains IP addresses.
+ # e.g. ipaddr, ipv4prefix, ipv6addr, or ipv6prefix
+ #
+ attribute_name = Framed-IP-Address
# Attribute which should be considered unique per NAS
#
# which writes Module-Success-Message message.
#
messages {
- exists = "Existing IP: %{reply:Framed-IP-Address} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+ exists = "Existing IP: %{reply:${..attribute_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
- success = "Allocated IP: %{reply:Framed-IP-Address} from %{control:Pool-Name} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+ success = "Allocated IP: %{reply:${..attribute_name}} from %{control:Pool-Name} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
- clear = "Released IP %{Framed-IP-Address} (did %{Called-Station-Id} cli %{Calling-Station-Id} user %{User-Name})"
+ clear = "Released IP %{${..attribute_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} user %{User-Name})"
failed = "IP Allocation FAILED from %{control:Pool-Name} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
#
# sqlippool (rlm_sqlippool) is called in the postauth section to allocate an IP address:
#
-# * If Framed-IP-Address already set, do nothing (return noop)
+# * If ${attribute_name} already set, do nothing (return noop)
# * If no Pool-Name defined, do nothing (return noop)
# * Run allocate_clear (if defined, runs at most once/second) to clean stale pool entries
# * Don't define this if you want users to keep old addresses after outages
# allocate_update is the final IP Allocation query, which saves the
# allocated IP details, officially allocating the IP address to the user.
#
-# WARNING: "WHERE framedipaddress = '%I'" MUST use %I instead of %{Framed-IP-Address}
-# (because Framed-IP-Address hasn't been set yet, that's what we're in the
+# WARNING: "WHERE framedipaddress = '%I'" MUST use %I instead of %{${attribute_name}}
+# (because ${attribute_name} hasn't been set yet, that's what we're in the
# process of doing)
#
allocate_update = "\
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# stop_clear frees an IP address when an accounting STOP record arrives.
# AND pool_key = '${pool_key}' \
# AND username = '%{User-Name}' \
# AND callingstationid = '%{Calling-Station-Id}' \
-# AND framedipaddress = '%{Framed-IP-Address}'"
+# AND framedipaddress = '%{${attribute_name}}'"
stop_clear = "\
UPDATE ${ippool_table} \
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# alive_update updates allocation info when an accounting ALIVE (Interim-Update)
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# on_clear clears the IP addresses allocated to a NAS when
expiry_time = current_timestamp + INTERVAL '${lease_duration}' second(1) \
WHERE nasipaddress = '%{Nas-IP-Address}' \
AND pool_key = '${pool_key}' \
- AND framedipaddress = '%{Framed-IP-Address}' \
+ AND framedipaddress = '%{${attribute_name}}' \
AND username = '%{SQL-User-Name}' \
AND callingstationid = '%{Calling-Station-Id}'"
AND pool_key = '${pool_key}' \
AND username = '%{SQL-User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# This query extends an IP address lease by "lease_duration" when an accounting
expiry_time = 'now'::timestamp(0) + '${lease_duration} seconds'::interval \
WHERE nasipaddress = '%{Nas-IP-Address}' \
AND pool_key = '${pool_key}' \
- AND framedipaddress = '%{Framed-IP-Address}' \
+ AND framedipaddress = '%{${attribute_name}}' \
AND username = '%{SQL-User-Name}' \
AND callingstationid = '%{Calling-Station-Id}'"
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# This series of queries frees an IP number when an accounting STOP record arrives
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# This series of queries frees an IP number when an accounting
AND pool_key = '${pool_key}' \
AND username = '%{User-Name}' \
AND callingstationid = '%{Calling-Station-Id}' \
- AND framedipaddress = '%{Framed-IP-Address}'"
+ AND framedipaddress = '%{${attribute_name}}'"
#
# This series of queries frees the IP numbers allocate to a
rlm_sql_t const *sql_inst;
char const *pool_name;
- bool ipv6; //!< Whether or not we do IPv6 pools.
- int framed_ip_address; //!< the attribute number for Framed-IP(v6)-Address
+ fr_dict_attr_t const *framed_ip_address; //!< the attribute for IP address allocation
+ char const *attribute_name; //!< name of the IP address attribute
time_t last_clear; //!< So we only do it once a second.
char const *allocate_begin; //!< SQL query to begin.
{ FR_CONF_OFFSET("pool_name", FR_TYPE_STRING, rlm_sqlippool_t, pool_name), .dflt = "" },
- { FR_CONF_OFFSET("default_pool", FR_TYPE_STRING, rlm_sqlippool_t, defaultpool), .dflt = "main_pool" },
+ { FR_CONF_OFFSET("attribute_name", FR_TYPE_STRING | FR_TYPE_REQUIRED | FR_TYPE_NOT_EMPTY, rlm_sqlippool_t, attribute_name), .dflt = "Framed-IP-Address" },
+ { FR_CONF_OFFSET("default_pool", FR_TYPE_STRING, rlm_sqlippool_t, defaultpool), .dflt = "main_pool" },
- { FR_CONF_OFFSET("ipv6", FR_TYPE_BOOL, rlm_sqlippool_t, ipv6) },
{ FR_CONF_OFFSET("allocate_begin", FR_TYPE_STRING | FR_TYPE_XLAT, rlm_sqlippool_t, allocate_begin), .dflt = "START TRANSACTION" },
return -1;
}
- if (!inst->ipv6) {
- inst->framed_ip_address = FR_FRAMED_IP_ADDRESS;
- } else {
- inst->framed_ip_address = FR_FRAMED_IPV6_PREFIX;
+ inst->framed_ip_address = fr_dict_attr_by_name(NULL, inst->attribute_name);
+ if (!inst->framed_ip_address) {
+ cf_log_err(conf, "Unknown attribute '%s'", inst->attribute_name);
+ return -1;
+ }
+
+ switch (inst->framed_ip_address->type) {
+ default:
+ cf_log_err(conf, "Cannot use non-IP attributes for 'attribute_name = %s'", inst->attribute_name);
+ return -1;
+
+ case FR_TYPE_IPV4_ADDR:
+ case FR_TYPE_IPV4_PREFIX:
+ case FR_TYPE_IPV6_ADDR:
+ case FR_TYPE_IPV6_PREFIX:
+ break;
}
inst->sql_inst = (rlm_sql_t *) sql_inst->dl_inst->data;
/*
* If there is a Framed-IP-Address attribute in the reply do nothing
*/
- if (fr_pair_find_by_num(request->reply->vps, 0, inst->framed_ip_address, TAG_ANY) != NULL) {
+ if (fr_pair_find_by_da(request->reply->vps, inst->framed_ip_address, TAG_ANY) != NULL) {
RDEBUG("Framed-IP-Address already exists");
return do_logging(request, inst->log_exists, RLM_MODULE_NOOP);
* See if we can create the VP from the returned data. If not,
* error out. If so, add it to the list.
*/
- vp = fr_pair_afrom_num(request->reply, 0, inst->framed_ip_address);
+ vp = fr_pair_afrom_da(request->reply, inst->framed_ip_address);
if (fr_pair_value_from_str(vp, allocation, allocation_len) < 0) {
DO_PART(allocate_commit);