21 RCSID(
"$Id: abae1800a7c68616febf6a29e227169c35e34ed0 $")
24 #define LOG_PREFIX "sql - unixodbc"
26 #include <freeradius-devel/server/base.h>
27 #include <freeradius-devel/util/debug.h>
51 DEBUG2(
"Socket destructor called, closing socket");
53 if (conn->
stmt) SQLFreeStmt(conn->
stmt, SQL_DROP);
56 SQLDisconnect(conn->
dbc);
57 SQLFreeConnect(conn->
dbc);
60 if (conn->
env) SQLFreeEnv(conn->
env);
76 err_handle = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &conn->
env);
78 ERROR(
"Can't allocate environment handle");
82 err_handle = SQLSetEnvAttr(conn->
env, SQL_ATTR_ODBC_VERSION, (
void*)SQL_OV_ODBC3, 0);
84 ERROR(
"Can't register ODBC version");
89 err_handle = SQLAllocHandle(SQL_HANDLE_DBC, conn->
env, &conn->
dbc);
91 ERROR(
"Can't allocate connection handle");
96 SQLSetConnectAttr(conn->
dbc, SQL_ATTR_LOGIN_TIMEOUT, &timeout_ms, SQL_IS_UINTEGER);
99 err_handle = SQLConnect(conn->
dbc,
105 ERROR(
"Connection failed");
110 err_handle = SQLAllocHandle(SQL_HANDLE_STMT, conn->
dbc, &conn->
stmt);
112 ERROR(
"Can't allocate the stmt");
129 DEBUG(
"rlm_sql will attempt to reconnect");
155 conn->
row = talloc_zero_array(conn,
char *, colcount + 1);
157 for (i = 1; i <= colcount; i++) {
159 SQLColAttributes(conn->
stmt, ((SQLUSMALLINT) i), SQL_DESC_LENGTH, NULL, 0, NULL, &len);
160 conn->
row[i - 1] = talloc_array(conn->
row,
char, ++len);
161 SQLBindCol(conn->
stmt, i, SQL_C_CHAR, (SQLCHAR *)conn->
row[i - 1], len, NULL);
171 SQLSMALLINT num_fields = 0;
173 err_handle = SQLNumResultCols(conn->
stmt,&num_fields);
183 SQLSMALLINT fields, len, i;
188 SQLNumResultCols(conn->
stmt, &fields);
191 MEM(
names = talloc_array(query_ctx,
char const *, fields));
193 for (i = 0; i < fields; i++) {
196 switch (SQLColAttribute(conn->
stmt, i, SQL_DESC_BASE_COLUMN_NAME,
197 field,
sizeof(field), &len, NULL)) {
198 case SQL_INVALID_HANDLE:
200 ERROR(
"Failed retrieving field name at index %i", i);
208 MEM(p = talloc_array(
names,
char, (
size_t)len + 1));
209 strlcpy(p, field, (
size_t)len + 1);
224 query_ctx->
row = NULL;
226 err_handle = SQLFetch(conn->
stmt);
227 if (err_handle == SQL_NO_DATA_FOUND) {
235 query_ctx->
row = conn->
row;
259 SQLFreeStmt(conn->
stmt, SQL_CLOSE);
268 SQLFreeStmt(conn->
stmt, SQL_CLOSE);
277 TALLOC_FREE(conn->
row);
298 SQLCHAR errbuff[256];
299 SQLINTEGER errnum = 0;
300 SQLSMALLINT length = 255;
304 errbuff[0] = state[0] =
'\0';
305 SQLError(conn->
env, conn->
dbc, conn->
stmt, state, &errnum,
306 errbuff,
sizeof(errbuff), &length);
307 if (errnum == 0)
return 0;
329 SQLINTEGER errornum = 0;
330 SQLSMALLINT length = 255;
335 if (SQL_SUCCEEDED(error_handle))
return 0;
337 error[0] = state[0] =
'\0';
339 SQLError(conn->
env, conn->
dbc, conn->
stmt, state, &errornum,
340 error,
sizeof(error), &length);
342 if (state[0] ==
'0') {
346 INFO(
"%s %s", state, error);
354 ERROR(
"SQL down %s %s", state, error);
360 ERROR(
"%s %s", state, error);
365 ERROR(
"%s %s", state, error);
397 .name =
"sql_unixodbc"
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define USES_APPLE_DEPRECATED_API
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
static fr_time_delta_t timeout
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static const conf_parser_t config[]
rlm_rcode_t
Return codes indicating the result of the module call.
Prototypes and functions for the SQL module.
void * conn
Database specific connection handle.
rlm_sql_t const * inst
Module instance for this query.
char const * query_str
Query string to run.
sql_rcode_t
Action to take at end of an SQL query.
@ RLM_SQL_RECONNECT
Stale connection, should reconnect.
@ RLM_SQL_ERROR
General connection/server error.
@ RLM_SQL_NO_MORE_ROWS
No more rows available.
rlm_sql_handle_t * handle
Connection handle this query is being run on.
rlm_sql_row_t row
Row data from the last query.
sql_rcode_t rcode
Result code.
static int affected_rows(PGresult *result)
Return the number of affected rows of the result as an int instead of the string that postgresql prov...
static sql_rcode_t sql_free_result(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config)
static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, fr_time_delta_t timeout)
rlm_sql_driver_t rlm_sql_unixodbc
static sql_rcode_t sql_fields(char const **out[], fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
static sql_rcode_t sql_finish_query(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
static sql_rcode_t sql_finish_select_query(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config)
static int sql_affected_rows(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config)
static unlang_action_t sql_fetch_row(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
static int _sql_socket_destructor(rlm_sql_unixodbc_conn_t *conn)
static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static size_t sql_error(TALLOC_CTX *ctx, sql_log_entry_t out[], NDEBUG_UNUSED size_t outlen, fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
Retrieves any errors associated with the query context.
static unlang_action_t sql_select_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
static USES_APPLE_DEPRECATED_API int sql_check_error(long err_handle, rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
size_t strlcpy(char *dst, char const *src, size_t siz)
module_t common
Common fields for all loadable modules.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
static const char * names[8]
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
A time delta, a difference in time measured in nanoseconds.
static size_t char ** out