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.
25 #include <freeradius-devel/ident.h>
28 #include <freeradius-devel/radiusd.h>
37 #define BOOTSTRAP_MAX (1048576 * 10)
39 typedef struct rlm_sql_sqlite_conn {
41 sqlite3_stmt *statement;
43 } rlm_sql_sqlite_conn_t;
45 typedef struct rlm_sql_sqlite_config {
47 const char *bootstrap;
48 } rlm_sql_sqlite_config_t;
50 static const CONF_PARSER driver_config[] = {
51 {"filename", PW_TYPE_STRING_PTR,
52 offsetof(rlm_sql_sqlite_config_t, filename), NULL, NULL},
53 {"bootstrap", PW_TYPE_STRING_PTR,
54 offsetof(rlm_sql_sqlite_config_t, bootstrap), NULL, NULL},
56 {NULL, -1, 0, NULL, NULL}
59 static int sql_check_error(sqlite3 *db)
61 int error = sqlite3_errcode(db);
71 * User/transient errors
73 case SQLITE_ERROR: /* SQL error or missing database */
75 case SQLITE_CONSTRAINT:
77 radlog(L_ERR, "rlm_sql_sqlite: Error (%d): %s", error,
84 * Errors with the handle, that probably require reinitialisation
87 radlog(L_ERR, "rlm_sql_sqlite: Handle is unusable, "
88 "error (%d): %s", error, sqlite3_errmsg(db));
94 static int sql_loadfile(sqlite3 *db, const char *filename)
104 sqlite3_stmt *statement;
107 radlog(L_INFO, "rlm_sql_sqlite: Executing SQL statements from "
108 "file \"%s\"", filename);
110 f = fopen(filename, "r");
112 radlog(L_ERR, "rlm_sql_sqlite: Failed opening SQL "
113 "file \"%s\": %s", filename,
119 if (fstat(fileno(f), &finfo) < 0) {
120 radlog(L_ERR, "rlm_sql_sqlite: Failed stating SQL "
121 "file \"%s\": %s", filename,
129 if (finfo.st_size > BOOTSTRAP_MAX) {
131 radlog(L_ERR, "rlm_sql_sqlite: Size of SQL "
132 "(%zu) file exceeds limit (%uk)", (size_t) finfo.st_size / 1024,
133 BOOTSTRAP_MAX / 1024);
140 MEM(buff = talloc_array(NULL, char, finfo.st_size + 1));
141 len = fread(buff, sizeof(char), finfo.st_size + 1, f);
142 if (len > finfo.st_size) {
150 radlog(L_ERR, "rlm_sql_sqlite: Error reading SQL "
151 "file: %s", strerror(errno));
159 radlog(L_DBG, "rlm_sql_sqlite: Ignoring empty SQL file");
172 * Statement delimiter is ;\n
175 while ((q = strchr(p, ';'))) {
182 (void) sqlite3_prepare_v2(db, s, len, &statement, &z_tail);
183 if (sql_check_error(db)) {
188 (void) sqlite3_step(statement);
189 status = sql_check_error(db);
191 (void) sqlite3_finalize(statement);
192 if (status || sql_check_error(db)) {
204 static int sql_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
206 rlm_sql_sqlite_config_t *driver;
209 MEM(driver = config->driver = talloc_zero(config,
210 rlm_sql_sqlite_config_t));
212 if (cf_section_parse(conf, driver, driver_config) < 0) {
216 if (!driver->filename) {
217 MEM(driver->filename = talloc_asprintf(driver, "%s/%s",
222 exists = rad_file_exists(driver->filename);
224 radlog(L_ERR, "rlm_sql_sqlite: Database exists, but couldn't "
225 "be opened: %s", strerror(errno));
230 if (driver->bootstrap && !exists) {
237 radlog(L_INFO, "rlm_sql_sqlite: Database doesn't exist, "
238 "creating it and loading schema");
240 p = strrchr(driver->filename, '/');
242 size_t len = (p - driver->filename) + 1;
244 buff = talloc_array(NULL, char, len);
245 strlcpy(buff, driver->filename, len);
247 buff = talloc_strdup(NULL, driver->filename);
250 if (rad_mkdir(buff, 0700) < 0) {
251 radlog(L_ERR, "rlm_sql_sqlite: Failed creating "
252 "directory for SQLite database");
261 status = sqlite3_open_v2(driver->filename, &db,
262 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
266 radlog(L_ERR, "rlm_sql_sqlite: Failed creating "
267 "opening/creating SQLite database, error "
268 "code (%u)", status);
273 if (sql_check_error(db)) {
274 (void) sqlite3_close(db);
279 ret = sql_loadfile(db, driver->bootstrap);
281 status = sqlite3_close(db);
282 if (status != SQLITE_OK) {
283 radlog(L_ERR, "rlm_sql_sqlite: Error closing SQLite "
284 "handle, error code (%u)", status);
296 static int sql_socket_destructor(void *c)
299 rlm_sql_sqlite_conn_t * conn = c;
301 DEBUG2("rlm_sql_sqlite: Socket destructor called, closing socket");
304 status = sqlite3_close(conn->db);
305 if (status != SQLITE_OK) {
306 DEBUGW("rlm_sql_sqlite: Got SQLite error "
307 "code (%u) when closing socket", status);
314 static int sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
316 rlm_sql_sqlite_conn_t *conn;
317 rlm_sql_sqlite_config_t *driver = config->driver;
321 MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_sqlite_conn_t));
322 talloc_set_destructor((void *) conn, sql_socket_destructor);
324 radlog(L_INFO, "rlm_sql_sqlite: Opening SQLite database \"%s\"",
327 status = sqlite3_open_v2(driver->filename, &(conn->db),
328 SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
331 radlog(L_ERR, "rlm_sql_sqlite: Failed creating "
332 "opening/creating SQLite database error "
333 "code (%u)", status);
338 if (sql_check_error(conn->db)) {
343 * Enable extended return codes for extra debugging info.
345 status = sqlite3_extended_result_codes(conn->db, 1);
347 if (sql_check_error(conn->db)) {
354 static int sql_select_query(rlm_sql_handle_t *handle,
355 UNUSED rlm_sql_config_t *config, char *querystr)
358 rlm_sql_sqlite_conn_t *conn = handle->conn;
361 status = sqlite3_prepare_v2(conn->db, querystr,
362 strlen(querystr), &conn->statement,
367 return sql_check_error(conn->db);
371 static int sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config,
375 rlm_sql_sqlite_conn_t *conn = handle->conn;
378 status = sqlite3_prepare_v2(conn->db, querystr,
379 strlen(querystr), &conn->statement,
382 status = sqlite3_step(conn->statement);
384 return sql_check_error(conn->db);
387 static int sql_store_result(UNUSED rlm_sql_handle_t *handle,
388 UNUSED rlm_sql_config_t *config)
393 static int sql_num_fields(rlm_sql_handle_t * handle,
394 UNUSED rlm_sql_config_t *config)
396 rlm_sql_sqlite_conn_t *conn = handle->conn;
398 if (conn->statement) {
399 return sqlite3_column_count(conn->statement);
405 static int sql_num_rows(rlm_sql_handle_t *handle,
406 UNUSED rlm_sql_config_t *config)
408 rlm_sql_sqlite_conn_t *conn = handle->conn;
410 if (conn->statement) {
411 return sqlite3_data_count(conn->statement);
417 static int sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
420 rlm_sql_sqlite_conn_t *conn = handle->conn;
427 * Executes the SQLite query and interates over the results
429 status = sqlite3_step(conn->statement);
432 * Error getting next row
434 if (sql_check_error(conn->db)) {
439 * No more rows to process (were done)
441 if (status == SQLITE_DONE) {
446 * We only need to do this once per result set, because
447 * the number of columns won't change.
449 if (conn->col_count == 0) {
450 conn->col_count = sql_num_fields(handle, config);
451 if (conn->col_count == 0) {
457 * Free the previous result (also gets called on finish_query)
459 talloc_free(handle->row);
461 MEM(row = handle->row = talloc_zero_array(handle->conn, char *,
462 conn->col_count + 1));
464 for (i = 0; i < conn->col_count; i++)
466 switch (sqlite3_column_type(conn->statement, i))
469 row[i] = talloc_asprintf(row, "%d",
470 sqlite3_column_int(conn->statement, i));
474 row[i] = talloc_asprintf(row, "%f",
475 sqlite3_column_double(conn->statement, i));
481 p = (const char *) sqlite3_column_text(conn->statement, i);
484 row[i] = talloc_strdup(row, p);
494 p = sqlite3_column_blob(conn->statement, i);
496 len = sqlite3_column_bytes(conn->statement, i);
498 MEM(row[i] = talloc_zero_array(row, char, len + 1));
499 memcpy(row[i], p, len);
512 static int sql_free_result(rlm_sql_handle_t *handle,
513 UNUSED rlm_sql_config_t *config)
515 rlm_sql_sqlite_conn_t *conn = handle->conn;
517 if (conn->statement) {
518 TALLOC_FREE(handle->row);
520 (void) sqlite3_finalize(conn->statement);
521 conn->statement = NULL;
526 * There's no point in checking the code returned by finalize
527 * as it'll have already been encountered elsewhere in the code.
529 * It's just the last error that occurred processing the
535 static const char *sql_error(rlm_sql_handle_t *handle,
536 UNUSED rlm_sql_config_t *config)
538 rlm_sql_sqlite_conn_t *conn = handle->conn;
541 return sqlite3_errmsg(conn->db);
544 return "Invalid handle";
547 static int sql_finish_query(rlm_sql_handle_t *handle,
548 UNUSED rlm_sql_config_t *config)
550 return sql_free_result(handle, config);
553 static int sql_affected_rows(rlm_sql_handle_t *handle,
554 UNUSED rlm_sql_config_t *config)
556 rlm_sql_sqlite_conn_t *conn = handle->conn;
559 return sqlite3_changes(conn->db);
566 /* Exported to rlm_sql */
567 rlm_sql_module_t rlm_sql_sqlite = {