All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_sql_sqlite.c
Go to the documentation of this file.
1 /*
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 as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 4f367721ef891cec2f263af3bf1ede039d3db190 $
19  * @file rlm_sql_sqlite.c
20  * @brief SQLite driver.
21  *
22  * @copyright 2013 Network RADIUS SARL <info@networkradius.com>
23  * @copyright 2007 Apple Inc.
24  */
25 RCSID("$Id: 4f367721ef891cec2f263af3bf1ede039d3db190 $")
26 
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/rad_assert.h>
29 
30 #include <fcntl.h>
31 #include <sys/stat.h>
32 
33 #include <sqlite3.h>
34 
35 #include "rlm_sql.h"
36 #include "config.h"
37 
38 #define BOOTSTRAP_MAX (1048576 * 10)
39 
40 /*
41  * Allow us to use versions < 3.6.0 beta0
42  */
43 #ifndef SQLITE_OPEN_NOMUTEX
44 # define SQLITE_OPEN_NOMUTEX 0
45 #endif
46 
47 #ifndef HAVE_SQLITE3_INT64
48 typedef sqlite3_int64 sqlite_int64
49 #endif
50 
51 typedef struct rlm_sql_sqlite_conn {
52  sqlite3 *db;
53  sqlite3_stmt *statement;
54  int col_count;
56 
57 typedef struct rlm_sql_sqlite_config {
58  char const *filename;
59  uint32_t busy_timeout;
61 
62 static const CONF_PARSER driver_config[] = {
64  { FR_CONF_OFFSET("busy_timeout", PW_TYPE_INTEGER, rlm_sql_sqlite_config_t, busy_timeout), .dflt = "200" },
66 };
67 
68 /** Convert an sqlite status code to an sql_rcode_t
69  *
70  * @param status to convert.
71  * @return
72  * - RLM_SQL_OK - If no errors found.
73  * - RLM_SQL_ERROR - If a known, non-fatal, error occurred.
74  * - RLM_SQL_ALT_QUERY - If a constraints violation occurred.
75  * - RLM_SQL_RECONNECT - Anything else, we assume the connection can no longer be used.
76  */
77 static sql_rcode_t sql_error_to_rcode(int status)
78 {
79  /*
80  * Lowest byte is error category, other byte may contain
81  * the extended error, depending on version.
82  */
83  switch (status & 0xff) {
84  /*
85  * Not errors
86  */
87  case SQLITE_OK:
88  case SQLITE_DONE:
89  case SQLITE_ROW:
90  return RLM_SQL_OK;
91  /*
92  * User/transient errors
93  */
94  case SQLITE_ERROR: /* SQL error or missing database */
95  case SQLITE_FULL:
96  case SQLITE_MISMATCH:
97  return RLM_SQL_ERROR;
98 
99  /*
100  * Constraints violations
101  */
102  case SQLITE_CONSTRAINT:
103  return RLM_SQL_ALT_QUERY;
104 
105  /*
106  * Errors with the handle, that probably require reinitialisation
107  */
108  default:
109  return RLM_SQL_RECONNECT;
110  }
111 }
112 
113 /** Determine if an error occurred, and what type of error it was
114  *
115  * @param db handle to extract error from (may be NULL).
116  * @param status to check (if unused, set to SQLITE_OK).
117  * @return
118  * - RLM_SQL_OK - If no errors found.
119  * - RLM_SQL_ERROR - If a known, non-fatal, error occurred.
120  * - RLM_SQL_ALT_QUERY - If a constraints violation occurred.
121  * - RLM_SQL_RECONNECT - Anything else. We assume the connection can no longer be used.
122  */
123 static sql_rcode_t sql_check_error(sqlite3 *db, int status)
124 {
125  int hstatus = SQLITE_OK;
126 
127  if (db) {
128  hstatus = sqlite3_errcode(db);
129  switch (hstatus & 0xff) {
130  case SQLITE_OK:
131  case SQLITE_DONE:
132  case SQLITE_ROW:
133  hstatus = SQLITE_OK;
134  break;
135 
136  default:
137  break;
138  }
139  }
140 
141  switch (status & 0xff) {
142  case SQLITE_OK:
143  case SQLITE_DONE:
144  case SQLITE_ROW:
145  status = SQLITE_OK;
146  break;
147 
148  default:
149  break;
150  }
151 
152  if (status != SQLITE_OK) return sql_error_to_rcode(status);
153  if (hstatus != SQLITE_OK) return sql_error_to_rcode(status);
154 
155  return RLM_SQL_OK;
156 }
157 
158 /** Print an error to the global debug log
159  *
160  * If status does not indicate success, write an error to the global error log.
161  *
162  * @note The error code will be appended to the fmt string in the format ": code 0x<hex> (<int>)[: <string>]".
163  *
164  * @param db handle to extract error from (may be NULL).
165  * @param status to check (if unused, set to SQLITE_OK).
166  * @param fmt to preprend.
167  * @param ... arguments to fmt.
168  */
169 static void sql_print_error(sqlite3 *db, int status, char const *fmt, ...)
170  CC_HINT(format (printf, 3, 4)) CC_HINT(nonnull (3));
171 static void sql_print_error(sqlite3 *db, int status, char const *fmt, ...)
172 {
173  va_list ap;
174  char *p;
175  int hstatus = SQLITE_OK;
176 
177  if (db) {
178  hstatus = sqlite3_errcode(db);
179  switch (hstatus & 0xff) {
180  case SQLITE_OK:
181  case SQLITE_DONE:
182  case SQLITE_ROW:
183  hstatus = SQLITE_OK;
184  break;
185 
186  default:
187  break;
188  }
189  }
190 
191  switch (status & 0xff) {
192  case SQLITE_OK:
193  case SQLITE_DONE:
194  case SQLITE_ROW:
195  status = SQLITE_OK;
196  break;
197 
198  default:
199  break;
200  }
201 
202  /*
203  * No errors!
204  */
205  if ((hstatus == SQLITE_OK) && (status == SQLITE_OK)) return;
206 
207  /*
208  * At least one error...
209  */
210  va_start(ap, fmt);
211  MEM(p = talloc_vasprintf(NULL, fmt, ap));
212  va_end(ap);
213 
214  /*
215  * Disagreement between handle, and function return code,
216  * print them both.
217  */
218  if ((status != SQLITE_OK) && (status != hstatus)) {
219 #ifdef HAVE_SQLITE3_ERRSTR
220  ERROR("rlm_sql_sqlite: %s: Code 0x%04x (%i): %s", p, status, status, sqlite3_errstr(status));
221 #else
222  ERROR("rlm_sql_sqlite: %s: Code 0x%04x (%i)", p, status, status);
223 #endif
224  }
225 
226  if (hstatus != SQLITE_OK) ERROR("rlm_sql_sqlite: %s: Code 0x%04x (%i): %s",
227  p, hstatus, hstatus, sqlite3_errmsg(db));
228 }
229 
230 #ifdef HAVE_SQLITE3_OPEN_V2
231 static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
232 {
233  ssize_t len;
234  int statement_cnt = 0;
235  char *buffer;
236  char *p, *q, *s;
237  int cl;
238  FILE *f;
239  struct stat finfo;
240 
241  int status;
242  sqlite3_stmt *statement;
243  char const *z_tail;
244 
245  INFO("rlm_sql_sqlite: Executing SQL statements from file \"%s\"", filename);
246 
247  f = fopen(filename, "r");
248  if (!f) {
249  ERROR("rlm_sql_sqlite: Failed opening SQL file \"%s\": %s", filename,
250  fr_syserror(errno));
251 
252  return -1;
253  }
254 
255  if (fstat(fileno(f), &finfo) < 0) {
256  ERROR("rlm_sql_sqlite: Failed stating SQL file \"%s\": %s", filename,
257  fr_syserror(errno));
258 
259  fclose(f);
260 
261  return -1;
262  }
263 
264  if (finfo.st_size > BOOTSTRAP_MAX) {
265  too_big:
266  ERROR("rlm_sql_sqlite: Size of SQL (%zu) file exceeds limit (%uk)",
267  (size_t) finfo.st_size / 1024, BOOTSTRAP_MAX / 1024);
268 
269  fclose(f);
270 
271  return -1;
272  }
273 
274  MEM(buffer = talloc_array(ctx, char, finfo.st_size + 1));
275  len = fread(buffer, sizeof(char), finfo.st_size + 1, f);
276  if (len > finfo.st_size) {
277  talloc_free(buffer);
278  goto too_big;
279  }
280 
281  if (!len) {
282  if (ferror(f)) {
283  ERROR("rlm_sql_sqlite: Error reading SQL file: %s", fr_syserror(errno));
284 
285  fclose(f);
286  talloc_free(buffer);
287 
288  return -1;
289  }
290 
291  DEBUG("rlm_sql_sqlite: Ignoring empty SQL file");
292 
293  fclose(f);
294  talloc_free(buffer);
295 
296  return 0;
297  }
298 
299  buffer[len] = '\0';
300  fclose(f);
301 
302  /*
303  * Check if input data is UTF-8. Allow CR/LF \t, too.
304  */
305  for (p = buffer; p < (buffer + len); p += cl) {
306  if (*p < ' ') {
307  if ((*p != 0x0a) && (*p != 0x0d) && (*p != '\t')) break;
308  cl = 1;
309  } else {
310  cl = fr_utf8_char((uint8_t *) p, -1);
311  if (!cl) break;
312  }
313  }
314 
315  if ((p - buffer) != len) {
316  ERROR("rlm_sql_sqlite: Bootstrap file contains non-UTF8 char at offset %zu", p - buffer);
317  talloc_free(buffer);
318  return -1;
319  }
320 
321  /*
322  * Statement delimiter is ;\n
323  */
324  s = p = buffer;
325  while ((q = strchr(p, ';'))) {
326  if (q[1] != '\n') {
327  p = q + 1;
328  statement_cnt++;
329  continue;
330  }
331 
332  *q = '\0';
333 
334 #ifdef HAVE_SQLITE3_PREPARE_V2
335  status = sqlite3_prepare_v2(db, s, len, &statement, &z_tail);
336 #else
337  status = sqlite3_prepare(db, s, len, &statement, &z_tail);
338 #endif
339 
340  if (sql_check_error(db, status) != RLM_SQL_OK) {
341  sql_print_error(db, status, "Failed preparing statement %i", statement_cnt);
342  talloc_free(buffer);
343  return -1;
344  }
345 
346  status = sqlite3_step(statement);
347  if (sql_check_error(db, status) != RLM_SQL_OK) {
348  sql_print_error(db, status, "Failed executing statement %i", statement_cnt);
349  sqlite3_finalize(statement);
350  talloc_free(buffer);
351  return -1;
352  }
353 
354  status = sqlite3_finalize(statement);
355  if (sql_check_error(db, status) != RLM_SQL_OK) {
356  sql_print_error(db, status, "Failed finalizing statement %i", statement_cnt);
357  talloc_free(buffer);
358  return -1;
359  }
360 
361  statement_cnt++;
362  p = s = q + 1;
363  }
364 
365  talloc_free(buffer);
366  return 0;
367 }
368 #endif
369 
371 {
372  static bool version_done;
373 
374  bool exists;
375  rlm_sql_sqlite_config_t *driver;
376  struct stat buf;
377 
378  if (!version_done) {
379  version_done = true;
380 
381  if (sqlite3_libversion_number() != SQLITE_VERSION_NUMBER) {
382  WARN("rlm_sql_sqlite: libsqlite version changed since the server was built");
383  WARN("rlm_sql_sqlite: linked: %s built: %s", sqlite3_libversion(), SQLITE_VERSION);
384  }
385  INFO("rlm_sql_sqlite: libsqlite version: %s", sqlite3_libversion());
386  }
387 
388  MEM(driver = config->driver = talloc_zero(config, rlm_sql_sqlite_config_t));
389  if (cf_section_parse(conf, driver, driver_config) < 0) {
390  return -1;
391  }
392  if (!driver->filename) {
393  MEM(driver->filename = talloc_typed_asprintf(driver, "%s/%s", get_radius_dir(), config->sql_db));
394  }
395 
396  if (stat(driver->filename, &buf) == 0) {
397  exists = true;
398  } else if (errno == ENOENT) {
399  exists = false;
400  } else {
401  ERROR("rlm_sql_sqlite: Database exists, but couldn't be opened: %s", fr_syserror(errno));
402  return -1;
403  }
404 
405  if (cf_pair_find(conf, "bootstrap") && !exists) {
406 # ifdef HAVE_SQLITE3_OPEN_V2
407  int status;
408  int ret;
409  char const *p;
410  char *buff;
411  sqlite3 *db = NULL;
412  CONF_PAIR *cp;
413 
414  INFO("rlm_sql_sqlite: Database doesn't exist, creating it and loading schema");
415 
416  p = strrchr(driver->filename, '/');
417  if (p) {
418  size_t len = (p - driver->filename) + 1;
419 
420  buff = talloc_array(conf, char, len);
421  strlcpy(buff, driver->filename, len);
422  } else {
423  MEM(buff = talloc_typed_strdup(conf, driver->filename));
424  }
425 
426  ret = rad_mkdir(buff, 0700, -1, -1);
427  talloc_free(buff);
428  if (ret < 0) {
429  ERROR("rlm_sql_sqlite: Failed creating directory for SQLite database: %s", fr_syserror(errno));
430 
431  return -1;
432  };
433 
434  status = sqlite3_open_v2(driver->filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
435  if (!db) {
436 # ifdef HAVE_SQLITE3_ERRSTR
437  ERROR("rlm_sql_sqlite: Failed creating opening/creating SQLite database: %s",
438  sqlite3_errstr(status));
439 # else
440  ERROR("rlm_sql_sqlite: Failed creating opening/creating SQLite database, got code (%i)",
441  status);
442 # endif
443 
444  goto unlink;
445  }
446 
447  if (sql_check_error(db, status) != RLM_SQL_OK) {
448  (void) sqlite3_close(db);
449 
450  goto unlink;
451  }
452 
453  /*
454  * Execute multiple bootstrap SQL files in order
455  */
456  for (cp = cf_pair_find(conf, "bootstrap");
457  cp;
458  cp = cf_pair_find_next(conf, cp, "bootstrap")) {
459  p = cf_pair_value(cp);
460  if (!p) continue;
461 
462  ret = sql_loadfile(conf, db, p);
463  if (ret < 0) goto unlink;
464  }
465 
466  status = sqlite3_close(db);
467  if (status != SQLITE_OK) {
468  /*
469  * Safer to use sqlite3_errstr here, just in case the handle is in a weird state
470  */
471 # ifdef HAVE_SQLITE3_ERRSTR
472  ERROR("rlm_sql_sqlite: Error closing SQLite handle: %s", sqlite3_errstr(status));
473 # else
474  ERROR("rlm_sql_sqlite: Error closing SQLite handle, got code (%i)", status);
475 # endif
476  goto unlink;
477  }
478 
479  if (ret < 0) {
480  unlink:
481  if ((unlink(driver->filename) < 0) && (errno != ENOENT)) {
482  ERROR("rlm_sql_sqlite: Error removing partially initialised database: %s",
483  fr_syserror(errno));
484  }
485  return -1;
486  }
487 #else
488  WARN("rlm_sql_sqlite: sqlite3_open_v2() not available, cannot bootstrap database. "
489  "Upgrade to SQLite >= 3.5.1 if you need this functionality");
490 #endif
491  }
492 
493  return 0;
494 }
495 
497 {
498  int status = 0;
499 
500  DEBUG2("rlm_sql_sqlite: Socket destructor called, closing socket");
501 
502  if (conn->db) {
503  status = sqlite3_close(conn->db);
504  if (status != SQLITE_OK) WARN("rlm_sql_sqlite: Got SQLite error when closing socket: %s",
505  sqlite3_errmsg(conn->db));
506  }
507 
508  return 0;
509 }
510 
511 static void _sql_greatest(sqlite3_context *ctx, int num_values, sqlite3_value **values)
512 {
513  int i;
514  sqlite3_int64 value, max = 0;
515 
516  for (i = 0; i < num_values; i++) {
517  value = sqlite3_value_int64(values[i]);
518  if (value > max) {
519  max = value;
520  }
521  }
522 
523  sqlite3_result_int64(ctx, max);
524 }
525 
526 static int CC_HINT(nonnull) sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config,
527  UNUSED struct timeval const *timeout)
528 {
529  rlm_sql_sqlite_conn_t *conn;
530  rlm_sql_sqlite_config_t *driver = config->driver;
531 
532  int status;
533 
534  MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_sqlite_conn_t));
535  talloc_set_destructor(conn, _sql_socket_destructor);
536 
537  INFO("rlm_sql_sqlite: Opening SQLite database \"%s\"", driver->filename);
538 #ifdef HAVE_SQLITE3_OPEN_V2
539  status = sqlite3_open_v2(driver->filename, &(conn->db), SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL);
540 #else
541  status = sqlite3_open(driver->filename, &(conn->db));
542 #endif
543 
544  if (!conn->db || (sql_check_error(conn->db, status) != RLM_SQL_OK)) {
545  sql_print_error(conn->db, status, "Error opening SQLite database \"%s\"", driver->filename);
546  return RLM_SQL_ERROR;
547  }
548  status = sqlite3_busy_timeout(conn->db, driver->busy_timeout);
549  if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
550  sql_print_error(conn->db, status, "Error setting busy timeout");
551  return RLM_SQL_ERROR;
552  }
553 
554  /*
555  * Enable extended return codes for extra debugging info.
556  */
557 #ifdef HAVE_SQLITE3_EXTENDED_RESULT_CODES
558  status = sqlite3_extended_result_codes(conn->db, 1);
559  if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
560  sql_print_error(conn->db, status, "Error enabling extended result codes");
561  return RLM_SQL_ERROR;
562  }
563 #endif
564 
565 #ifdef HAVE_SQLITE3_CREATE_FUNCTION_V2
566  status = sqlite3_create_function_v2(conn->db, "GREATEST", -1, SQLITE_ANY, NULL,
567  _sql_greatest, NULL, NULL, NULL);
568 #else
569  status = sqlite3_create_function(conn->db, "GREATEST", -1, SQLITE_ANY, NULL,
570  _sql_greatest, NULL, NULL);
571 #endif
572  if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
573  sql_print_error(conn->db, status, "Failed registering 'GREATEST' sql function");
574  return RLM_SQL_ERROR;
575  }
576 
577  return RLM_SQL_OK;
578 }
579 
580 static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
581 {
582  rlm_sql_sqlite_conn_t *conn = handle->conn;
583  char const *z_tail;
584  int status;
585 
586 #ifdef HAVE_SQLITE3_PREPARE_V2
587  status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
588 #else
589  status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
590 #endif
591 
592  conn->col_count = 0;
593 
594  return sql_check_error(conn->db, status);
595 }
596 
597 
598 static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
599 {
600 
601  sql_rcode_t rcode;
602  rlm_sql_sqlite_conn_t *conn = handle->conn;
603  char const *z_tail;
604  int status;
605 
606 #ifdef HAVE_SQLITE3_PREPARE_V2
607  status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
608 #else
609  status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
610 #endif
611  rcode = sql_check_error(conn->db, status);
612  if (rcode != RLM_SQL_OK) return rcode;
613 
614  status = sqlite3_step(conn->statement);
615  return sql_check_error(conn->db, status);
616 }
617 
619 {
620  rlm_sql_sqlite_conn_t *conn = handle->conn;
621 
622  if (conn->statement) return sqlite3_column_count(conn->statement);
623 
624  return 0;
625 }
626 
627 static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
628 {
629  rlm_sql_sqlite_conn_t *conn = handle->conn;
630 
631  int fields, i;
632  char const **names;
633 
634  fields = sqlite3_column_count(conn->statement);
635  if (fields <= 0) return RLM_SQL_ERROR;
636 
637  MEM(names = talloc_array(handle, char const *, fields));
638 
639  for (i = 0; i < fields; i++) names[i] = sqlite3_column_name(conn->statement, i);
640  *out = names;
641 
642  return RLM_SQL_OK;
643 }
644 
646 {
647  int status;
648  rlm_sql_sqlite_conn_t *conn = handle->conn;
649 
650  int i = 0;
651 
652  char **row;
653 
654  *out = NULL;
655 
656  /*
657  * Executes the SQLite query and interates over the results
658  */
659  status = sqlite3_step(conn->statement);
660 
661  /*
662  * Error getting next row
663  */
664  if (sql_check_error(conn->db, status) != RLM_SQL_OK) return RLM_SQL_ERROR;
665 
666  /*
667  * No more rows to process (were done)
668  */
669  if (status == SQLITE_DONE) return RLM_SQL_OK;
670 
671  /*
672  * We only need to do this once per result set, because
673  * the number of columns won't change.
674  */
675  if (conn->col_count == 0) {
676  conn->col_count = sql_num_fields(handle, config);
677  if (conn->col_count == 0) return RLM_SQL_ERROR;
678  }
679 
680  /*
681  * Free the previous result (also gets called on finish_query)
682  */
683  talloc_free(handle->row);
684  MEM(row = handle->row = talloc_zero_array(handle->conn, char *, conn->col_count + 1));
685 
686  for (i = 0; i < conn->col_count; i++) {
687  switch (sqlite3_column_type(conn->statement, i)) {
688  case SQLITE_INTEGER:
689  MEM(row[i] = talloc_typed_asprintf(row, "%d", sqlite3_column_int(conn->statement, i)));
690  break;
691 
692  case SQLITE_FLOAT:
693  MEM(row[i] = talloc_typed_asprintf(row, "%f", sqlite3_column_double(conn->statement, i)));
694  break;
695 
696  case SQLITE_TEXT:
697  {
698  char const *p;
699  p = (char const *) sqlite3_column_text(conn->statement, i);
700 
701  if (p) MEM(row[i] = talloc_typed_strdup(row, p));
702  }
703  break;
704 
705  case SQLITE_BLOB:
706  {
707  uint8_t const *p;
708  size_t len;
709 
710  p = sqlite3_column_blob(conn->statement, i);
711  if (p) {
712  len = sqlite3_column_bytes(conn->statement, i);
713 
714  MEM(row[i] = talloc_zero_array(row, char, len + 1));
715  memcpy(row[i], p, len);
716  }
717  }
718  break;
719 
720  default:
721  break;
722  }
723  }
724 
725  *out = row;
726 
727  return RLM_SQL_OK;
728 }
729 
731 {
732  rlm_sql_sqlite_conn_t *conn = handle->conn;
733 
734  if (conn->statement) {
735  TALLOC_FREE(handle->row);
736 
737  (void) sqlite3_finalize(conn->statement);
738  conn->statement = NULL;
739  conn->col_count = 0;
740  }
741 
742  /*
743  * There's no point in checking the code returned by finalize
744  * as it'll have already been encountered elsewhere in the code.
745  *
746  * It's just the last error that occurred processing the
747  * statement.
748  */
749  return 0;
750 }
751 
752 /** Retrieves any errors associated with the connection handle
753  *
754  * @note Caller will free any memory allocated in ctx.
755  *
756  * @param ctx to allocate temporary error buffers in.
757  * @param out Array of sql_log_entrys to fill.
758  * @param outlen Length of out array.
759  * @param handle rlm_sql connection handle.
760  * @param config rlm_sql config.
761  * @return number of errors written to the #sql_log_entry_t array.
762  */
763 static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen,
764  rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
765 {
766  rlm_sql_sqlite_conn_t *conn = handle->conn;
767  char const *error;
768 
769  rad_assert(outlen > 0);
770 
771  error = sqlite3_errmsg(conn->db);
772  if (!error) return 0;
773 
774  out[0].type = L_ERR;
775  out[0].msg = error;
776 
777  return 1;
778 }
779 
781 {
782  return sql_free_result(handle, config);
783 }
784 
786  UNUSED rlm_sql_config_t *config)
787 {
788  rlm_sql_sqlite_conn_t *conn = handle->conn;
789 
790  if (conn->db) {
791  return sqlite3_changes(conn->db);
792  }
793 
794  return -1;
795 }
796 
797 
798 /* Exported to rlm_sql */
800 rlm_sql_module_t rlm_sql_sqlite = {
801  .name = "rlm_sql_sqlite",
803  .mod_instantiate = mod_instantiate,
804  .sql_socket_init = sql_socket_init,
805  .sql_query = sql_query,
806  .sql_select_query = sql_select_query,
807  .sql_num_fields = sql_num_fields,
808  .sql_affected_rows = sql_affected_rows,
809  .sql_fetch_row = sql_fetch_row,
810  .sql_fields = sql_fields,
811  .sql_free_result = sql_free_result,
812  .sql_error = sql_error,
813  .sql_finish_query = sql_finish_query,
814  .sql_finish_select_query = sql_finish_query
815 };
static sql_rcode_t sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
static sql_rcode_t sql_check_error(sqlite3 *db, int status)
Determine if an error occurred, and what type of error it was.
General connection/server error.
Definition: rlm_sql.h:46
Prototypes and functions for the SQL module.
char ** rlm_sql_row_t
Definition: rlm_sql.h:59
log_type_t type
Type of log entry L_ERR, L_WARN, L_INFO, L_DBG etc..
Definition: rlm_sql.h:62
#define RLM_SQL_RCODE_FLAGS_ALT_QUERY
Can distinguish between other errors and those.
Definition: rlm_sql.h:164
#define MEM(x)
Definition: radiusd.h:396
#define INFO(fmt,...)
Definition: log.h:143
char const * msg
Log message.
Definition: rlm_sql.h:63
#define UNUSED
Definition: libradius.h:134
Error message.
Definition: log.h:36
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
#define SQLITE_OPEN_NOMUTEX
static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
static float timeout
Definition: radclient.c:43
static sql_rcode_t sql_error_to_rcode(int status)
Convert an sqlite status code to an sql_rcode_t.
int rad_mkdir(char *directory, mode_t mode, uid_t uid, gid_t gid)
Create possibly many directories.
Definition: util.c:90
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
static int mod_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
Definition: conffile.c:3478
char const * cf_pair_value(CONF_PAIR const *pair)
Definition: conffile.c:3506
Key constraint violation.
Definition: rlm_sql.h:49
typedef sqlite3_int64 sqlite_int64 struct rlm_sql_sqlite_conn rlm_sql_sqlite_conn_t
#define rad_assert(expr)
Definition: rad_assert.h:38
Stale connection, should reconnect.
Definition: rlm_sql.h:48
static sql_rcode_t sql_fetch_row(rlm_sql_row_t *out, rlm_sql_handle_t *handle, rlm_sql_config_t *config)
static void CC_HINT(nonnull(3))
char const * name
Definition: rlm_sql.h:191
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
rlm_sql_module_t rlm_sql_sqlite
#define DEBUG(fmt,...)
Definition: log.h:175
sql_rcode_t
Definition: rlm_sql.h:44
static void _sql_greatest(sqlite3_context *ctx, int num_values, sqlite3_value **values)
#define DEBUG2(fmt,...)
Definition: log.h:176
static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Definition: conffile.c:2234
Definition: rlm_sql.h:61
Success.
Definition: rlm_sql.h:47
static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
char * talloc_typed_asprintf(void const *t, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: missing.c:611
CONF_PAIR * cf_pair_find_next(CONF_SECTION const *, CONF_PAIR const *, char const *name)
Find a pair with a name matching attr, after specified pair.
Definition: conffile.c:3673
Configuration AVP similar to a VALUE_PAIR.
Definition: conffile.c:82
void * driver
Where drivers should write a pointer to their configurations.
Definition: rlm_sql.h:135
32 Bit unsigned integer.
Definition: radius.h:34
static rs_t * conf
Definition: radsniff.c:46
void * conn
Database specific connection handle.
Definition: rlm_sql.h:153
rlm_sql_row_t row
Row data from the last query.
Definition: rlm_sql.h:154
static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config, struct timeval const *timeout)
struct rlm_sql_sqlite_config rlm_sql_sqlite_config_t
#define PW_TYPE_FILE_OUTPUT
File matching value must exist, and must be writeable.
Definition: conffile.h:205
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen, rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
Retrieves any errors associated with the connection handle.
#define BOOTSTRAP_MAX
static const CONF_PARSER driver_config[]
#define WARN(fmt,...)
Definition: log.h:144
char const * sql_db
Database to run queries against.
Definition: rlm_sql.h:89
#define PW_TYPE_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: conffile.h:200
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:38
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
static int _sql_socket_destructor(rlm_sql_sqlite_conn_t *conn)
int 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.
Definition: print.c:34
sqlite3_stmt * statement
static int sql_affected_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
char const * get_radius_dir(void)
Get the global radius config directory.
Definition: mainconfig.c:721
#define RCSID(id)
Definition: build.h:135
char * talloc_typed_strdup(void const *t, char const *p)
Call talloc strdup, setting the type on the new chunk correctly.
Definition: missing.c:588
#define ERROR(fmt,...)
Definition: log.h:145
static void sql_print_error(sqlite3 *db, int status, char const *fmt,...) CC_HINT(format(printf
Print an error to the global debug log.
static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)