21 RCSID(
"$Id: 30ed97d6a3aa220bd7203269ba3b959a41e38592 $")
24 #define LOG_PREFIX "sql - unixodbc"
26 #include <freeradius-devel/server/base.h>
27 #include <freeradius-devel/util/debug.h>
52 DEBUG2(
"Socket destructor called, closing socket");
54 if (conn->
stmt) SQLFreeStmt(conn->
stmt, SQL_DROP);
57 SQLDisconnect(conn->
dbc);
58 SQLFreeConnect(conn->
dbc);
61 if (conn->
env) SQLFreeEnv(conn->
env);
77 err_handle = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &conn->
env);
79 ERROR(
"Can't allocate environment handle");
83 err_handle = SQLSetEnvAttr(conn->
env, SQL_ATTR_ODBC_VERSION, (
void*)SQL_OV_ODBC3, 0);
85 ERROR(
"Can't register ODBC version");
90 err_handle = SQLAllocHandle(SQL_HANDLE_DBC, conn->
env, &conn->
dbc);
92 ERROR(
"Can't allocate connection handle");
97 SQLSetConnectAttr(conn->
dbc, SQL_ATTR_LOGIN_TIMEOUT, &timeout_ms, SQL_IS_UINTEGER);
100 err_handle = SQLConnect(conn->
dbc,
106 ERROR(
"Connection failed");
111 err_handle = SQLAllocHandle(SQL_HANDLE_STMT, conn->
dbc, &conn->
stmt);
113 ERROR(
"Can't allocate the stmt");
127 err_handle = SQLExecDirect(conn->
stmt,
UNCONST(SQLCHAR *, query), strlen(query));
130 DEBUG(
"rlm_sql will attempt to reconnect");
156 conn->
row = talloc_zero_array(conn,
char *, colcount + 1);
158 for (i = 1; i <= colcount; i++) {
160 SQLColAttributes(conn->
stmt, ((SQLUSMALLINT) i), SQL_DESC_LENGTH, NULL, 0, NULL, &len);
161 conn->
row[i - 1] = talloc_array(conn->
row,
char, ++len);
162 SQLBindCol(conn->
stmt, i, SQL_C_CHAR, (SQLCHAR *)conn->
row[i - 1], len, NULL);
172 SQLSMALLINT num_fields = 0;
174 err_handle = SQLNumResultCols(conn->
stmt,&num_fields);
184 SQLSMALLINT fields, len, i;
189 SQLNumResultCols(conn->
stmt, &fields);
192 MEM(
names = talloc_array(handle,
char const *, fields));
194 for (i = 0; i < fields; i++) {
197 switch (SQLColAttribute(conn->
stmt, i, SQL_DESC_BASE_COLUMN_NAME,
198 field,
sizeof(field), &len, NULL)) {
199 case SQL_INVALID_HANDLE:
201 ERROR(
"Failed retrieving field name at index %i", i);
209 MEM(p = talloc_array(
names,
char, (
size_t)len + 1));
210 strlcpy(p, field, (
size_t)len + 1);
228 err_handle = SQLFetch(conn->
stmt);
256 SQLFreeStmt(conn->
stmt, SQL_CLOSE);
265 SQLFreeStmt(conn->
stmt, SQL_CLOSE);
274 TALLOC_FREE(conn->
row);
295 SQLCHAR errbuff[256];
296 SQLINTEGER errnum = 0;
297 SQLSMALLINT length = 255;
301 errbuff[0] = state[0] =
'\0';
302 SQLError(conn->
env, conn->
dbc, conn->
stmt, state, &errnum,
303 errbuff,
sizeof(errbuff), &length);
304 if (errnum == 0)
return 0;
326 SQLINTEGER errornum = 0;
327 SQLSMALLINT length = 255;
332 if (SQL_SUCCEEDED(error_handle))
return 0;
334 error[0] = state[0] =
'\0';
336 SQLError(conn->
env, conn->
dbc, conn->
stmt, state, &errornum,
337 error,
sizeof(error), &length);
339 if (state[0] ==
'0') {
343 INFO(
"%s %s", state, error);
351 ERROR(
"SQL down %s %s", state, error);
357 ERROR(
"%s %s", state, error);
362 ERROR(
"%s %s", state, error);
394 .name =
"sql_unixodbc"
#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[]
Prototypes and functions for the SQL module.
void * conn
Database specific connection handle.
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_row_t row
Row data from the last query.
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_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_fetch_row(rlm_sql_row_t *out, rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static int _sql_socket_destructor(rlm_sql_unixodbc_conn_t *conn)
static sql_rcode_t sql_finish_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
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, rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
Retrieves any errors associated with the connection handle.
static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static USES_APPLE_DEPRECATED_API int sql_check_error(long err_handle, rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
static sql_rcode_t sql_finish_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, char const *query)
static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
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