From: Nick Porter Date: Thu, 2 May 2024 08:00:52 +0000 (+0100) Subject: Change function signature of SQL driver query functions to unlang_function_t X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a40443c5fab60465084fcd78ee53600a0685c48;p=thirdparty%2Ffreeradius-server.git Change function signature of SQL driver query functions to unlang_function_t --- diff --git a/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c b/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c index f335b8676c2..eeb6f959689 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c @@ -432,16 +432,17 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co return RLM_SQL_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_cassandra_conn_t *conn = handle->conn; - rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_cassandra_t); + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_cassandra_conn_t *conn = query_ctx->handle->conn; + rlm_sql_cassandra_t *inst = talloc_get_type_abort(query_ctx->handle->inst->driver_submodule->data, rlm_sql_cassandra_t); CassStatement *statement; CassFuture *future; CassError ret; - statement = cass_statement_new_n(query, talloc_array_length(query) - 1, 0); + statement = cass_statement_new_n(query_ctx->query_str, talloc_array_length(query_ctx->query_str) - 1, 0); if (inst->consistency_str) cass_statement_set_consistency(statement, inst->consistency); future = cass_session_execute(inst->session, statement); @@ -459,17 +460,20 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c switch (ret) { case CASS_ERROR_SERVER_SYNTAX_ERROR: case CASS_ERROR_SERVER_INVALID_QUERY: - return RLM_SQL_QUERY_INVALID; + query_ctx->rcode = RLM_SQL_QUERY_INVALID; + RETURN_MODULE_INVALID; default: - return RLM_SQL_ERROR; + query_ctx->rcode = RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } conn->result = cass_future_get_result(future); cass_future_free(future); - return RLM_SQL_OK; + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) diff --git a/src/modules/rlm_sql/drivers/rlm_sql_db2/rlm_sql_db2.c b/src/modules/rlm_sql/drivers/rlm_sql_db2/rlm_sql_db2.c index 688968c1e10..629aae4b5ef 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_db2/rlm_sql_db2.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_db2/rlm_sql_db2.c @@ -106,12 +106,13 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co return RLM_SQL_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx) { + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); SQLRETURN row; rlm_sql_db2_conn_t *conn; - conn = handle->conn; + conn = query_ctx->handle->conn; /* allocate handle for statement */ SQLAllocHandle(SQL_HANDLE_STMT, conn->dbc_handle, &(conn->stmt)); @@ -119,22 +120,19 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c /* execute query */ { SQLCHAR *db2_query; - memcpy(&db2_query, &query, sizeof(query)); + memcpy(&db2_query, &query_ctx->query_str, sizeof(query_ctx->query_str)); row = SQLExecDirect(conn->stmt, db2_query, SQL_NTS); if(row != SQL_SUCCESS) { /* XXX Check if row means we should return RLM_SQL_RECONNECT */ ERROR("Could not execute statement \"%s\"", query); - return RLM_SQL_ERROR; + query_ctx->rcode = RLM_SQL_ERROR; + RETURN_MODULE_FAIL } } - return RLM_SQL_OK; -} - -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) -{ - return sql_query(handle, config, query); + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) @@ -291,7 +289,7 @@ rlm_sql_driver_t rlm_sql_db2 = { }, .sql_socket_init = sql_socket_init, .sql_query = sql_query, - .sql_select_query = sql_select_query, + .sql_select_query = sql_query, .sql_num_fields = sql_num_fields, .sql_affected_rows = sql_affected_rows, .sql_fields = sql_fields, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c index bb33f1018e3..a18a3c36353 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c @@ -89,12 +89,13 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co return 0; } -/** Issue a non-SELECT query (ie: update/delete/insert) to the database. +/** Issue a query to the database. * */ -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_firebird_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_firebird_conn_t *conn = query_ctx->handle->conn; int deadlock = 0; @@ -105,11 +106,11 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c * Try again query when deadlock, because in any case it * will be retried. */ - if (fb_sql_query(conn, query)) { + if (fb_sql_query(conn, query_ctx->query_str)) { /* but may be lost for short sessions */ if ((conn->sql_code == DEADLOCK_SQL_CODE) && !deadlock) { - DEBUG("conn_id deadlock. Retry query %s", query); + DEBUG("conn_id deadlock. Retry query %s", query_ctx->query_str); /* * @todo For non READ_COMMITED transactions put @@ -121,12 +122,13 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c } ERROR("conn_id rlm_sql_firebird,sql_query error: sql_code=%li, error='%s', query=%s", - (long int) conn->sql_code, conn->error, query); + (long int) conn->sql_code, conn->error, query_ctx->query_str); if (conn->sql_code == DOWN_SQL_CODE) { pthread_mutex_unlock(&conn->mut); - return RLM_SQL_RECONNECT; + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } /* Free problem query */ @@ -134,28 +136,26 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c //assume the network is down if rollback had failed ERROR("Fail to rollback transaction after previous error: %s", conn->error); - return RLM_SQL_RECONNECT; + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } // conn->in_use=0; - return RLM_SQL_ERROR; + query_ctx->rcode = RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } if (conn->statement_type != isc_info_sql_stmt_select) { - if (fb_commit(conn)) return RLM_SQL_ERROR; /* fb_commit unlocks the mutex */ + if (fb_commit(conn)) { + query_ctx->rcode = RLM_SQL_ERROR; /* fb_commit unlocks the mutex */ + RETURN_MODULE_FAIL; + } } else { pthread_mutex_unlock(&conn->mut); } - return 0; -} - -/** Issue a select query to the database. - * - */ -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) -{ - return sql_query(handle, config, query); + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } /** Returns number of columns from query. @@ -298,7 +298,7 @@ rlm_sql_driver_t rlm_sql_firebird = { }, .sql_socket_init = sql_socket_init, .sql_query = sql_query, - .sql_select_query = sql_select_query, + .sql_select_query = sql_query, .sql_num_fields = sql_num_fields, .sql_num_rows = sql_num_rows, .sql_affected_rows = sql_affected_rows, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c b/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c index 2154e0e6233..49635452057 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_freetds/rlm_sql_freetds.c @@ -192,13 +192,16 @@ static CS_RETCODE CS_PUBLIC servermsg_callback(CS_CONTEXT *context, UNUSED CS_CO * the database. * *************************************************************************/ -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_freetds_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_freetds_conn_t *conn = query_ctx->handle->conn; CS_RETCODE results_ret; CS_INT result_type; + query_ctx->rcode = RLM_SQL_ERROR; + /* * Reset rows_affected in case the query fails. * Prevents accidentally returning the rows_affected from a previous query. @@ -208,19 +211,19 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) { ERROR("Unable to allocate command structure (ct_cmd_alloc())"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } - if (ct_command(conn->command, CS_LANG_CMD, query, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) { + if (ct_command(conn->command, CS_LANG_CMD, query_ctx->query_str, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) { ERROR("Unable to initialise command structure (ct_command())"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } if (ct_send(conn->command) != CS_SUCCEED) { ERROR("Unable to send command (ct_send())"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } /* @@ -239,7 +242,7 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c } ERROR("Result failure or unexpected result type from query"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } else { switch (results_ret) { @@ -248,16 +251,17 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) { INFO("Cleaning up"); - - return RLM_SQL_RECONNECT; + reconnect: + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } conn->command = NULL; - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; default: ERROR("Unexpected return value from ct_results()"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } @@ -269,7 +273,7 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c if (ct_res_info(conn->command, CS_ROW_COUNT, &conn->rows_affected, CS_UNUSED, NULL) != CS_SUCCEED) { ERROR("rlm_sql_freetds: error retrieving row count"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } /* @@ -280,21 +284,21 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c if (result_type != CS_CMD_DONE) { ERROR("Result failure or unexpected result type from query"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } else { switch (results_ret) { case CS_FAIL: /* Serious failure, freetds requires us to cancel and maybe even close db */ ERROR("Failure retrieving query results"); - if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) return RLM_SQL_RECONNECT; + if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) goto reconnect; conn->command = NULL; - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; default: ERROR("Unexpected return value from ct_results()"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } @@ -305,10 +309,10 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c switch (results_ret) { case CS_FAIL: /* Serious failure, freetds requires us to cancel and maybe even close db */ ERROR("Failure retrieving query results"); - if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) return RLM_SQL_RECONNECT; + if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) goto reconnect; conn->command = NULL; - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; case CS_END_RESULTS: /* This is where we want to end up */ break; @@ -316,10 +320,11 @@ static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t c default: ERROR("Unexpected return value from ct_results()"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } - return RLM_SQL_OK; + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } /************************************************************************* @@ -446,9 +451,10 @@ static sql_rcode_t sql_finish_select_query(rlm_sql_handle_t *handle, UNUSED rlm_ * consecutive rows will be discarded. * */ -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_freetds_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_freetds_conn_t *conn = query_ctx->handle->conn; CS_RETCODE results_ret; CS_INT result_type; @@ -457,27 +463,29 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c int colcount,i; char **rowdata; + query_ctx->rcode = RLM_SQL_ERROR; + if (!conn->db) { ERROR("socket not connected"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } if (ct_cmd_alloc(conn->db, &conn->command) != CS_SUCCEED) { ERROR("unable to allocate command structure (ct_cmd_alloc())"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } - if (ct_command(conn->command, CS_LANG_CMD, query, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) { + if (ct_command(conn->command, CS_LANG_CMD, query_ctx->query_str, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) { ERROR("unable to initiate command structure (ct_command()"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } if (ct_send(conn->command) != CS_SUCCEED) { ERROR("unable to send command (ct_send())"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } results_ret = ct_results(conn->command, &result_type); @@ -504,7 +512,7 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c descriptor.count = 1; /* Fetch one row of data */ descriptor.locale = NULL; /* Don't do NLS stuff */ - colcount = sql_num_fields(handle, config); /* Get number of elements in row result */ + colcount = sql_num_fields(query_ctx->handle, &query_ctx->inst->config); /* Get number of elements in row result */ rowdata = talloc_zero_array(conn, char *, colcount + 1); /* Space for pointers */ rowdata[colcount] = NULL; @@ -519,7 +527,7 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c ERROR("ct_bind() failed)"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } } @@ -536,9 +544,9 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c default: ERROR("unexpected result type from query"); - sql_finish_select_query(handle, config); + sql_finish_select_query(query_ctx->handle, &query_ctx->inst->config); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } break; @@ -553,19 +561,21 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c if (ct_cancel(NULL, conn->command, CS_CANCEL_ALL) == CS_FAIL) { ERROR("cleaning up"); - return RLM_SQL_RECONNECT; + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } conn->command = NULL; - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; default: ERROR("unexpected return value from ct_results()"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } - return RLM_SQL_OK; + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) @@ -691,6 +701,8 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co { rlm_sql_freetds_conn_t *conn; unsigned int timeout_ms = fr_time_delta_to_msec(timeout); + fr_sql_query_t *query_ctx; + rlm_rcode_t p_result; MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_freetds_conn_t)); talloc_set_destructor(conn, _sql_socket_destructor); @@ -792,11 +804,12 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co * sql statement when we first open the connection. */ snprintf(database, sizeof(database), "USE %s;", config->sql_db); - if (sql_query(handle, config, database) != RLM_SQL_OK) { + MEM(query_ctx = fr_sql_query_alloc(NULL, handle->inst, handle, database, SQL_QUERY_OTHER)); + if ((sql_query(&p_result, NULL, NULL, query_ctx) == UNLANG_ACTION_CALCULATE_RESULT) && + (query_ctx->rcode != RLM_SQL_OK)) { goto error; } - - sql_finish_query(handle, config); + talloc_free(query_ctx); } return RLM_SQL_OK; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c index 691b06b3d92..6c369304d9d 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c @@ -387,21 +387,21 @@ static sql_rcode_t sql_check_error(MYSQL *server, int client_errno) return RLM_SQL_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_mysql_conn_t *conn = talloc_get_type_abort(handle->conn, rlm_sql_mysql_conn_t); - sql_rcode_t rcode; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_mysql_conn_t *conn = talloc_get_type_abort(query_ctx->handle->conn, rlm_sql_mysql_conn_t); char const *info; - mysql_query(conn->sock, query); - rcode = sql_check_error(conn->sock, 0); - if (rcode != RLM_SQL_OK) return rcode; + mysql_query(conn->sock, query_ctx->query_str); + query_ctx->rcode = sql_check_error(conn->sock, 0); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; /* Only returns non-null string for INSERTS */ info = mysql_info(conn->sock); if (info) DEBUG2("%s", info); - return RLM_SQL_OK; + RETURN_MODULE_OK; } static sql_rcode_t sql_store_result(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) @@ -435,14 +435,16 @@ static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t cons return mysql_field_count(conn->sock); } -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx) { - sql_rcode_t rcode; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); - rcode = sql_query(handle, config, query); - if (rcode != RLM_SQL_OK) return rcode; + sql_query(p_result, NULL, request, query_ctx); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; - return sql_store_result(handle, config); + query_ctx->rcode = sql_store_result(query_ctx->handle, &query_ctx->inst->config); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; + RETURN_MODULE_OK; } static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) diff --git a/src/modules/rlm_sql/drivers/rlm_sql_null/rlm_sql_null.c b/src/modules/rlm_sql/drivers/rlm_sql_null/rlm_sql_null.c index 20d869ab321..369f1dc65b0 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_null/rlm_sql_null.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_null/rlm_sql_null.c @@ -36,10 +36,11 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, UNUSED rlm_sql_conf return 0; } -static sql_rcode_t sql_query(UNUSED rlm_sql_handle_t * handle, - UNUSED rlm_sql_config_t const *config, UNUSED char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - return 0; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; } static int sql_num_fields(UNUSED rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t const *config) @@ -47,12 +48,6 @@ static int sql_num_fields(UNUSED rlm_sql_handle_t * handle, UNUSED rlm_sql_confi return 0; } -static sql_rcode_t sql_select_query(UNUSED rlm_sql_handle_t *handle, - UNUSED rlm_sql_config_t const *config, UNUSED char const *query) -{ - return 0; -} - static int sql_num_rows(UNUSED rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t const *config) { return 0; @@ -103,7 +98,7 @@ rlm_sql_driver_t rlm_sql_null = { }, .sql_socket_init = sql_socket_init, .sql_query = sql_query, - .sql_select_query = sql_select_query, + .sql_select_query = sql_query, .sql_num_fields = sql_num_fields, .sql_num_rows = sql_num_rows, .sql_fetch_row = sql_fetch_row, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c index aa4a7463a14..f676888e4fb 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c @@ -361,41 +361,49 @@ static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, rlm_ return RLM_SQL_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); int status; - rlm_sql_oracle_conn_t *conn = handle->conn; + rlm_sql_oracle_conn_t *conn = query_ctx->handle->conn; if (!conn->ctx) { ERROR("Socket not connected"); - return RLM_SQL_RECONNECT; + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } - if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query, strlen(query), + query_ctx->rcode = RLM_SQL_ERROR; + + if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query_ctx->query_str, strlen(query_ctx->query_str), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)) { ERROR("prepare failed in sql_query"); - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } status = OCIStmtExecute(conn->ctx, conn->query, conn->error, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS); - if (status == OCI_SUCCESS) return RLM_SQL_OK; + if (status == OCI_SUCCESS) { + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; + } if (status == OCI_ERROR) { ERROR("execute query failed in sql_query"); - return sql_check_reconnect(handle, config); + query_ctx->rcode = sql_check_reconnect(query_ctx->handle, &query_ctx->inst->config); } - return RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); int status; - char **row; + char **row = NULL; int i; OCIParam *param; @@ -406,24 +414,25 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c sb2 *ind; - rlm_sql_oracle_conn_t *conn = handle->conn; + rlm_sql_oracle_conn_t *conn = query_ctx->handle->conn; - if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query, strlen(query), + if (OCIStmtPrepare2(conn->ctx, &conn->query, conn->error, (const OraText *)query_ctx->query_str, strlen(query_ctx->query_str), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)) { ERROR("prepare failed in sql_select_query"); - return RLM_SQL_ERROR; + goto error; } /* * Retrieve a single row */ status = OCIStmtExecute(conn->ctx, conn->query, conn->error, 0, 0, NULL, NULL, OCI_DEFAULT); - if (status == OCI_NO_DATA) return RLM_SQL_OK; + if (status == OCI_NO_DATA) goto finish; if (status != OCI_SUCCESS) { ERROR("query failed in sql_select_query"); - return sql_check_reconnect(handle, config); + query_ctx->rcode = sql_check_reconnect(query_ctx->handle, &query_ctx->inst->config); + RETURN_MODULE_FAIL; } /* @@ -431,9 +440,9 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c * the number of columns won't change. */ if (conn->col_count == 0) { - conn->col_count = sql_num_fields(handle, config); + conn->col_count = sql_num_fields(query_ctx->handle, &query_ctx->inst->config); - if (conn->col_count == 0) return RLM_SQL_ERROR; + if (conn->col_count == 0) goto error; } MEM(row = talloc_zero_array(conn, char*, conn->col_count + 1)); @@ -515,12 +524,15 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c conn->row = row; conn->ind = ind; - return RLM_SQL_OK; +finish: + query_ctx->rcode = RLM_SQL_OK; + RETURN_MODULE_OK; error: talloc_free(row); - return RLM_SQL_ERROR; + query_ctx->rcode = RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c index b51e288a317..076c36a3bf0 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c @@ -261,12 +261,12 @@ static int CC_HINT(nonnull) sql_socket_init(rlm_sql_handle_t *handle, UNUSED rlm return 0; } -static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, - char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_postgres_conn_t *conn = handle->conn; - rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_postgresql_t); - fr_time_delta_t timeout = config->query_timeout; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_postgres_conn_t *conn = query_ctx->handle->conn; + rlm_sql_postgresql_t *inst = talloc_get_type_abort(query_ctx->inst->driver_submodule->data, rlm_sql_postgresql_t); + fr_time_delta_t timeout = query_ctx->inst->config.query_timeout; fr_time_t start; int sockfd; PGresult *tmp_result; @@ -275,18 +275,20 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ if (!conn->db) { ERROR("Socket not connected"); - return RLM_SQL_RECONNECT; + reconnect: + query_ctx->rcode = RLM_SQL_RECONNECT; + RETURN_MODULE_FAIL; } sockfd = PQsocket(conn->db); if (sockfd < 0) { ERROR("Unable to obtain socket: %s", PQerrorMessage(conn->db)); - return RLM_SQL_RECONNECT; + goto reconnect; } - if (!PQsendQuery(conn->db, query)) { + if (!PQsendQuery(conn->db, query_ctx->query_str)) { ERROR("Failed to send query: %s", PQerrorMessage(conn->db)); - return RLM_SQL_RECONNECT; + goto reconnect; } /* @@ -302,26 +304,26 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ FD_ZERO(&read_fd); FD_SET(sockfd, &read_fd); - if (fr_time_delta_ispos(config->query_timeout)) { + if (fr_time_delta_ispos(timeout)) { elapsed = fr_time_sub(fr_time(), start); if (fr_time_delta_gteq(elapsed, timeout)) goto too_long; } - r = select(sockfd + 1, &read_fd, NULL, NULL, fr_time_delta_ispos(config->query_timeout) ? + r = select(sockfd + 1, &read_fd, NULL, NULL, fr_time_delta_ispos(timeout) ? &fr_time_delta_to_timeval(fr_time_delta_sub(timeout, elapsed)) : NULL); if (r == 0) { too_long: - ERROR("Socket read timeout after %d seconds", (int) fr_time_delta_to_sec(config->query_timeout)); - return RLM_SQL_RECONNECT; + ERROR("Socket read timeout after %d seconds", (int) fr_time_delta_to_sec(timeout)); + goto reconnect; } if (r < 0) { if (errno == EINTR) continue; ERROR("Failed in select: %s", fr_syserror(errno)); - return RLM_SQL_RECONNECT; + goto reconnect; } if (!PQconsumeInput(conn->db)) { ERROR("Failed reading input: %s", PQerrorMessage(conn->db)); - return RLM_SQL_RECONNECT; + goto reconnect; } } @@ -346,7 +348,7 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ */ if (!conn->result) { ERROR("Failed getting query result: %s", PQerrorMessage(conn->db)); - return RLM_SQL_RECONNECT; + goto reconnect; } status = PQresultStatus(conn->result); @@ -397,12 +399,9 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ break; } - return sql_classify_error(inst, status, conn->result); -} - -static sql_rcode_t sql_select_query(rlm_sql_handle_t * handle, rlm_sql_config_t const *config, char const *query) -{ - return sql_query(handle, config, query); + query_ctx->rcode = sql_classify_error(inst, status, conn->result); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; + RETURN_MODULE_OK; } static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) @@ -679,7 +678,7 @@ rlm_sql_driver_t rlm_sql_postgresql = { .flags = RLM_SQL_RCODE_FLAGS_ALT_QUERY, .sql_socket_init = sql_socket_init, .sql_query = sql_query, - .sql_select_query = sql_select_query, + .sql_select_query = sql_query, .sql_num_fields = sql_num_fields, .sql_fields = sql_fields, .sql_fetch_row = sql_fetch_row, diff --git a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c index 9c2cf19f5c0..f8e06ac54bb 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c @@ -452,42 +452,46 @@ static sql_rcode_t CC_HINT(nonnull) sql_socket_init(rlm_sql_handle_t *handle, rl return RLM_SQL_OK; } -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_sqlite_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_sqlite_conn_t *conn = query_ctx->handle->conn; char const *z_tail; int status; #ifdef HAVE_SQLITE3_PREPARE_V2 - status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail); + status = sqlite3_prepare_v2(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail); #else - status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail); + status = sqlite3_prepare(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail); #endif conn->col_count = 0; - return sql_check_error(conn->db, status); + query_ctx->rcode = sql_check_error(conn->db, status); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; + RETURN_MODULE_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - - sql_rcode_t rcode; - rlm_sql_sqlite_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_sqlite_conn_t *conn = query_ctx->handle->conn; char const *z_tail; int status; #ifdef HAVE_SQLITE3_PREPARE_V2 - status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail); + status = sqlite3_prepare_v2(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail); #else - status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail); + status = sqlite3_prepare(conn->db, query_ctx->query_str, strlen(query_ctx->query_str), &conn->statement, &z_tail); #endif - rcode = sql_check_error(conn->db, status); - if (rcode != RLM_SQL_OK) return rcode; + query_ctx->rcode = sql_check_error(conn->db, status); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; status = sqlite3_step(conn->statement); - return sql_check_error(conn->db, status); + query_ctx->rcode = sql_check_error(conn->db, status); + if (query_ctx->rcode != RLM_SQL_OK) RETURN_MODULE_FAIL; + RETURN_MODULE_OK; } static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config) diff --git a/src/modules/rlm_sql/drivers/rlm_sql_unixodbc/rlm_sql_unixodbc.c b/src/modules/rlm_sql/drivers/rlm_sql_unixodbc/rlm_sql_unixodbc.c index b8bdcbf1136..3e9003afadd 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_unixodbc/rlm_sql_unixodbc.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_unixodbc/rlm_sql_unixodbc.c @@ -117,39 +117,39 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co return RLM_SQL_OK; } -static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_unixodbc_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_unixodbc_conn_t *conn = query_ctx->handle->conn; long err_handle; - int state; /* Executing query */ - err_handle = SQLExecDirect(conn->stmt, UNCONST(SQLCHAR *, query), strlen(query)); - if ((state = sql_check_error(err_handle, handle, config))) { - if(state == RLM_SQL_RECONNECT) { + err_handle = SQLExecDirect(conn->stmt, UNCONST(SQLCHAR *, query_ctx->query_str), strlen(query_ctx->query_str)); + if ((query_ctx->rcode = sql_check_error(err_handle, query_ctx->handle, &query_ctx->inst->config))) { + if(query_ctx->rcode == RLM_SQL_RECONNECT) { DEBUG("rlm_sql will attempt to reconnect"); } - return state; + RETURN_MODULE_FAIL; } - return 0; + RETURN_MODULE_OK; } -static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query) +static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { - rlm_sql_unixodbc_conn_t *conn = handle->conn; + fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); + rlm_sql_unixodbc_conn_t *conn = query_ctx->handle->conn; SQLINTEGER i; SQLLEN len; int colcount; - int state; /* Only state = 0 means success */ - if ((state = sql_query(handle, config, query))) { - return state; - } + if ((sql_query(p_result, NULL, request, query_ctx) == UNLANG_ACTION_CALCULATE_RESULT) && + (query_ctx->rcode != RLM_SQL_OK)) RETURN_MODULE_FAIL; - colcount = sql_num_fields(handle, config); + colcount = sql_num_fields(query_ctx->handle, &query_ctx->inst->config); if (colcount < 0) { - return RLM_SQL_ERROR; + query_ctx->rcode = RLM_SQL_ERROR; + RETURN_MODULE_FAIL; } /* Reserving memory for result */ @@ -162,7 +162,7 @@ static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t c SQLBindCol(conn->stmt, i, SQL_C_CHAR, (SQLCHAR *)conn->row[i - 1], len, NULL); } - return RLM_SQL_OK; + RETURN_MODULE_OK; } static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t const *config) diff --git a/src/modules/rlm_sql/rlm_sql.h b/src/modules/rlm_sql/rlm_sql.h index c74c0203795..66a8a3b87a7 100644 --- a/src/modules/rlm_sql/rlm_sql.h +++ b/src/modules/rlm_sql/rlm_sql.h @@ -176,8 +176,8 @@ typedef struct { sql_rcode_t (*sql_socket_init)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, fr_time_delta_t timeout); - sql_rcode_t (*sql_query)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query); - sql_rcode_t (*sql_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query); + unlang_function_t sql_query; + unlang_function_t sql_select_query; sql_rcode_t (*sql_store_result)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config); int (*sql_num_fields)(rlm_sql_handle_t *handle, rlm_sql_config_t const *config); diff --git a/src/modules/rlm_sql/sql.c b/src/modules/rlm_sql/sql.c index 4631f14224b..9ee03861fe5 100644 --- a/src/modules/rlm_sql/sql.c +++ b/src/modules/rlm_sql/sql.c @@ -462,7 +462,7 @@ unlang_action_t rlm_sql_query(rlm_rcode_t *p_result, UNUSED int *priority, reque for (i = 0; i < (count + 1); i++) { ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query_ctx->query_str); - query_ctx->rcode = (inst->driver->sql_query)(query_ctx->handle, &inst->config, query_ctx->query_str); + (inst->driver->sql_query)(p_result, NULL, request, query_ctx); query_ctx->status = SQL_QUERY_SUBMITTED; switch (query_ctx->rcode) { case RLM_SQL_OK: @@ -569,7 +569,7 @@ unlang_action_t rlm_sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority for (i = 0; i < (count + 1); i++) { ROPTIONAL(RDEBUG2, DEBUG2, "Executing select query: %s", query_ctx->query_str); - query_ctx->rcode = (inst->driver->sql_select_query)(query_ctx->handle, &inst->config, query_ctx->query_str); + (inst->driver->sql_select_query)(p_result, NULL, request, query_ctx); query_ctx->status = SQL_QUERY_SUBMITTED; switch (query_ctx->rcode) { case RLM_SQL_OK: