25 RCSID(
"$Id: 3b5f663a6a4ed2ef31d270091af385da3a30a770 $")
27 #define LOG_PREFIX "sql - sqlite"
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/util/debug.h>
39 #define BOOTSTRAP_MAX (1048576 * 10)
44 #ifndef SQLITE_OPEN_NOMUTEX
45 # define SQLITE_OPEN_NOMUTEX 0
48 #ifndef HAVE_SQLITE3_INT64
83 switch (status & 0xff) {
103 case SQLITE_CONSTRAINT:
126 int hstatus = SQLITE_OK;
129 hstatus = sqlite3_errcode(db);
130 switch (hstatus & 0xff) {
142 switch (status & 0xff) {
176 int hstatus = SQLITE_OK;
179 hstatus = sqlite3_errcode(db);
180 switch (hstatus & 0xff) {
192 switch (status & 0xff) {
206 if ((hstatus == SQLITE_OK) && (status == SQLITE_OK))
return;
212 MEM(p = talloc_vasprintf(NULL,
fmt, ap));
219 if ((status != SQLITE_OK) && (status != hstatus)) {
220 #ifdef HAVE_SQLITE3_ERRSTR
221 ERROR(
"%s: Code 0x%04x (%i): %s", p, status, status, sqlite3_errstr(status));
223 ERROR(
"%s: Code 0x%04x (%i)", p, status, status);
227 if (hstatus != SQLITE_OK)
ERROR(
"%s: Code 0x%04x (%i): %s",
228 p, hstatus, hstatus, sqlite3_errmsg(db));
231 #ifdef HAVE_SQLITE3_OPEN_V2
232 static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db,
char const *filename)
235 int statement_len, statement_cnt = 0;
243 sqlite3_stmt *statement;
246 INFO(
"Executing SQL statements from file \"%s\"", filename);
248 f = fopen(filename,
"r");
250 ERROR(
"Failed opening SQL file \"%s\": %s", filename,
256 if (fstat(fileno(f), &finfo) < 0) {
257 ERROR(
"Failed stating SQL file \"%s\": %s", filename,
267 ERROR(
"Size of SQL (%zu) file exceeds limit (%uk)",
275 MEM(
buffer = talloc_array(ctx,
char, finfo.st_size + 1));
276 len = fread(
buffer,
sizeof(
char), finfo.st_size, f);
277 if (len > finfo.st_size) {
292 DEBUG(
"Ignoring empty SQL file");
308 if ((*p != 0x0a) && (*p != 0x0d) && (*p !=
'\t'))
break;
316 if ((p -
buffer) != len) {
317 ERROR(
"Bootstrap file contains non-UTF8 char at offset %zu", p -
buffer);
324 statement_len = len - (p -
buffer);
325 #ifdef HAVE_SQLITE3_PREPARE_V2
326 status = sqlite3_prepare_v2(db, p, statement_len, &statement, &z_tail);
328 status = sqlite3_prepare(db, p, statement_len, &statement, &z_tail);
332 sql_print_error(db, status,
"Failed preparing statement %i", statement_cnt);
340 if (!statement)
break;
342 status = sqlite3_step(statement);
344 sql_print_error(db, status,
"Failed executing statement %i", statement_cnt);
345 sqlite3_finalize(statement);
350 status = sqlite3_finalize(statement);
352 sql_print_error(db, status,
"Failed finalizing statement %i", statement_cnt);
370 DEBUG2(
"Socket destructor called, closing socket");
373 status = sqlite3_close(conn->
db);
374 if (status != SQLITE_OK)
WARN(
"Got SQLite error when closing socket: %s",
375 sqlite3_errmsg(conn->
db));
381 static void _sql_greatest(sqlite3_context *ctx,
int num_values, sqlite3_value **values)
386 for (i = 0; i < num_values; i++) {
387 value = sqlite3_value_int64(values[i]);
393 sqlite3_result_int64(ctx, max);
407 INFO(
"Opening SQLite database \"%s\"",
inst->filename);
408 #ifdef HAVE_SQLITE3_OPEN_V2
411 status = sqlite3_open(
inst->filename, &(conn->
db));
416 #ifdef HAVE_SQLITE3_OPEN_V2
417 if (!
inst->bootstrap) {
418 INFO(
"Use the sqlite driver 'bootstrap' option to automatically create the database file");
432 #ifdef HAVE_SQLITE3_EXTENDED_RESULT_CODES
433 status = sqlite3_extended_result_codes(conn->
db, 1);
440 #ifdef HAVE_SQLITE3_CREATE_FUNCTION_V2
441 status = sqlite3_create_function_v2(conn->
db,
"GREATEST", -1, SQLITE_ANY, NULL,
444 status = sqlite3_create_function(conn->
db,
"GREATEST", -1, SQLITE_ANY, NULL,
461 #ifdef HAVE_SQLITE3_PREPARE_V2
462 status = sqlite3_prepare_v2(conn->
db, query, strlen(query), &conn->
statement, &z_tail);
464 status = sqlite3_prepare(conn->
db, query, strlen(query), &conn->
statement, &z_tail);
481 #ifdef HAVE_SQLITE3_PREPARE_V2
482 status = sqlite3_prepare_v2(conn->
db, query, strlen(query), &conn->
statement, &z_tail);
484 status = sqlite3_prepare(conn->
db, query, strlen(query), &conn->
statement, &z_tail);
509 fields = sqlite3_column_count(conn->
statement);
512 MEM(
names = talloc_array(handle,
char const *, fields));
514 for (i = 0; i < fields; i++)
names[i] = sqlite3_column_name(conn->
statement, i);
531 TALLOC_FREE(handle->
row);
563 switch (sqlite3_column_type(conn->
statement, i)) {
575 p = (
char const *) sqlite3_column_text(conn->
statement, i);
586 p = sqlite3_column_blob(conn->
statement, i);
588 len = sqlite3_column_bytes(conn->
statement, i);
590 MEM(row[i] = talloc_zero_array(row,
char, len + 1));
591 memcpy(row[i], p, len);
611 TALLOC_FREE(handle->
row);
613 (void) sqlite3_finalize(conn->
statement);
647 error = sqlite3_errmsg(conn->
db);
648 if (!error)
return 0;
666 if (conn->
db)
return sqlite3_changes(conn->
db);
681 if (!
inst->filename) {
693 }
else if (fstatat(fd, r, &buf, 0) == 0) {
695 }
else if (errno == ENOENT) {
704 inst->bootstrap =
true;
707 if (
inst->bootstrap && !exists) {
708 #ifdef HAVE_SQLITE3_OPEN_V2
716 INFO(
"Database \"%s\" doesn't exist, creating it and loading schema",
inst->filename);
718 p = strrchr(
inst->filename,
'/');
720 size_t len = (p -
inst->filename) + 1;
731 PERROR(
"Failed creating directory for SQLite database");
737 status = sqlite3_open_v2(
inst->filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
739 # ifdef HAVE_SQLITE3_ERRSTR
740 ERROR(
"Failed creating opening/creating SQLite database: %s",
741 sqlite3_errstr(status));
743 ERROR(
"Failed creating opening/creating SQLite database, got code (%i)",
751 (void) sqlite3_close(db);
765 ret = sql_loadfile(mctx->
inst->
conf, db, p);
766 if (ret < 0)
goto unlink;
769 status = sqlite3_close(db);
770 if (status != SQLITE_OK) {
774 # ifdef HAVE_SQLITE3_ERRSTR
775 ERROR(
"Error closing SQLite handle: %s", sqlite3_errstr(status));
777 ERROR(
"Error closing SQLite handle, got code (%i)", status);
784 if ((unlinkat(fd, r, 0) < 0) && (errno != ENOENT)) {
785 ERROR(
"Error removing partially initialised database: %s",
792 WARN(
"sqlite3_open_v2() not available, cannot bootstrap database. "
793 "Upgrade to SQLite >= 3.5.1 if you need this functionality");
803 if (sqlite3_libversion_number() != SQLITE_VERSION_NUMBER) {
804 WARN(
"libsqlite version changed since the server was built");
805 WARN(
"linked: %s built: %s", sqlite3_libversion(), SQLITE_VERSION);
807 INFO(
"libsqlite version: %s", sqlite3_libversion());
816 .name =
"sql_sqlite",
static int const char char buffer[256]
static int const char * fmt
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_FILE_OUTPUT
File matching value must exist, and must be writable.
Defines a CONF_PAIR to C data type mapping.
Configuration AVP similar to a fr_pair_t.
CONF_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
CONF_PAIR * cf_pair_find_next(CONF_SECTION const *cs, CONF_PAIR const *prev, char const *attr)
Find a pair with a name matching attr, after specified pair.
static fr_time_delta_t timeout
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
dl_module_inst_t const *_CONST parent
Parent module's instance (if any).
ssize_t fr_mkdir(int *fd_out, char const *path, ssize_t len, mode_t mode, fr_mkdir_func_t func, void *uctx)
Create directories that are missing in the specified path.
int fr_dirfd(int *dirfd, char const **filename, char const *pathname)
From a pathname, return fd and filename needed for *at() functions.
main_config_t const * main_config
Main server configuration.
char const * raddb_dir
Path to raddb directory.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for instantiation calls.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
static const conf_parser_t config[]
Prototypes and functions for the SQL module.
rlm_sql_t const * inst
The rlm_sql instance this connection belongs to.
void * conn
Database specific connection handle.
sql_rcode_t
Action to take at end of an SQL query.
@ RLM_SQL_ALT_QUERY
Key constraint violation, use an alternative query.
@ RLM_SQL_RECONNECT
Stale connection, should reconnect.
@ RLM_SQL_ERROR
General connection/server error.
@ RLM_SQL_NO_MORE_ROWS
No more rows available.
#define RLM_SQL_RCODE_FLAGS_ALT_QUERY
Can distinguish between other errors and those.
rlm_sql_row_t row
Row data from the last query.
sqlite_int64 sqlite3_int64
static int mod_load(void)
static sql_rcode_t sql_fetch_row(rlm_sql_row_t *out, rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static void sql_print_error(sqlite3 *db, int status, char const *fmt,...))
Print an error to the global debug log.
rlm_sql_driver_t rlm_sql_sqlite
static sql_rcode_t sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t const *config)
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
static const conf_parser_t driver_config[]
static sql_rcode_t sql_error_to_rcode(int status)
Convert an sqlite status code to an sql_rcode_t.
#define SQLITE_OPEN_NOMUTEX
static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query)
static int sql_affected_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
static int _sql_socket_destructor(rlm_sql_sqlite_conn_t *conn)
static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
static sql_rcode_t sql_check_error(sqlite3 *db, int status)
Determine if an error occurred, and what type of error it was.
static void _sql_greatest(sqlite3_context *ctx, int num_values, sqlite3_value **values)
static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, UNUSED fr_time_delta_t timeout)
static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config)
static size_t sql_error(UNUSED 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.
dl_module_inst_t * dl_inst
Structure containing the module's instance data, configuration, and dl handle.
static char buff[sizeof("18446744073709551615")+3]
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
module_t common
Common fields for all loadable modules.
module_instance_t * driver_submodule
Driver's submodule.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
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_sec(fr_time_delta_t delta)
A time delta, a difference in time measured in nanoseconds.
int format(printf, 5, 0))
static size_t char ** out