Merge remote-tracking branch 'origin/upstream_release_3_0_13' into tr-integ-fr-3...
[freeradius.git] / src / modules / rlm_sql / drivers / rlm_sql_sqlite / rlm_sql_sqlite.c
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$
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$")
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 sqlite_int64 sqlite3_int64;
49 #endif
50
51 typedef struct rlm_sql_sqlite_conn {
52         sqlite3 *db;
53         sqlite3_stmt *statement;
54         int col_count;
55 } rlm_sql_sqlite_conn_t;
56
57 typedef struct rlm_sql_sqlite_config {
58         char const      *filename;
59         uint32_t        busy_timeout;
60 } rlm_sql_sqlite_config_t;
61
62 static const CONF_PARSER driver_config[] = {
63         { "filename", FR_CONF_OFFSET(PW_TYPE_FILE_OUTPUT | PW_TYPE_REQUIRED, rlm_sql_sqlite_config_t, filename), NULL },
64         { "busy_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_sql_sqlite_config_t, busy_timeout), "200" },
65         CONF_PARSER_TERMINATOR
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
370 static int mod_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
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
477                         goto unlink;
478                 }
479
480                 if (ret < 0) {
481                 unlink:
482                         if ((unlink(driver->filename) < 0) && (errno != ENOENT)) {
483                                 ERROR("rlm_sql_sqlite: Error removing partially initialised database: %s",
484                                       fr_syserror(errno));
485                         }
486                         return -1;
487                 }
488 #else
489                 WARN("rlm_sql_sqlite: sqlite3_open_v2() not available, cannot bootstrap database. "
490                        "Upgrade to SQLite >= 3.5.1 if you need this functionality");
491 #endif
492         }
493
494         return 0;
495 }
496
497 static int _sql_socket_destructor(rlm_sql_sqlite_conn_t *conn)
498 {
499         int status = 0;
500
501         DEBUG2("rlm_sql_sqlite: Socket destructor called, closing socket");
502
503         if (conn->db) {
504                 status = sqlite3_close(conn->db);
505                 if (status != SQLITE_OK) WARN("rlm_sql_sqlite: Got SQLite error code (%u) when closing socket", status);
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 sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
527 {
528         rlm_sql_sqlite_conn_t *conn;
529         rlm_sql_sqlite_config_t *driver = config->driver;
530
531         int status;
532
533         MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_sqlite_conn_t));
534         talloc_set_destructor(conn, _sql_socket_destructor);
535
536         INFO("rlm_sql_sqlite: Opening SQLite database \"%s\"", driver->filename);
537 #ifdef HAVE_SQLITE3_OPEN_V2
538         status = sqlite3_open_v2(driver->filename, &(conn->db), SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL);
539         sqlite3_busy_timeout( conn->db, 200); /*wait up to 200 ms for db locks*/
540 #else
541         
542         status = sqlite3_open(driver->filename, &(conn->db));
543 #endif
544
545         if (!conn->db || (sql_check_error(conn->db, status) != RLM_SQL_OK)) {
546                 sql_print_error(conn->db, status, "Error opening SQLite database \"%s\"", driver->filename);
547                 return RLM_SQL_ERROR;
548         }
549         status = sqlite3_busy_timeout(conn->db, driver->busy_timeout);
550         if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
551                 sql_print_error(conn->db, status, "Error setting busy timeout");
552                 return RLM_SQL_ERROR;
553         }
554
555         /*
556          *      Enable extended return codes for extra debugging info.
557          */
558 #ifdef HAVE_SQLITE3_EXTENDED_RESULT_CODES
559         status = sqlite3_extended_result_codes(conn->db, 1);
560         if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
561                 sql_print_error(conn->db, status, "Error enabling extended result codes");
562                 return RLM_SQL_ERROR;
563         }
564 #endif
565
566 #ifdef HAVE_SQLITE3_CREATE_FUNCTION_V2
567         status = sqlite3_create_function_v2(conn->db, "GREATEST", -1, SQLITE_ANY, NULL,
568                                             _sql_greatest, NULL, NULL, NULL);
569 #else
570         status = sqlite3_create_function(conn->db, "GREATEST", -1, SQLITE_ANY, NULL,
571                                          _sql_greatest, NULL, NULL);
572 #endif
573         if (sql_check_error(conn->db, status) != RLM_SQL_OK) {
574                 sql_print_error(conn->db, status, "Failed registering 'GREATEST' sql function");
575                 return RLM_SQL_ERROR;
576         }
577
578         return RLM_SQL_OK;
579 }
580
581 static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
582 {
583         rlm_sql_sqlite_conn_t   *conn = handle->conn;
584         char const              *z_tail;
585         int                     status;
586
587 #ifdef HAVE_SQLITE3_PREPARE_V2
588         status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
589 #else
590         status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
591 #endif
592
593         conn->col_count = 0;
594
595         return sql_check_error(conn->db, status);
596 }
597
598
599 static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, char const *query)
600 {
601
602         sql_rcode_t             rcode;
603         rlm_sql_sqlite_conn_t   *conn = handle->conn;
604         char const              *z_tail;
605         int                     status;
606
607 #ifdef HAVE_SQLITE3_PREPARE_V2
608         status = sqlite3_prepare_v2(conn->db, query, strlen(query), &conn->statement, &z_tail);
609 #else
610         status = sqlite3_prepare(conn->db, query, strlen(query), &conn->statement, &z_tail);
611 #endif
612         rcode = sql_check_error(conn->db, status);
613         if (rcode != RLM_SQL_OK) return rcode;
614
615         status = sqlite3_step(conn->statement);
616         return sql_check_error(conn->db, status);
617 }
618
619 static int sql_num_fields(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
620 {
621         rlm_sql_sqlite_conn_t *conn = handle->conn;
622
623         if (conn->statement) {
624                 return sqlite3_column_count(conn->statement);
625         }
626
627         return 0;
628 }
629
630 static int sql_num_rows(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
631 {
632         rlm_sql_sqlite_conn_t *conn = handle->conn;
633
634         if (conn->statement) {
635                 return sqlite3_data_count(conn->statement);
636         }
637
638         return 0;
639 }
640
641 static sql_rcode_t sql_fields(char const **out[], rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
642 {
643         rlm_sql_sqlite_conn_t *conn = handle->conn;
644
645         int             fields, i;
646         char const      **names;
647
648         fields = sqlite3_column_count(conn->statement);
649         if (fields <= 0) return RLM_SQL_ERROR;
650
651         MEM(names = talloc_zero_array(handle, char const *, fields + 1));
652
653         for (i = 0; i < fields; i++) names[i] = sqlite3_column_name(conn->statement, i);
654         *out = names;
655
656         return RLM_SQL_OK;
657 }
658
659 static sql_rcode_t sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
660 {
661         int status;
662         rlm_sql_sqlite_conn_t *conn = handle->conn;
663
664         int i = 0;
665
666         char **row;
667
668         TALLOC_FREE(handle->row);
669
670         /*
671          *      Executes the SQLite query and interates over the results
672          */
673         status = sqlite3_step(conn->statement);
674
675         /*
676          *      Error getting next row
677          */
678         if (sql_check_error(conn->db, status) != RLM_SQL_OK) return RLM_SQL_ERROR;
679
680         /*
681          *      No more rows to process (were done)
682          */
683         if (status == SQLITE_DONE) return RLM_SQL_NO_MORE_ROWS;
684
685         /*
686          *      We only need to do this once per result set, because
687          *      the number of columns won't change.
688          */
689         if (conn->col_count == 0) {
690                 conn->col_count = sql_num_fields(handle, config);
691                 if (conn->col_count == 0) return RLM_SQL_ERROR;
692         }
693
694         MEM(row = handle->row = talloc_zero_array(handle->conn, char *, conn->col_count + 1));
695
696         for (i = 0; i < conn->col_count; i++) {
697                 switch (sqlite3_column_type(conn->statement, i)) {
698                 case SQLITE_INTEGER:
699                         MEM(row[i] = talloc_typed_asprintf(row, "%d", sqlite3_column_int(conn->statement, i)));
700                         break;
701
702                 case SQLITE_FLOAT:
703                         MEM(row[i] = talloc_typed_asprintf(row, "%f", sqlite3_column_double(conn->statement, i)));
704                         break;
705
706                 case SQLITE_TEXT:
707                 {
708                         char const *p;
709                         p = (char const *) sqlite3_column_text(conn->statement, i);
710
711                         if (p) MEM(row[i] = talloc_typed_strdup(row, p));
712                 }
713                         break;
714
715                 case SQLITE_BLOB:
716                 {
717                         uint8_t const *p;
718                         size_t len;
719
720                         p = sqlite3_column_blob(conn->statement, i);
721                         if (p) {
722                                 len = sqlite3_column_bytes(conn->statement, i);
723
724                                 MEM(row[i] = talloc_zero_array(row, char, len + 1));
725                                 memcpy(row[i], p, len);
726                         }
727                 }
728                         break;
729
730                 default:
731                         break;
732                 }
733         }
734
735         return RLM_SQL_OK;
736 }
737
738 static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
739 {
740         rlm_sql_sqlite_conn_t *conn = handle->conn;
741
742         if (conn->statement) {
743                 TALLOC_FREE(handle->row);
744
745                 (void) sqlite3_finalize(conn->statement);
746                 conn->statement = NULL;
747                 conn->col_count = 0;
748         }
749
750         /*
751          *      There's no point in checking the code returned by finalize
752          *      as it'll have already been encountered elsewhere in the code.
753          *
754          *      It's just the last error that occurred processing the
755          *      statement.
756          */
757         return RLM_SQL_OK;
758 }
759
760 /** Retrieves any errors associated with the connection handle
761  *
762  * @note Caller will free any memory allocated in ctx.
763  *
764  * @param ctx to allocate temporary error buffers in.
765  * @param out Array of sql_log_entrys to fill.
766  * @param outlen Length of out array.
767  * @param handle rlm_sql connection handle.
768  * @param config rlm_sql config.
769  * @return number of errors written to the sql_log_entry array.
770  */
771 static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen,
772                         rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
773 {
774         rlm_sql_sqlite_conn_t *conn = handle->conn;
775         char const *error;
776
777         rad_assert(outlen > 0);
778
779         error = sqlite3_errmsg(conn->db);
780         if (!error) return 0;
781
782         out[0].type = L_ERR;
783         out[0].msg = error;
784
785         return 1;
786 }
787
788 static sql_rcode_t sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
789 {
790         return sql_free_result(handle, config);
791 }
792
793 static int sql_affected_rows(rlm_sql_handle_t *handle,
794                              UNUSED rlm_sql_config_t *config)
795 {
796         rlm_sql_sqlite_conn_t *conn = handle->conn;
797
798         if (conn->db) return sqlite3_changes(conn->db);
799
800         return -1;
801 }
802
803
804 /* Exported to rlm_sql */
805 extern rlm_sql_module_t rlm_sql_sqlite;
806 rlm_sql_module_t rlm_sql_sqlite = {
807         .name                           = "rlm_sql_sqlite",
808         .flags                          = RLM_SQL_RCODE_FLAGS_ALT_QUERY,
809         .mod_instantiate                = mod_instantiate,
810         .sql_socket_init                = sql_socket_init,
811         .sql_query                      = sql_query,
812         .sql_select_query               = sql_select_query,
813         .sql_num_fields                 = sql_num_fields,
814         .sql_num_rows                   = sql_num_rows,
815         .sql_affected_rows              = sql_affected_rows,
816         .sql_fetch_row                  = sql_fetch_row,
817         .sql_fields                     = sql_fields,
818         .sql_free_result                = sql_free_result,
819         .sql_error                      = sql_error,
820         .sql_finish_query               = sql_finish_query,
821         .sql_finish_select_query        = sql_finish_query
822 };