The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 51cd8ff821b7cf12459aa663f263f9b9039355c4 $
19  * @file rlm_sql_sqlite.c
20  * @brief SQLite driver.
21  *
22  * @copyright 2013 Network RADIUS SAS (legal@networkradius.com)
23  * @copyright 2007 Apple Inc.
24  */
25 RCSID("$Id: 51cd8ff821b7cf12459aa663f263f9b9039355c4 $")
26 
27 #define LOG_PREFIX "sql - sqlite"
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/util/debug.h>
30 
31 #include <fcntl.h>
32 #include <sys/stat.h>
33 
34 #include <sqlite3.h>
35 
36 #include "rlm_sql.h"
37 #include "rlm_sql_trunk.h"
38 #include "config.h"
39 
40 #define BOOTSTRAP_MAX (1048576 * 10)
41 
42 /*
43  * Allow us to use versions < 3.6.0 beta0
44  */
45 #ifndef SQLITE_OPEN_NOMUTEX
46 # define SQLITE_OPEN_NOMUTEX 0
47 #endif
48 
49 #ifndef HAVE_SQLITE3_INT64
50 typedef sqlite_int64 sqlite3_int64;
51 #endif
52 
53 typedef struct {
54  sqlite3 *db;
55  sqlite3_stmt *statement;
56  int col_count;
58 
59 typedef struct {
60  char const *filename;
61  bool bootstrap;
63 
64 static const conf_parser_t driver_config[] = {
67 };
68 
69 /** Convert an sqlite status code to an sql_rcode_t
70  *
71  * @param status to convert.
72  * @return
73  * - RLM_SQL_OK - If no errors found.
74  * - RLM_SQL_ERROR - If a known, non-fatal, error occurred.
75  * - RLM_SQL_ALT_QUERY - If a constraints violation occurred.
76  * - RLM_SQL_RECONNECT - Anything else, we assume the connection can no longer be used.
77  */
78 static sql_rcode_t sql_error_to_rcode(int status)
79 {
80  /*
81  * Lowest byte is error category, other byte may contain
82  * the extended error, depending on version.
83  */
84  switch (status & 0xff) {
85  /*
86  * Not errors
87  */
88  case SQLITE_OK:
89  case SQLITE_DONE:
90  case SQLITE_ROW:
91  return RLM_SQL_OK;
92  /*
93  * User/transient errors
94  */
95  case SQLITE_ERROR: /* SQL error or missing database */
96  case SQLITE_FULL:
97  case SQLITE_MISMATCH:
98  case SQLITE_BUSY: /* Can be caused by database locking */
99  return RLM_SQL_ERROR;
100 
101  /*
102  * Constraints violations
103  */
104  case SQLITE_CONSTRAINT:
105  return RLM_SQL_ALT_QUERY;
106 
107  /*
108  * Errors with the handle, that probably require reinitialisation
109  */
110  default:
111  return RLM_SQL_RECONNECT;
112  }
113 }
114 
115 /** Determine if an error occurred, and what type of error it was
116  *
117  * @param db handle to extract error from (may be NULL).
118  * @param status to check (if unused, set to SQLITE_OK).
119  * @return
120  * - RLM_SQL_OK - If no errors found.
121  * - RLM_SQL_ERROR - If a known, non-fatal, error occurred.
122  * - RLM_SQL_ALT_QUERY - If a constraints violation occurred.
123  * - RLM_SQL_RECONNECT - Anything else. We assume the connection can no longer be used.
124  */
125 static sql_rcode_t sql_check_error(sqlite3 *db, int status)
126 {
127  int hstatus = SQLITE_OK;
128 
129  if (db) {
130  hstatus = sqlite3_errcode(db);
131  switch (hstatus & 0xff) {
132  case SQLITE_OK:
133  case SQLITE_DONE:
134  case SQLITE_ROW:
135  hstatus = SQLITE_OK;
136  break;
137 
138  default:
139  break;
140  }
141  }
142 
143  switch (status & 0xff) {
144  case SQLITE_OK:
145  case SQLITE_DONE:
146  case SQLITE_ROW:
147  status = SQLITE_OK;
148  break;
149 
150  default:
151  break;
152  }
153 
154  if (status != SQLITE_OK) return sql_error_to_rcode(status);
155  if (hstatus != SQLITE_OK) return sql_error_to_rcode(hstatus);
156 
157  return RLM_SQL_OK;
158 }
159 
160 /** Print an error to the global debug log
161  *
162  * If status does not indicate success, write an error to the global error log.
163  *
164  * @note The error code will be appended to the fmt string in the format ": code 0x<hex> (<int>)[: <string>]".
165  *
166  * @param db handle to extract error from (may be NULL).
167  * @param status to check (if unused, set to SQLITE_OK).
168  * @param fmt to prepend.
169  * @param ... arguments to fmt.
170  */
171 static void sql_print_error(sqlite3 *db, int status, char const *fmt, ...)
172  CC_HINT(format (printf, 3, 4)) CC_HINT(nonnull (3));
173 static void sql_print_error(sqlite3 *db, int status, char const *fmt, ...)
174 {
175  va_list ap;
176  char *p;
177  int hstatus = SQLITE_OK;
178 
179  if (db) {
180  hstatus = sqlite3_errcode(db);
181  switch (hstatus & 0xff) {
182  case SQLITE_OK:
183  case SQLITE_DONE:
184  case SQLITE_ROW:
185  hstatus = SQLITE_OK;
186  break;
187 
188  default:
189  break;
190  }
191  }
192 
193  switch (status & 0xff) {
194  case SQLITE_OK:
195  case SQLITE_DONE:
196  case SQLITE_ROW:
197  status = SQLITE_OK;
198  break;
199 
200  default:
201  break;
202  }
203 
204  /*
205  * No errors!
206  */
207  if ((hstatus == SQLITE_OK) && (status == SQLITE_OK)) return;
208 
209  /*
210  * At least one error...
211  */
212  va_start(ap, fmt);
213  MEM(p = talloc_vasprintf(NULL, fmt, ap));
214  va_end(ap);
215 
216  /*
217  * Disagreement between handle, and function return code,
218  * print them both.
219  */
220  if ((status != SQLITE_OK) && (status != hstatus)) {
221  ERROR("%s: Code 0x%04x (%i): %s", p, status, status, sqlite3_errstr(status));
222  }
223 
224  if (hstatus != SQLITE_OK) ERROR("%s: Code 0x%04x (%i): %s",
225  p, hstatus, hstatus, sqlite3_errmsg(db));
226 }
227 
228 static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
229 {
230  ssize_t len;
231  int statement_len, statement_cnt = 0;
232  char *buffer;
233  char const *p;
234  int cl;
235  FILE *f;
236  struct stat finfo;
237 
238  int status;
239  sqlite3_stmt *statement;
240  char const *z_tail;
241 
242  INFO("Executing SQL statements from file \"%s\"", filename);
243 
244  f = fopen(filename, "r");
245  if (!f) {
246  ERROR("Failed opening SQL file \"%s\": %s", filename,
247  fr_syserror(errno));
248 
249  return -1;
250  }
251 
252  if (fstat(fileno(f), &finfo) < 0) {
253  ERROR("Failed stating SQL file \"%s\": %s", filename,
254  fr_syserror(errno));
255 
256  fclose(f);
257 
258  return -1;
259  }
260 
261  if (finfo.st_size > BOOTSTRAP_MAX) {
262  too_big:
263  ERROR("Size of SQL (%zu) file exceeds limit (%uk)",
264  (size_t) finfo.st_size / 1024, BOOTSTRAP_MAX / 1024);
265 
266  fclose(f);
267 
268  return -1;
269  }
270 
271  MEM(buffer = talloc_array(ctx, char, finfo.st_size + 1));
272  len = fread(buffer, sizeof(char), finfo.st_size, f);
273  if (len > finfo.st_size) {
275  goto too_big;
276  }
277 
278  if (!len) {
279  if (ferror(f)) {
280  ERROR("Error reading SQL file: %s", fr_syserror(errno));
281 
282  fclose(f);
284 
285  return -1;
286  }
287 
288  DEBUG("Ignoring empty SQL file");
289 
290  fclose(f);
292 
293  return 0;
294  }
295 
296  buffer[len] = '\0';
297  fclose(f);
298 
299  /*
300  * Check if input data is UTF-8. Allow CR/LF \t, too.
301  */
302  for (p = buffer; p < (buffer + len); p += cl) {
303  if (*p < ' ') {
304  if ((*p != 0x0a) && (*p != 0x0d) && (*p != '\t')) break;
305  cl = 1;
306  } else {
307  cl = fr_utf8_char((uint8_t const *) p, -1);
308  if (!cl) break;
309  }
310  }
311 
312  if ((p - buffer) != len) {
313  ERROR("Bootstrap file contains non-UTF8 char at offset %zu", p - buffer);
315  return -1;
316  }
317 
318  p = buffer;
319  while (*p) {
320  statement_len = len - (p - buffer);
321  status = sqlite3_prepare_v2(db, p, statement_len, &statement, &z_tail);
322 
323  if (sql_check_error(db, status) != RLM_SQL_OK) {
324  sql_print_error(db, status, "Failed preparing statement %i", statement_cnt);
326  return -1;
327  }
328 
329  /*
330  * No SQL statement was found
331  */
332  if (!statement) break;
333 
334  status = sqlite3_step(statement);
335  if (sql_check_error(db, status) != RLM_SQL_OK) {
336  sql_print_error(db, status, "Failed executing statement %i", statement_cnt);
337  sqlite3_finalize(statement);
339  return -1;
340  }
341 
342  status = sqlite3_finalize(statement);
343  if (sql_check_error(db, status) != RLM_SQL_OK) {
344  sql_print_error(db, status, "Failed finalizing statement %i", statement_cnt);
346  return -1;
347  }
348 
349  statement_cnt++;
350  p = z_tail;
351  }
352 
354  return 0;
355 }
356 
357 static void _sql_greatest(sqlite3_context *ctx, int num_values, sqlite3_value **values)
358 {
359  int i;
360  sqlite3_int64 value, max = 0;
361 
362  for (i = 0; i < num_values; i++) {
363  value = sqlite3_value_int64(values[i]);
364  if (value > max) {
365  max = value;
366  }
367  }
368 
369  sqlite3_result_int64(ctx, max);
370 }
371 
372 CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function*/
373 static connection_state_t _sql_connection_init(void **h, connection_t *conn, void *uctx)
374 {
376  rlm_sql_sqlite_t *inst = talloc_get_type_abort(sql->driver_submodule->data, rlm_sql_sqlite_t);
378  rlm_sql_config_t const *config = &sql->config;
379  int status;
380 
381  MEM(c = talloc_zero(conn, rlm_sql_sqlite_conn_t));
382 
383  INFO("Opening SQLite database \"%s\"", inst->filename);
384  status = sqlite3_open_v2(inst->filename, &(c->db), SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL);
385 
386  if (!c->db || (sql_check_error(c->db, status) != RLM_SQL_OK)) {
387  sql_print_error(c->db, status, "Error opening SQLite database \"%s\"", inst->filename);
388  if (!inst->bootstrap) {
389  INFO("Use the sqlite driver 'bootstrap' option to automatically create the database file");
390  }
391  error:
392  talloc_free(c);
394  }
395  status = sqlite3_busy_timeout(c->db, fr_time_delta_to_sec(config->query_timeout));
396  if (sql_check_error(c->db, status) != RLM_SQL_OK) {
397  sql_print_error(c->db, status, "Error setting busy timeout");
398  goto error;
399  }
400 
401  /*
402  * Enable extended return codes for extra debugging info.
403  */
404  status = sqlite3_extended_result_codes(c->db, 1);
405  if (sql_check_error(c->db, status) != RLM_SQL_OK) {
406  sql_print_error(c->db, status, "Error enabling extended result codes");
407  goto error;
408  }
409 
410  status = sqlite3_create_function_v2(c->db, "GREATEST", -1, SQLITE_ANY, NULL,
411  _sql_greatest, NULL, NULL, NULL);
412  if (sql_check_error(c->db, status) != RLM_SQL_OK) {
413  sql_print_error(c->db, status, "Failed registering 'GREATEST' sql function");
414  goto error;
415  }
416 
417  *h = c;
418 
420 }
421 
423 {
424  rlm_sql_sqlite_conn_t *c = talloc_get_type_abort(h, rlm_sql_sqlite_conn_t);
425  int status = 0;
426 
427  DEBUG2("Socket destructor called, closing socket");
428 
429  if (c->db) {
430  status = sqlite3_close(c->db);
431  if (status != SQLITE_OK) WARN("Got SQLite error when closing socket: %s",
432  sqlite3_errmsg(c->db));
433  }
434 }
435 
436 static sql_rcode_t sql_fields(char const **out[], fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
437 {
438  rlm_sql_sqlite_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_sqlite_conn_t);
439 
440  int fields, i;
441  char const **names;
442 
443  fields = sqlite3_column_count(conn->statement);
444  if (fields <= 0) return RLM_SQL_ERROR;
445 
446  MEM(names = talloc_array(query_ctx, char const *, fields));
447 
448  for (i = 0; i < fields; i++) names[i] = sqlite3_column_name(conn->statement, i);
449  *out = names;
450 
451  return RLM_SQL_OK;
452 }
453 
454 static unlang_action_t sql_fetch_row(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
455 {
456  fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t);
457  int status, i = 0;
458  rlm_sql_sqlite_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_sqlite_conn_t);
459  char **row;
460 
461  TALLOC_FREE(query_ctx->row);
462 
463  /*
464  * Executes the SQLite query and iterates over the results
465  */
466  status = sqlite3_step(conn->statement);
467 
468  /*
469  * Error getting next row
470  */
471  if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
472  error:
473  query_ctx->rcode = RLM_SQL_ERROR;
475  }
476 
477  /*
478  * No more rows to process (we're done)
479  */
480  if (status == SQLITE_DONE) {
481  query_ctx->rcode = RLM_SQL_NO_MORE_ROWS;
483  }
484 
485  /*
486  * We only need to do this once per result set, because
487  * the number of columns won't change.
488  */
489  if (conn->col_count == 0) {
490  conn->col_count = sqlite3_column_count(conn->statement);
491  if (conn->col_count == 0) goto error;
492  }
493 
494  /*
495  * Free the previous result (also gets called on finish_query)
496  */
497  MEM(row = query_ctx->row = talloc_zero_array(query_ctx, char *, conn->col_count + 1));
498 
499  for (i = 0; i < conn->col_count; i++) {
500  switch (sqlite3_column_type(conn->statement, i)) {
501  case SQLITE_INTEGER:
502  MEM(row[i] = talloc_typed_asprintf(row, "%d", sqlite3_column_int(conn->statement, i)));
503  break;
504 
505  case SQLITE_FLOAT:
506  MEM(row[i] = talloc_typed_asprintf(row, "%f", sqlite3_column_double(conn->statement, i)));
507  break;
508 
509  case SQLITE_TEXT:
510  {
511  char const *p;
512  p = (char const *) sqlite3_column_text(conn->statement, i);
513 
514  if (p) MEM(row[i] = talloc_typed_strdup(row, p));
515  }
516  break;
517 
518  case SQLITE_BLOB:
519  {
520  uint8_t const *p;
521  size_t len;
522 
523  p = sqlite3_column_blob(conn->statement, i);
524  if (p) {
525  len = sqlite3_column_bytes(conn->statement, i);
526 
527  MEM(row[i] = talloc_zero_array(row, char, len + 1));
528  memcpy(row[i], p, len);
529  }
530  }
531  break;
532 
533  default:
534  break;
535  }
536  }
537 
538  query_ctx->rcode = RLM_SQL_OK;
540 }
541 
543 {
544  rlm_sql_sqlite_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_sqlite_conn_t);
545 
546  if (conn->statement) {
547  TALLOC_FREE(query_ctx->row);
548 
549  (void) sqlite3_finalize(conn->statement);
550  conn->statement = NULL;
551  conn->col_count = 0;
552  }
553 
554  /*
555  * There's no point in checking the code returned by finalize
556  * as it'll have already been encountered elsewhere in the code.
557  *
558  * It's just the last error that occurred processing the
559  * statement.
560  */
561  return RLM_SQL_OK;
562 }
563 
564 /** Retrieves any errors associated with the query context
565  *
566  * @note Caller will free any memory allocated in ctx.
567  *
568  * @param ctx to allocate temporary error buffers in.
569  * @param out Array of sql_log_entrys to fill.
570  * @param outlen Length of out array.
571  * @param query_ctx Query context to retrieve error for.
572  * @param config rlm_sql config.
573  * @return number of errors written to the #sql_log_entry_t array.
574  */
575 static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], NDEBUG_UNUSED size_t outlen,
576  fr_sql_query_t *query_ctx)
577 {
578  rlm_sql_sqlite_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_sqlite_conn_t);
579  char const *error;
580 
581  fr_assert(outlen > 0);
582 
583  error = sqlite3_errmsg(conn->db);
584  if (!error) return 0;
585 
586  out[0].type = L_ERR;
587  out[0].msg = error;
588 
589  return 1;
590 }
591 
593 {
594  return sql_free_result(query_ctx, config);
595 }
596 
597 static int sql_affected_rows(fr_sql_query_t *query_ctx,
599 {
600  rlm_sql_sqlite_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_sqlite_conn_t);
601 
602  if (conn->db) return sqlite3_changes(conn->db);
603 
604  return -1;
605 }
606 
608 
609 CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function*/
610 static void sql_trunk_request_mux(UNUSED fr_event_list_t *el, trunk_connection_t *tconn,
611  connection_t *conn, UNUSED void *uctx)
612 {
613  rlm_sql_sqlite_conn_t *sql_conn = talloc_get_type_abort(conn->h, rlm_sql_sqlite_conn_t);
614  trunk_request_t *treq;
615  request_t *request;
616  fr_sql_query_t *query_ctx;
617  int status;
618  char const *z_tail;
619 
620  if (trunk_connection_pop_request(&treq, tconn) != 0) return;
621  if (!treq) return;
622 
623  query_ctx = talloc_get_type_abort(treq->preq, fr_sql_query_t);
624  request = query_ctx->request;
625  query_ctx->tconn = tconn;
626 
627  ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query_ctx->query_str);
628  status = sqlite3_prepare_v2(sql_conn->db, query_ctx->query_str, strlen(query_ctx->query_str),
629  &sql_conn->statement, &z_tail);
630  query_ctx->rcode = sql_check_error(sql_conn->db, status);
631  if (query_ctx->rcode != RLM_SQL_OK) {
632  error:
633  query_ctx->status = SQL_QUERY_FAILED;
635  return;
636  }
637 
638  if (query_ctx->type == SQL_QUERY_OTHER) {
639  status = sqlite3_step(sql_conn->statement);
640  query_ctx->rcode = sql_check_error(sql_conn->db, status);
641  if (query_ctx->rcode == RLM_SQL_ERROR) goto error;
642  }
643 
645 }
646 
648 
649 static void sql_request_fail(UNUSED request_t *request, void *preq, UNUSED void *rctx,
651 {
652  fr_sql_query_t *query_ctx = talloc_get_type_abort(preq, fr_sql_query_t);
653 
654  query_ctx->treq = NULL;
655  if (query_ctx->rcode == RLM_SQL_OK) query_ctx->rcode = RLM_SQL_ERROR;
656 }
657 
658 static void sql_request_complete(UNUSED request_t *request, void *preq, UNUSED void *rctx, UNUSED void *uctx)
659 {
660  fr_sql_query_t *query_ctx = talloc_get_type_abort(preq, fr_sql_query_t);
661 
662  sql_free_result(query_ctx, NULL);
663 }
664 
665 static int mod_instantiate(module_inst_ctx_t const *mctx)
666 {
667  rlm_sql_t const *parent = talloc_get_type_abort(mctx->mi->parent->data, rlm_sql_t);
668  rlm_sql_config_t const *config = &parent->config;
669  rlm_sql_sqlite_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sql_sqlite_t);
670  bool exists;
671  struct stat buf;
672  int fd;
673  char const *r;
674 
675  if (!inst->filename) {
676  MEM(inst->filename = talloc_typed_asprintf(inst, "%s/%s",
677  main_config->raddb_dir, config->sql_db));
678  }
679 
680  /*
681  * We will try to create the database if it doesn't exist, up to and
682  * including creating the directory it should live in, in which case
683  * we get to call fr_dirfd() again. Hence failing this first fr_dirfd()
684  * just means the database isn't there.
685  */
686  if (fr_dirfd(&fd, &r, inst->filename) < 0) {
687  exists = false;
688  } else if (fstatat(fd, r, &buf, 0) == 0) {
689  exists = true;
690  } else if (errno == ENOENT) {
691  exists = false;
692  } else {
693  ERROR("Database exists, but couldn't be opened: %s", fr_syserror(errno));
694  close(fd);
695  return -1;
696  }
697 
698  if (cf_pair_find(mctx->mi->conf, "bootstrap")) {
699  inst->bootstrap = true;
700  }
701 
702  if (inst->bootstrap && !exists) {
703  int status;
704  int ret;
705  char const *p;
706  char *buff;
707  sqlite3 *db = NULL;
708  CONF_PAIR *cp;
709 
710  INFO("Database \"%s\" doesn't exist, creating it and loading schema", inst->filename);
711 
712  p = strrchr(inst->filename, '/');
713  if (p) {
714  size_t len = (p - inst->filename) + 1;
715 
716  buff = talloc_array(mctx->mi->conf, char, len);
717  strlcpy(buff, inst->filename, len);
718  } else {
719  MEM(buff = talloc_typed_strdup(mctx->mi->conf, inst->filename));
720  }
721 
722  ret = fr_mkdir(NULL, buff, -1, 0700, NULL, NULL);
723  talloc_free(buff);
724  if (ret < 0) {
725  PERROR("Failed creating directory for SQLite database");
726 
727  return -1;
728  }
729  (void) fr_dirfd(&fd, &r, inst->filename);
730 
731  status = sqlite3_open_v2(inst->filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
732  if (!db) {
733  ERROR("Failed creating opening/creating SQLite database: %s",
734  sqlite3_errstr(status));
735  goto unlink;
736  }
737 
738  if (sql_check_error(db, status) != RLM_SQL_OK) {
739  (void) sqlite3_close(db);
740 
741  goto unlink;
742  }
743 
744  /*
745  * Execute multiple bootstrap SQL files in order
746  */
747  for (cp = cf_pair_find(mctx->mi->conf, "bootstrap");
748  cp;
749  cp = cf_pair_find_next(mctx->mi->conf, cp, "bootstrap")) {
750  p = cf_pair_value(cp);
751  if (!p) continue;
752 
753  ret = sql_loadfile(mctx->mi->conf, db, p);
754  if (ret < 0) {
755  (void) sqlite3_close(db);
756  goto unlink;
757  }
758  }
759 
760  status = sqlite3_close(db);
761  if (status != SQLITE_OK) {
762  /*
763  * Safer to use sqlite3_errstr here, just in case the handle is in a weird state
764  */
765  ERROR("Error closing SQLite handle: %s", sqlite3_errstr(status));
766  goto unlink;
767  }
768 
769  if (ret < 0) {
770  unlink:
771  if ((unlinkat(fd, r, 0) < 0) && (errno != ENOENT)) {
772  ERROR("Error removing partially initialised database: %s",
773  fr_syserror(errno));
774  }
775  close(fd);
776  return -1;
777  }
778  }
779 
780  close(fd);
781  return 0;
782 }
783 
784 static int mod_load(void)
785 {
786  if (sqlite3_libversion_number() != SQLITE_VERSION_NUMBER) {
787  WARN("libsqlite version changed since the server was built");
788  WARN("linked: %s built: %s", sqlite3_libversion(), SQLITE_VERSION);
789  }
790  INFO("libsqlite version: %s", sqlite3_libversion());
791 
792  return 0;
793 }
794 
795 /* Exported to rlm_sql */
798  .common = {
799  .name = "sql_sqlite",
800  .magic = MODULE_MAGIC_INIT,
801  .inst_size = sizeof(rlm_sql_sqlite_t),
803  .onload = mod_load,
805  },
807  .sql_query_resume = sql_query_resume,
808  .sql_select_query_resume = sql_query_resume,
809  .sql_affected_rows = sql_affected_rows,
810  .sql_fetch_row = sql_fetch_row,
811  .sql_fields = sql_fields,
812  .sql_free_result = sql_free_result,
813  .sql_error = sql_error,
814  .sql_finish_query = sql_finish_query,
815  .sql_finish_select_query = sql_finish_query,
816  .uses_trunks = true,
817  .trunk_io_funcs = {
818  .connection_alloc = sql_trunk_connection_alloc,
819  .request_mux = sql_trunk_request_mux,
820  .request_complete = sql_request_complete,
821  .request_fail = sql_request_fail
822  }
823 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
static int const char char buffer[256]
Definition: acutest.h:574
va_end(args)
static int const char * fmt
Definition: acutest.h:573
va_start(args, fmt)
#define RCSID(id)
Definition: build.h:481
#define NDEBUG_UNUSED
Definition: build.h:324
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#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
Definition: cf_parse.h:256
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:405
@ CONF_FLAG_FILE_OUTPUT
File matching value must exist, and must be writable.
Definition: cf_parse.h:413
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
Configuration AVP similar to a fr_pair_t.
Definition: cf_priv.h:70
CONF_PAIR * cf_pair_find(CONF_SECTION const *cs, char const *attr)
Search for a CONF_PAIR with a specific name.
Definition: cf_util.c:1439
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1594
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.
Definition: cf_util.c:1453
connection_state_t
Definition: connection.h:45
@ CONNECTION_STATE_FAILED
Connection has failed.
Definition: connection.h:54
@ CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
Definition: connection.h:52
fr_dcursor_eval_t void const * uctx
Definition: dcursor.h:546
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
Test enumeration values.
Definition: dict_test.h:92
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
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.
Definition: file.c:219
int fr_dirfd(int *dirfd, char const **filename, char const *pathname)
From a pathname, return fd and filename needed for *at() functions.
Definition: file.c:412
#define PERROR(_fmt,...)
Definition: log.h:228
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:528
talloc_free(reap)
Stores all information relating to an event list.
Definition: event.c:411
@ L_ERR
Error message.
Definition: log.h:56
main_config_t const * main_config
Main server configuration.
Definition: main_config.c:69
char const * raddb_dir
Path to raddb directory.
Definition: main_config.h:78
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
module_instance_t * mi
Instance of the module being instantiated.
Definition: module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:50
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.
Definition: print.c:39
static const conf_parser_t config[]
Definition: base.c:183
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define WARN(fmt,...)
Definition: radclient.h:47
#define INFO(fmt,...)
Definition: radict.c:54
#define RETURN_MODULE_OK
Definition: rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1302
Prototypes and functions for the SQL module.
fr_sql_query_status_t status
Status of the query.
Definition: rlm_sql.h:146
trunk_connection_t * tconn
Trunk connection this query is being run on.
Definition: rlm_sql.h:142
fr_sql_query_type_t type
Type of query.
Definition: rlm_sql.h:145
char const * query_str
Query string to run.
Definition: rlm_sql.h:144
request_t * request
Request this query relates to.
Definition: rlm_sql.h:139
sql_rcode_t
Action to take at end of an SQL query.
Definition: rlm_sql.h:44
@ RLM_SQL_ALT_QUERY
Key constraint violation, use an alternative query.
Definition: rlm_sql.h:49
@ RLM_SQL_RECONNECT
Stale connection, should reconnect.
Definition: rlm_sql.h:48
@ RLM_SQL_ERROR
General connection/server error.
Definition: rlm_sql.h:46
@ RLM_SQL_OK
Success.
Definition: rlm_sql.h:47
@ RLM_SQL_NO_MORE_ROWS
No more rows available.
Definition: rlm_sql.h:50
@ SQL_QUERY_OTHER
Definition: rlm_sql.h:122
#define RLM_SQL_RCODE_FLAGS_ALT_QUERY
Can distinguish between other errors and those.
Definition: rlm_sql.h:172
rlm_sql_row_t row
Row data from the last query.
Definition: rlm_sql.h:148
sql_rcode_t rcode
Result code.
Definition: rlm_sql.h:147
trunk_request_t * treq
Trunk request for this query.
Definition: rlm_sql.h:143
@ SQL_QUERY_FAILED
Failed to submit.
Definition: rlm_sql.h:128
Definition: rlm_sql.h:61
static void sql_request_complete(UNUSED request_t *request, void *preq, UNUSED void *rctx, UNUSED void *uctx)
static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], NDEBUG_UNUSED size_t outlen, fr_sql_query_t *query_ctx)
Retrieves any errors associated with the query context.
sqlite_int64 sqlite3_int64
static int mod_load(void)
static sql_rcode_t sql_fields(char const **out[], fr_sql_query_t *query_ctx, UNUSED 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
char const * filename
static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
static unlang_action_t sql_fetch_row(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx)
sqlite3_stmt * statement
static void _sql_connection_close(UNUSED fr_event_list_t *el, void *h, UNUSED void *uctx)
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
#define BOOTSTRAP_MAX
static SQL_QUERY_RESUME void sql_request_fail(UNUSED request_t *request, void *preq, UNUSED void *rctx, UNUSED trunk_request_state_t state, UNUSED void *uctx)
static sql_rcode_t sql_finish_query(fr_sql_query_t *query_ctx, rlm_sql_config_t const *config)
static sql_rcode_t sql_free_result(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
CC_NO_UBSAN(function)
static int sql_affected_rows(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config)
static int mod_instantiate(module_inst_ctx_t const *mctx)
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)
Macros to reduce boilerplate in trunk SQL drivers.
#define SQL_QUERY_RESUME
Definition: rlm_sql_trunk.h:56
#define SQL_TRUNK_CONNECTION_ALLOC
Allocate an SQL trunk connection.
Definition: rlm_sql_trunk.h:35
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
void * data
Module's instance data.
Definition: module.h:271
module_instance_t const * parent
Parent module's instance (if any).
Definition: module.h:337
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
RETURN_MODULE_FAIL
fr_assert(0)
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)
Definition: strlcpy.c:34
module_t common
Common fields for all loadable modules.
Definition: rlm_sql.h:204
module_instance_t * driver_submodule
Driver's submodule.
Definition: rlm_sql.h:245
rlm_sql_config_t config
Definition: rlm_sql.h:238
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:445
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:492
#define talloc_get_type_abort_const
Definition: talloc.h:282
static const char * names[8]
Definition: time.c:617
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
Definition: time.h:647
void trunk_request_signal_fail(trunk_request_t *treq)
Signal that a trunk request failed.
Definition: trunk.c:2120
int trunk_connection_pop_request(trunk_request_t **treq_out, trunk_connection_t *tconn)
Pop a request off a connection's pending queue.
Definition: trunk.c:3861
void trunk_request_signal_reapable(trunk_request_t *treq)
Signal that the request was written to a connection successfully, but no response is expected.
Definition: trunk.c:2065
Associates request queues with a connection.
Definition: trunk.c:131
Wraps a normal request.
Definition: trunk.c:97
trunk_request_state_t
Used for sanity checks and to simplify freeing.
Definition: trunk.h:161
close(uq->fd)
static fr_event_list_t * el
static fr_slen_t parent
Definition: pair.h:851
int nonnull(2, 5))
int format(printf, 5, 0))
static size_t char ** out
Definition: value.h:997