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>
36 typedef struct rlm_sql_conn {
38 sqlite3_stmt *statement;
42 typedef struct rlm_sql_sqlite_config {
44 } rlm_sql_sqlite_config_t;
46 static const CONF_PARSER driver_config[] = {
47 {"filename", PW_TYPE_STRING_PTR,
48 offsetof(rlm_sql_sqlite_config_t, filename), NULL, NULL},
50 {NULL, -1, 0, NULL, NULL}
53 static int sql_check_error(sqlite3 *db)
55 int error = sqlite3_errcode(db);
65 * User/transient errors
67 case SQLITE_ERROR: /* SQL error or missing database */
69 case SQLITE_CONSTRAINT:
71 radlog(L_ERR, "rlm_sql_sqlite: Error (%d)", error);
77 * Errors with the handle, that probably require reinitialisation
80 radlog(L_ERR, "rlm_sql_sqlite: Handle is unusable, "
87 static int sql_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
89 rlm_sql_sqlite_config_t *driver;
91 MEM(driver = config->driver = talloc_zero(config, rlm_sql_sqlite_config_t));
93 if (cf_section_parse(conf, driver, driver_config) < 0) {
97 if (!driver->filename) {
98 MEM(driver->filename = talloc_asprintf(driver, "%s/%s",
106 static int sql_init_socket(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
108 rlm_sql_conn_t *conn;
109 rlm_sql_sqlite_config_t *driver = config->driver;
113 MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_conn_t));
115 radlog(L_INFO, "rlm_sql_sqlite: Opening SQLite database \"%s\"",
118 status = sqlite3_open_v2(driver->filename, &(conn->db),
119 SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
121 if (status != SQLITE_OK) {
122 return sql_check_error(conn->db);
126 * Enable extended return codes for extra debugging info.
128 status = sqlite3_extended_result_codes(conn->db, 1);
130 return sql_check_error(conn->db);
133 static int sql_destroy_socket(rlm_sql_handle_t *handle,
134 UNUSED rlm_sql_config_t *config)
140 TALLOC_FREE(handle->conn);
145 static int sql_select_query(rlm_sql_handle_t * handle,
146 UNUSED rlm_sql_config_t *config, char *querystr)
149 rlm_sql_conn_t *conn = handle->conn;
152 status = sqlite3_prepare_v2(conn->db, querystr,
153 strlen(querystr), &conn->statement,
158 return sql_check_error(conn->db);
162 static int sql_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config,
166 rlm_sql_conn_t *conn = handle->conn;
169 status = sqlite3_prepare_v2(conn->db, querystr,
170 strlen(querystr), &conn->statement,
173 status = sqlite3_step(conn->statement);
175 return sql_check_error(conn->db);
178 static int sql_store_result(UNUSED rlm_sql_handle_t * handle,
179 UNUSED rlm_sql_config_t *config)
184 static int sql_num_fields(rlm_sql_handle_t * handle,
185 UNUSED rlm_sql_config_t *config)
187 rlm_sql_conn_t *conn = handle->conn;
189 if (conn->statement) {
190 return sqlite3_column_count(conn->statement);
196 static int sql_num_rows(rlm_sql_handle_t * handle,
197 UNUSED rlm_sql_config_t *config)
199 rlm_sql_conn_t *conn = handle->conn;
201 if (conn->statement) {
202 return sqlite3_data_count(conn->statement);
208 static int sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
211 rlm_sql_conn_t *conn = handle->conn;
218 * Executes the SQLite query and interates over the results
220 status = sqlite3_step(conn->statement);
223 * Error getting next row
225 if (sql_check_error(conn->db)) {
230 * No more rows to process (were done)
232 if (status == SQLITE_DONE) {
237 * We only need to do this once per result set, because
238 * the number of columns won't change.
240 if (conn->col_count == 0) {
241 conn->col_count = sql_num_fields(handle, config);
242 if (conn->col_count == 0) {
248 * Free the previous result (also gets called on finish_query)
250 talloc_free(handle->row);
252 MEM(row = handle->row = talloc_zero_array(handle->conn, char *,
253 conn->col_count + 1));
255 for (i = 0; i < conn->col_count; i++)
257 switch (sqlite3_column_type(conn->statement, i))
260 row[i] = talloc_asprintf(row, "%d",
261 sqlite3_column_int(conn->statement, i));
265 row[i] = talloc_asprintf(row, "%f",
266 sqlite3_column_double(conn->statement, i));
272 p = (const char *) sqlite3_column_text(conn->statement, i);
275 row[i] = talloc_strdup(row, p);
285 p = sqlite3_column_blob(conn->statement, i);
287 len = sqlite3_column_bytes(conn->statement, i);
289 MEM(row[i] = talloc_zero_array(row, char, len + 1));
290 memcpy(row[i], p, len);
303 static int sql_free_result(rlm_sql_handle_t *handle,
304 UNUSED rlm_sql_config_t *config)
306 rlm_sql_conn_t *conn = handle->conn;
308 if (conn->statement) {
309 TALLOC_FREE(handle->row);
311 (void) sqlite3_finalize(conn->statement);
312 conn->statement = NULL;
317 * There's no point in checking the code returned by finalize
318 * as it'll have already been encountered elsewhere in the code.
320 * It's just the last error that occurred processing the
326 static const char *sql_error(rlm_sql_handle_t *handle,
327 UNUSED rlm_sql_config_t *config)
329 rlm_sql_conn_t *conn = handle->conn;
332 return sqlite3_errmsg(conn->db);
335 return "Invalid handle";
338 static int sql_close(rlm_sql_handle_t *handle,
339 UNUSED rlm_sql_config_t *config)
342 rlm_sql_conn_t *conn = handle->conn;
344 if (conn && conn->db) {
345 status = sqlite3_close(conn->db);
349 if (status != SQLITE_OK) {
356 static int sql_finish_query(rlm_sql_handle_t *handle,
357 UNUSED rlm_sql_config_t *config)
359 return sql_free_result(handle, config);
362 static int sql_affected_rows(rlm_sql_handle_t *handle,
363 UNUSED rlm_sql_config_t *config)
365 rlm_sql_conn_t *conn = handle->conn;
368 return sqlite3_changes(conn->db);
375 /* Exported to rlm_sql */
376 rlm_sql_module_t rlm_sql_sqlite = {