2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2 if the
4 * License as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * @file rlm_sql_sqlite.c
19 * @brief SQLite driver.
21 * @copyright 2013 Network RADIUS SARL <info@networkradius.com>
22 * @copyright 2007 Apple Inc.
27 #include <freeradius-devel/radiusd.h>
37 #define BOOTSTRAP_MAX (1048576 * 10)
40 * Allow us to use versions < 3.6.0 beta0
42 #ifndef SQLITE_OPEN_NOMUTEX
43 # define SQLITE_OPEN_NOMUTEX 0
46 typedef struct rlm_sql_sqlite_conn {
48 sqlite3_stmt *statement;
50 } rlm_sql_sqlite_conn_t;
52 typedef struct rlm_sql_sqlite_config {
54 const char *bootstrap;
55 } rlm_sql_sqlite_config_t;
57 static const CONF_PARSER driver_config[] = {
58 {"filename", PW_TYPE_STRING_PTR,
59 offsetof(rlm_sql_sqlite_config_t, filename), NULL, NULL},
60 {"bootstrap", PW_TYPE_STRING_PTR,
61 offsetof(rlm_sql_sqlite_config_t, bootstrap), NULL, NULL},
63 {NULL, -1, 0, NULL, NULL}
66 static int sql_check_error(sqlite3 *db)
68 int error = sqlite3_errcode(db);
78 * User/transient errors
80 case SQLITE_ERROR: /* SQL error or missing database */
82 case SQLITE_CONSTRAINT:
84 radlog(L_ERR, "rlm_sql_sqlite: Error (%d): %s", error, sqlite3_errmsg(db));
90 * Errors with the handle, that probably require reinitialisation
93 radlog(L_ERR, "rlm_sql_sqlite: Handle is unusable, error (%d): %s", error, sqlite3_errmsg(db));
99 #ifdef HAVE_SQLITE_V2_API
100 static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, const char *filename)
110 sqlite3_stmt *statement;
113 radlog(L_INFO, "rlm_sql_sqlite: Executing SQL statements from file \"%s\"", filename);
115 f = fopen(filename, "r");
117 radlog(L_ERR, "rlm_sql_sqlite: Failed opening SQL file \"%s\": %s", filename,
123 if (fstat(fileno(f), &finfo) < 0) {
124 radlog(L_ERR, "rlm_sql_sqlite: Failed stating SQL file \"%s\": %s", filename,
132 if (finfo.st_size > BOOTSTRAP_MAX) {
134 radlog(L_ERR, "rlm_sql_sqlite: Size of SQL (%zu) file exceeds limit (%uk)",
135 (size_t) finfo.st_size / 1024, BOOTSTRAP_MAX / 1024);
142 MEM(buffer = talloc_array(ctx, char, finfo.st_size + 1));
143 len = fread(buffer, sizeof(char), finfo.st_size + 1, f);
144 if (len > finfo.st_size) {
151 radlog(L_ERR, "rlm_sql_sqlite: Error reading SQL file: %s", strerror(errno));
159 radlog(L_DBG, "rlm_sql_sqlite: Ignoring empty SQL file");
171 * Check if input data is UTF-8. Allow CR/LF \t, too.
173 for (p = buffer; p < (buffer + len); p += cl) {
175 if ((*p != 0x0a) && (*p != 0x0d) && (*p != '\t')) break;
178 cl = fr_utf8_char((uint8_t *) p);
183 if ((p - buffer) != len) {
184 radlog(L_ERR, "rlm_sql_sqlite: Bootstrap file contains non-UTF8 char at offset %zu", p - buffer);
190 * Statement delimiter is ;\n
193 while ((q = strchr(p, ';'))) {
201 (void) sqlite3_prepare_v2(db, s, len, &statement, &z_tail);
202 if (sql_check_error(db)) {
207 (void) sqlite3_step(statement);
208 status = sql_check_error(db);
210 (void) sqlite3_finalize(statement);
211 if (status || sql_check_error(db)) {
224 static int mod_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
226 rlm_sql_sqlite_config_t *driver;
229 if (sqlite3_libversion_number() != SQLITE_VERSION_NUMBER) {
230 DEBUG2("rlm_sql_sqlite: SQLite library version (%s) is different from the version the server was "
231 "originally built against (%s), this may cause issues",
232 sqlite3_libversion(), SQLITE_VERSION);
235 MEM(driver = config->driver = talloc_zero(config, rlm_sql_sqlite_config_t));
237 if (cf_section_parse(conf, driver, driver_config) < 0) {
241 radlog(L_INFO, "rlm_sql_sqlite: SQLite library version: %s", sqlite3_libversion());
242 if (!driver->filename) {
243 MEM(driver->filename = talloc_asprintf(driver, "%s/%s", radius_dir, config->sql_db));
246 exists = rad_file_exists(driver->filename);
248 radlog(L_ERR, "rlm_sql_sqlite: Database exists, but couldn't be opened: %s", strerror(errno));
253 if (driver->bootstrap && !exists) {
254 #ifdef HAVE_SQLITE_V2_API
261 radlog(L_INFO, "rlm_sql_sqlite: Database doesn't exist, creating it and loading schema");
263 p = strrchr(driver->filename, '/');
265 size_t len = (p - driver->filename) + 1;
267 buff = talloc_array(conf, char, len);
268 strlcpy(buff, driver->filename, len);
270 MEM(buff = talloc_strdup(conf, driver->filename));
273 if (rad_mkdir(buff, 0700) < 0) {
274 radlog(L_ERR, "rlm_sql_sqlite: Failed creating directory for SQLite database");
283 status = sqlite3_open_v2(driver->filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
285 radlog(L_ERR, "rlm_sql_sqlite: Failed creating opening/creating SQLite database, error "
286 "code (%u)", status);
291 if (sql_check_error(db)) {
292 (void) sqlite3_close(db);
297 ret = sql_loadfile(conf, db, driver->bootstrap);
299 status = sqlite3_close(db);
300 if (status != SQLITE_OK) {
301 radlog(L_ERR, "rlm_sql_sqlite: Error closing SQLite handle, error code (%u)", status);
307 if (unlink(driver->filename) < 0) {
308 radlog(L_ERR, "rlm_sql_sqlite: Error removing partially initialised database: %s",
314 DEBUGW("rlm_sql_sqlite: sqlite3_open_v2() not available, cannot bootstrap database. "
315 "Upgrade to SQLite >= 3.5.1 if you need this functionality");
322 static int sql_socket_destructor(void *c)
325 rlm_sql_sqlite_conn_t * conn = c;
327 DEBUG2("rlm_sql_sqlite: Socket destructor called, closing socket");
330 status = sqlite3_close(conn->db);
331 if (status != SQLITE_OK) {
332 DEBUGW("rlm_sql_sqlite: Got SQLite error code (%u) when closing socket", status);
339 static int sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
341 rlm_sql_sqlite_conn_t *conn;
342 rlm_sql_sqlite_config_t *driver = config->driver;
346 MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_sqlite_conn_t));
347 talloc_set_destructor((void *) conn, sql_socket_destructor);
349 radlog(L_INFO, "rlm_sql_sqlite: Opening SQLite database \"%s\"", driver->filename);
351 #ifdef HAVE_SQLITE_V2_API
352 status = sqlite3_open_v2(driver->filename, &(conn->db), SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL);
354 status = sqlite3_open(driver->filename, &(conn->db));
357 radlog(L_ERR, "rlm_sql_sqlite: Failed creating opening/creating SQLite database error code (%u)",
363 if (sql_check_error(conn->db)) {
368 * Enable extended return codes for extra debugging info.
370 status = sqlite3_extended_result_codes(conn->db, 1);
372 if (sql_check_error(conn->db)) {
379 static int sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, const char *query)
382 rlm_sql_sqlite_conn_t *conn = handle->conn;
385 #ifdef HAVE_SQLITE_V2_API
386 status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
388 status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
393 return sql_check_error(conn->db);
397 static int sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, const char *query)
400 rlm_sql_sqlite_conn_t *conn = handle->conn;
403 #ifdef HAVE_SQLITE_V2_API
404 status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
406 status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
408 status = sqlite3_step(conn->statement);
410 return sql_check_error(conn->db);
413 static int sql_store_result(UNUSED rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
418 static int sql_num_fields(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config)
420 rlm_sql_sqlite_conn_t *conn = handle->conn;
422 if (conn->statement) {
423 return sqlite3_column_count(conn->statement);
429 static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
431 rlm_sql_sqlite_conn_t *conn = handle->conn;
433 if (conn->statement) {
434 return sqlite3_data_count(conn->statement);
440 static int sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
443 rlm_sql_sqlite_conn_t *conn = handle->conn;
450 * Executes the SQLite query and interates over the results
452 status = sqlite3_step(conn->statement);
455 * Error getting next row
457 if (sql_check_error(conn->db)) {
462 * No more rows to process (were done)
464 if (status == SQLITE_DONE) {
469 * We only need to do this once per result set, because
470 * the number of columns won't change.
472 if (conn->col_count == 0) {
473 conn->col_count = sql_num_fields(handle, config);
474 if (conn->col_count == 0) {
480 * Free the previous result (also gets called on finish_query)
482 talloc_free(handle->row);
484 MEM(row = handle->row = talloc_zero_array(handle->conn, char *, conn->col_count + 1));
486 for (i = 0; i < conn->col_count; i++)
488 switch (sqlite3_column_type(conn->statement, i))
491 MEM(row[i] = talloc_asprintf(row, "%d", sqlite3_column_int(conn->statement, i)));
495 MEM(row[i] = talloc_asprintf(row, "%f", sqlite3_column_double(conn->statement, i)));
501 p = (const char *) sqlite3_column_text(conn->statement, i);
504 MEM(row[i] = talloc_strdup(row, p));
514 p = sqlite3_column_blob(conn->statement, i);
516 len = sqlite3_column_bytes(conn->statement, i);
518 MEM(row[i] = talloc_zero_array(row, char, len + 1));
519 memcpy(row[i], p, len);
532 static int sql_free_result(rlm_sql_handle_t *handle,
533 UNUSED rlm_sql_config_t *config)
535 rlm_sql_sqlite_conn_t *conn = handle->conn;
537 if (conn->statement) {
538 TALLOC_FREE(handle->row);
540 (void) sqlite3_finalize(conn->statement);
541 conn->statement = NULL;
546 * There's no point in checking the code returned by finalize
547 * as it'll have already been encountered elsewhere in the code.
549 * It's just the last error that occurred processing the
555 static const char *sql_error(rlm_sql_handle_t *handle,
556 UNUSED rlm_sql_config_t *config)
558 rlm_sql_sqlite_conn_t *conn = handle->conn;
561 return sqlite3_errmsg(conn->db);
564 return "Invalid handle";
567 static int sql_finish_query(rlm_sql_handle_t *handle,
568 UNUSED rlm_sql_config_t *config)
570 return sql_free_result(handle, config);
573 static int sql_affected_rows(rlm_sql_handle_t *handle,
574 UNUSED rlm_sql_config_t *config)
576 rlm_sql_sqlite_conn_t *conn = handle->conn;
579 return sqlite3_changes(conn->db);
586 /* Exported to rlm_sql */
587 rlm_sql_module_t rlm_sql_sqlite = {