From: Alan T. DeKok Date: Tue, 14 Nov 2017 20:16:43 +0000 (-0500) Subject: make IP address assignment generic X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7ddefcaebb414ed9bf5db43f6f74a5a874e77d4;p=thirdparty%2Ffreeradius-server.git make IP address assignment generic --- diff --git a/raddb/README.md b/raddb/README.md index 78cd50acea1..a486eb296a9 100644 --- a/raddb/README.md +++ b/raddb/README.md @@ -459,9 +459,27 @@ data, instead of as hex strings. `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/`. + +#### rlm_sql_mysql + +Now calls `mysql_real_escape_string` and no longer produces +`=` 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 `=` +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:: @@ -494,23 +512,13 @@ This allows significantly greater flexibility, and better integration with 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/`. +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 -`=` 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 `=` -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 diff --git a/raddb/mods-available/sqlippool b/raddb/mods-available/sqlippool index b32b77aa4ca..ce273b561ff 100644 --- a/raddb/mods-available/sqlippool +++ b/raddb/mods-available/sqlippool @@ -24,8 +24,11 @@ sqlippool { # 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 # @@ -53,11 +56,11 @@ sqlippool { # 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})" diff --git a/raddb/mods-config/sql/ippool/mysql/queries.conf b/raddb/mods-config/sql/ippool/mysql/queries.conf index 2fe7f172e06..451ac5cfb1c 100644 --- a/raddb/mods-config/sql/ippool/mysql/queries.conf +++ b/raddb/mods-config/sql/ippool/mysql/queries.conf @@ -6,7 +6,7 @@ # # 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 @@ -122,8 +122,8 @@ pool_check = "\ # 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 = "\ @@ -146,7 +146,7 @@ start_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. @@ -164,7 +164,7 @@ start_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 = "\ UPDATE ${ippool_table} \ @@ -178,7 +178,7 @@ stop_clear = "\ 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) @@ -192,7 +192,7 @@ alive_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 diff --git a/raddb/mods-config/sql/ippool/oracle/queries.conf b/raddb/mods-config/sql/ippool/oracle/queries.conf index 06d37f8985f..ad74651578d 100644 --- a/raddb/mods-config/sql/ippool/oracle/queries.conf +++ b/raddb/mods-config/sql/ippool/oracle/queries.conf @@ -131,7 +131,7 @@ alive_update = "\ 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}'" diff --git a/raddb/mods-config/sql/ippool/postgresql/queries.conf b/raddb/mods-config/sql/ippool/postgresql/queries.conf index 38465e829f6..b08bcd7af66 100644 --- a/raddb/mods-config/sql/ippool/postgresql/queries.conf +++ b/raddb/mods-config/sql/ippool/postgresql/queries.conf @@ -103,7 +103,7 @@ stop_clear = "\ 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 @@ -115,7 +115,7 @@ alive_update = "\ 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}'" diff --git a/raddb/mods-config/sql/ippool/sqlite/queries.conf b/raddb/mods-config/sql/ippool/sqlite/queries.conf index e912bd32a74..86f801abe6d 100644 --- a/raddb/mods-config/sql/ippool/sqlite/queries.conf +++ b/raddb/mods-config/sql/ippool/sqlite/queries.conf @@ -99,7 +99,7 @@ start_update = "\ 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 @@ -116,7 +116,7 @@ stop_clear = "\ 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 @@ -130,7 +130,7 @@ alive_update = "\ 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 diff --git a/src/modules/rlm_sqlippool/rlm_sqlippool.c b/src/modules/rlm_sqlippool/rlm_sqlippool.c index e3980f94dab..bdc0f8b1844 100644 --- a/src/modules/rlm_sqlippool/rlm_sqlippool.c +++ b/src/modules/rlm_sqlippool/rlm_sqlippool.c @@ -47,8 +47,8 @@ typedef struct rlm_sqlippool_t { 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. @@ -112,10 +112,10 @@ static CONF_PARSER module_config[] = { { 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" }, @@ -391,10 +391,22 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) 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; @@ -446,7 +458,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, UNUSED void *t /* * 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); @@ -547,7 +559,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, UNUSED void *t * 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);