From: Nick Porter Date: Fri, 19 Jan 2024 16:35:35 +0000 (+0000) Subject: Add initial call_env to sqlippool X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3bdebdfb661172d06962acf11457657f05ebb84;p=thirdparty%2Ffreeradius-server.git Add initial call_env to sqlippool Just for allocated_address_attr to start with --- diff --git a/raddb/mods-available/sqlippool b/raddb/mods-available/sqlippool index e86293c4f84..d82642e8332 100644 --- a/raddb/mods-available/sqlippool +++ b/raddb/mods-available/sqlippool @@ -58,7 +58,7 @@ sqlippool { # # e.g. `ipaddr`, `ipv4prefix,` `ipv6addr`, or `ipv6prefix`. # ==== - allocated_address_attr = radius.Framed-IP-Address + allocated_address_attr = &reply.Framed-IP-Address # # owner:: Expansion which identifies the owner of the lease. diff --git a/raddb/mods-config/sql/ippool/mssql/queries.conf b/raddb/mods-config/sql/ippool/mssql/queries.conf index 5f1078aeb41..208871b8721 100644 --- a/raddb/mods-config/sql/ippool/mssql/queries.conf +++ b/raddb/mods-config/sql/ippool/mssql/queries.conf @@ -156,7 +156,7 @@ pool_check = "\ # SET \ # gateway = '${gateway}', owner = '${owner}', \ # expiry_time = DATEADD(SECOND,${offer_duration},CURRENT_TIMESTAMP) \ -# WHERE address = '%{reply.${allocated_address_attr}}' \ +# WHERE address = '%{${allocated_address_attr}}' \ # AND pool_name = '%{control.${pool_name}}'" # diff --git a/raddb/mods-config/sql/ippool/mysql/queries.conf b/raddb/mods-config/sql/ippool/mysql/queries.conf index 75a76a0abd0..016e1196c05 100644 --- a/raddb/mods-config/sql/ippool/mysql/queries.conf +++ b/raddb/mods-config/sql/ippool/mysql/queries.conf @@ -119,7 +119,7 @@ alloc_update = "\ SET \ gateway = '${gateway}', owner = '${owner}', \ expiry_time = NOW() + INTERVAL ${offer_duration} SECOND \ - WHERE address = '%{reply.${allocated_address_attr}}' \ + WHERE address = '%{${allocated_address_attr}}' \ AND pool_name = '%{control.${pool_name}}'" # diff --git a/raddb/mods-config/sql/ippool/oracle/queries.conf b/raddb/mods-config/sql/ippool/oracle/queries.conf index 60397978b89..cc02ac5385b 100644 --- a/raddb/mods-config/sql/ippool/oracle/queries.conf +++ b/raddb/mods-config/sql/ippool/oracle/queries.conf @@ -108,7 +108,7 @@ pool_check = "\ # gateway = '${gateway}', \ # owner = '${owner}', \ # expiry_time = current_timestamp + INTERVAL '${offer_duration}' second(1) \ -# WHERE address = '%{reply.${allocated_address_attr}}' \ +# WHERE address = '%{${allocated_address_attr}}' \ # AND pool_name = '%{control.${pool_name}}'" diff --git a/raddb/mods-config/sql/ippool/postgresql/queries.conf b/raddb/mods-config/sql/ippool/postgresql/queries.conf index 6935da23af7..9c5ec0d8d44 100644 --- a/raddb/mods-config/sql/ippool/postgresql/queries.conf +++ b/raddb/mods-config/sql/ippool/postgresql/queries.conf @@ -112,7 +112,7 @@ alloc_find = "\ # gateway = '${gateway}', \ # owner = '${owner}', \ # expiry_time = 'now'::timestamp(0) + '${offer_duration} second'::interval \ -# WHERE address = '%{reply.${allocated_address_attr}}' \ +# WHERE address = '%{${allocated_address_attr}}' \ # AND pool_name = '%{control.${pool_name}}'" # diff --git a/raddb/mods-config/sql/ippool/sqlite/queries.conf b/raddb/mods-config/sql/ippool/sqlite/queries.conf index a412c02990d..7d59eb63d22 100644 --- a/raddb/mods-config/sql/ippool/sqlite/queries.conf +++ b/raddb/mods-config/sql/ippool/sqlite/queries.conf @@ -104,7 +104,7 @@ alloc_update = "\ gateway = '${gateway}', \ owner = '${owner}', \ expiry_time = datetime(strftime('%%s', 'now') + ${offer_duration}, 'unixepoch') \ - WHERE address = '%{reply.${allocated_address_attr}}' \ + WHERE address = '%{${allocated_address_attr}}' \ AND pool_name = '%{control.${pool_name}}'" diff --git a/src/modules/rlm_sqlippool/rlm_sqlippool.c b/src/modules/rlm_sqlippool/rlm_sqlippool.c index a08370ac73e..afd429d50a4 100644 --- a/src/modules/rlm_sqlippool/rlm_sqlippool.c +++ b/src/modules/rlm_sqlippool/rlm_sqlippool.c @@ -42,8 +42,6 @@ typedef struct { rlm_sql_t const *sql; - fr_dict_attr_t const *allocated_address_da; //!< the attribute for IP address allocation - char const *allocated_address_attr; //!< name of the IP address attribute tmpl_t *requested_address; //!< name of the requested IP address attribute /* Alloc sequence */ @@ -73,8 +71,6 @@ typedef struct { static conf_parser_t module_config[] = { { FR_CONF_OFFSET("sql_module_instance", rlm_sqlippool_t, sql_name), .dflt = "sql" }, - { FR_CONF_OFFSET_FLAGS("allocated_address_attr", CONF_FLAG_REQUIRED | CONF_FLAG_NOT_EMPTY, rlm_sqlippool_t, allocated_address_attr) }, - { FR_CONF_OFFSET("requested_address", rlm_sqlippool_t, requested_address) }, @@ -279,25 +275,6 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) return -1; } - inst->allocated_address_da = fr_dict_attr_search_by_qualified_oid(NULL, dict_freeradius, - inst->allocated_address_attr, false, false); - if (!inst->allocated_address_da) { - cf_log_perr(conf, "Failed resolving attribute"); - return -1; - } - - switch (inst->allocated_address_da->type) { - default: - cf_log_err(conf, "Cannot use non-IP attributes for 'allocated_address_attr = %s'", inst->allocated_address_attr); - return -1; - - case FR_TYPE_IPV4_ADDR: - case FR_TYPE_IPV4_PREFIX: - case FR_TYPE_IPV6_ADDR: - case FR_TYPE_IPV6_PREFIX: - break; - } - if (inst->requested_address) { if (!tmpl_is_xlat(inst->requested_address)) { cf_log_err(conf, "requested_address must be a double quoted expansion, not %s", @@ -322,21 +299,23 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) static unlang_action_t CC_HINT(nonnull) mod_alloc(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) { rlm_sqlippool_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_sqlippool_t); + ippool_alloc_call_env_t *env = talloc_get_type_abort(mctx->env_data, ippool_alloc_call_env_t); char allocation[FR_MAX_STRING_LEN]; int allocation_len; - fr_pair_t *vp = NULL; rlm_sql_handle_t *handle; + tmpl_t ip_rhs; + map_t ip_map; /* - * If there is a Framed-IP-Address attribute in the reply do nothing + * If the allocated IP attribute already exists, do nothing */ - if (fr_pair_find_by_da(&request->reply_pairs, NULL, inst->allocated_address_da) != NULL) { - RDEBUG2("%s already exists", inst->allocated_address_da->name); + if (env->allocated_address.type) { + RDEBUG2("%s already exists (%pV)", env->allocated_address_attr->name, &env->allocated_address); RETURN_MODULE_NOOP; } - if (fr_pair_find_by_da(&request->control_pairs, NULL, attr_pool_name) == NULL) { + if (fr_pair_find_by_da_nested(&request->control_pairs, NULL, attr_pool_name) == NULL) { RDEBUG2("No %s defined", attr_pool_name->name); RETURN_MODULE_NOOP; @@ -446,11 +425,17 @@ static unlang_action_t CC_HINT(nonnull) mod_alloc(rlm_rcode_t *p_result, module_ * See if we can create the VP from the returned data. If not, * error out. If so, add it to the list. */ - MEM(vp = fr_pair_afrom_da(request->reply_ctx, inst->allocated_address_da)); - if (fr_pair_value_from_str(vp, allocation, allocation_len, NULL, true) < 0) { + ip_map = (map_t) { + .lhs = env->allocated_address_attr, + .op = T_OP_SET, + .rhs = &ip_rhs + }; + + tmpl_init_shallow(&ip_rhs, TMPL_TYPE_DATA, T_BARE_WORD, "", 0, NULL); + fr_value_box_bstrndup_shallow(&ip_map.rhs->data.literal, NULL, allocation, allocation_len, false); + if (map_to_request(request, &ip_map, map_to_vp, NULL) < 0) { DO_PART(alloc_commit); - talloc_free(vp); RDEBUG2("Invalid IP address [%s] returned from database query.", allocation); fr_pool_connection_release(inst->sql->pool, request, handle); RETURN_MODULE_NOOP; @@ -461,7 +446,6 @@ static unlang_action_t CC_HINT(nonnull) mod_alloc(rlm_rcode_t *p_result, module_ */ if (sqlippool_command(inst->alloc_update, &handle, inst, request) < 0) { error: - talloc_free(vp); if (handle) fr_pool_connection_release(inst->sql->pool, request, handle); RETURN_MODULE_FAIL; } @@ -469,7 +453,6 @@ static unlang_action_t CC_HINT(nonnull) mod_alloc(rlm_rcode_t *p_result, module_ DO_PART(alloc_commit); RDEBUG2("Allocated IP %s", allocation); - fr_pair_append(&request->reply_pairs, vp); if (handle) fr_pool_connection_release(inst->sql->pool, request, handle); @@ -578,6 +561,16 @@ static unlang_action_t CC_HINT(nonnull) mod_mark(rlm_rcode_t *p_result, module_c RETURN_MODULE_FAIL; } +static const call_env_method_t sqlippool_alloc_method_env = { + FR_CALL_ENV_METHOD_OUT(ippool_alloc_call_env_t), + .env = (call_env_parser_t[]) { + { FR_CALL_ENV_PARSE_OFFSET("allocated_address_attr", FR_TYPE_VOID, + CALL_ENV_FLAG_ATTRIBUTE | CALL_ENV_FLAG_REQUIRED | CALL_ENV_FLAG_NULLABLE, + ippool_alloc_call_env_t, allocated_address, allocated_address_attr) }, + CALL_ENV_TERMINATOR + } +}; + /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. @@ -602,7 +595,8 @@ module_rlm_t rlm_sqlippool = { /* * RADIUS specific */ - { .name1 = "recv", .name2 = "access-request", .method = mod_alloc }, + { .name1 = "recv", .name2 = "access-request", .method = mod_alloc, + .method_env = &sqlippool_alloc_method_env }, { .name1 = "accounting", .name2 = "start", .method = mod_update }, { .name1 = "accounting", .name2 = "alive", .method = mod_update }, { .name1 = "accounting", .name2 = "stop", .method = mod_release }, @@ -612,7 +606,8 @@ module_rlm_t rlm_sqlippool = { /* * DHCPv4 */ - { .name1 = "recv", .name2 = "Discover", .method = mod_alloc }, + { .name1 = "recv", .name2 = "Discover", .method = mod_alloc, + .method_env = &sqlippool_alloc_method_env }, { .name1 = "recv", .name2 = "Request", .method = mod_update }, { .name1 = "recv", .name2 = "Confirm", .method = mod_update }, { .name1 = "recv", .name2 = "Rebind", .method = mod_update }, @@ -624,12 +619,14 @@ module_rlm_t rlm_sqlippool = { * Generic */ { .name1 = "recv", .name2 = CF_IDENT_ANY, .method = mod_update }, - { .name1 = "send", .name2 = CF_IDENT_ANY, .method = mod_alloc }, + { .name1 = "send", .name2 = CF_IDENT_ANY, .method = mod_alloc, + .method_env = &sqlippool_alloc_method_env }, /* * Named methods matching module operations */ - { .name1 = "allocate", .name2 = CF_IDENT_ANY, .method = mod_alloc }, + { .name1 = "allocate", .name2 = CF_IDENT_ANY, .method = mod_alloc, + .method_env = &sqlippool_alloc_method_env }, { .name1 = "update", .name2 = CF_IDENT_ANY, .method = mod_update }, { .name1 = "renew", .name2 = CF_IDENT_ANY, .method = mod_update }, { .name1 = "release", .name2 = CF_IDENT_ANY, .method = mod_release },