All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sql.c
Go to the documentation of this file.
1 /*
2  * sql.c rlm_sql - FreeRADIUS SQL Module
3  * Main code directly taken from ICRADIUS
4  *
5  * Version: $Id: 6f09ed2bffc0d69fc61cbf43e3bfbd66e9e1854c $
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * Copyright 2001,2006 The FreeRADIUS server project
22  * Copyright 2000 Mike Machado <mike@innercite.com>
23  * Copyright 2000 Alan DeKok <aland@ox.org>
24  * Copyright 2001 Chad Miller <cmiller@surfsouth.com>
25  */
26 
27 RCSID("$Id: 6f09ed2bffc0d69fc61cbf43e3bfbd66e9e1854c $")
28 
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/rad_assert.h>
31 
32 #include <sys/file.h>
33 #include <sys/stat.h>
34 
35 #include <ctype.h>
36 
37 #include "rlm_sql.h"
38 
39 #ifdef HAVE_PTHREAD_H
40 #endif
41 
42 /*
43  * Translate rlm_sql rcodes to humanly
44  * readable reason strings.
45  */
47  { "success", RLM_SQL_OK },
48  { "need alt query", RLM_SQL_ALT_QUERY },
49  { "server error", RLM_SQL_ERROR },
50  { "query invalid", RLM_SQL_QUERY_INVALID },
51  { "no connection", RLM_SQL_RECONNECT },
52  { NULL, 0 }
53 };
54 
55 
57 {
58  rlm_sql_t *inst = conn->inst;
59 
60  rad_assert(inst);
61 
62  exec_trigger(NULL, inst->cs, "modules.sql.close", false);
63 
64  return 0;
65 }
66 
67 void *mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
68 {
69  int rcode;
70  rlm_sql_t *inst = instance;
71  rlm_sql_handle_t *handle;
72 
73  /*
74  * Connections cannot be alloced from the inst or
75  * pool contexts due to threading issues.
76  */
77  handle = talloc_zero(ctx, rlm_sql_handle_t);
78  if (!handle) return NULL;
79 
80  handle->log_ctx = talloc_pool(handle, 2048);
81  if (!handle->log_ctx) {
82  talloc_free(handle);
83  return NULL;
84  }
85 
86  /*
87  * Handle requires a pointer to the SQL inst so the
88  * destructor has access to the module configuration.
89  */
90  handle->inst = inst;
91 
92  /*
93  * When something frees this handle the destructor set by
94  * the driver will be called first, closing any open sockets.
95  * Then we call our destructor to trigger an modules.sql.close
96  * event, then all the memory is freed.
97  */
98  talloc_set_destructor(handle, _mod_conn_free);
99 
100  rcode = (inst->module->sql_socket_init)(handle, inst->config, timeout);
101  if (rcode != 0) {
102  fail:
103  exec_trigger(NULL, inst->cs, "modules.sql.fail", true);
104 
105  /*
106  * Destroy any half opened connections.
107  */
108  talloc_free(handle);
109  return NULL;
110  }
111 
112  if (inst->config->connect_query) {
113  if (rlm_sql_select_query(inst, NULL, &handle, inst->config->connect_query) != RLM_SQL_OK) goto fail;
114  (inst->module->sql_finish_select_query)(handle, inst->config);
115  }
116 
117  exec_trigger(NULL, inst->cs, "modules.sql.open", false);
118  return handle;
119 }
120 
121 /*************************************************************************
122  *
123  * Function: sql_fr_pair_list_afrom_str
124  *
125  * Purpose: Read entries from the database and fill VALUE_PAIR structures
126  *
127  *************************************************************************/
128 int sql_fr_pair_list_afrom_str(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **head, rlm_sql_row_t row)
129 {
130  VALUE_PAIR *vp;
131  char const *ptr, *value;
132  char buf[MAX_STRING_LEN];
133  char do_xlat = 0;
134  FR_TOKEN token, operator = T_EOL;
135 
136  /*
137  * Verify the 'Attribute' field
138  */
139  if (!row[2] || row[2][0] == '\0') {
140  REDEBUG("The 'Attribute' field is empty or NULL, skipping the entire row");
141  return -1;
142  }
143 
144  /*
145  * Verify the 'op' field
146  */
147  if (row[4] != NULL && row[4][0] != '\0') {
148  ptr = row[4];
149  operator = gettoken(&ptr, buf, sizeof(buf), false);
150  if ((operator < T_OP_ADD) ||
151  (operator > T_OP_CMP_EQ)) {
152  REDEBUG("Invalid operator \"%s\" for attribute %s", row[4], row[2]);
153  return -1;
154  }
155 
156  } else {
157  /*
158  * Complain about empty or invalid 'op' field
159  */
160  operator = T_OP_CMP_EQ;
161  REDEBUG("The 'op' field for attribute '%s = %s' is NULL, or non-existent.", row[2], row[3]);
162  REDEBUG("You MUST FIX THIS if you want the configuration to behave as you expect");
163  }
164 
165  /*
166  * The 'Value' field may be empty or NULL
167  */
168  value = row[3];
169  /*
170  * If we have a new-style quoted string, where the
171  * *entire* string is quoted, do xlat's.
172  */
173  if (row[3] != NULL &&
174  ((row[3][0] == '\'') || (row[3][0] == '`') || (row[3][0] == '"')) &&
175  (row[3][0] == row[3][strlen(row[3])-1])) {
176 
177  token = gettoken(&value, buf, sizeof(buf), false);
178  switch (token) {
179  /*
180  * Take the unquoted string.
181  */
184  value = buf;
185  break;
186 
187  /*
188  * Mark the pair to be allocated later.
189  */
191  value = NULL;
192  do_xlat = 1;
193  break;
194 
195  /*
196  * Keep the original string.
197  */
198  default:
199  value = row[3];
200  break;
201  }
202  }
203 
204  /*
205  * Create the pair
206  */
207  vp = fr_pair_make(ctx, NULL, row[2], NULL, operator);
208  if (!vp) {
209  REDEBUG("Failed to create the pair: %s", fr_strerror());
210  return -1;
211  }
212 
213  if (do_xlat) {
214  if (fr_pair_mark_xlat(vp, value) < 0) {
215  REDEBUG("Error marking pair for xlat");
216 
217  talloc_free(vp);
218  return -1;
219  }
220  } else {
221  if (fr_pair_value_from_str(vp, value, -1) < 0) {
222  REDEBUG("Error parsing value: %s", fr_strerror());
223 
224  talloc_free(vp);
225  return -1;
226  }
227  }
228 
229  /*
230  * Add the pair into the packet
231  */
232  fr_pair_add(head, vp);
233  return 0;
234 }
235 
236 /** Call the driver's sql_fetch_row function
237  *
238  * Calls the driver's sql_fetch_row logging any errors. On success, will
239  * write row data to ``(*handle)->row``.
240  *
241  * @param out Where to write row data.
242  * @param inst Instance of #rlm_sql_t.
243  * @param request The Current request, may be NULL.
244  * @param handle Handle to retrieve errors for.
245  * @return
246  * - #RLM_SQL_OK on success.
247  * - other #sql_rcode_t constants on error.
248  */
250 {
251  sql_rcode_t ret;
252 
253  if (!*handle || !(*handle)->conn) return RLM_SQL_ERROR;
254 
255  /*
256  * We can't implement reconnect logic here, because the caller
257  * may require the original connection to free up queries or
258  * result sets associated with that connection.
259  */
260  ret = (inst->module->sql_fetch_row)(out, *handle, inst->config);
261  if (ret < 0) {
262  MOD_ROPTIONAL(RERROR, ERROR, "Error fetching row");
263 
264  rlm_sql_print_error(inst, request, *handle, false);
265  }
266 
267  return ret;
268 }
269 
270 /** Retrieve any errors from the SQL driver
271  *
272  * Retrieves errors from the driver from the last operation and writes them to
273  * to request/global log, in the ERROR, WARN, INFO and DEBUG categories.
274  *
275  * @param inst Instance of rlm_sql.
276  * @param request Current request, may be NULL.
277  * @param handle Handle to retrieve errors for.
278  * @param force_debug Force all errors to be logged as debug messages.
279  */
280 void rlm_sql_print_error(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t *handle, bool force_debug)
281 {
282  char const *driver;
283  sql_log_entry_t log[20];
284  size_t num, i;
285 
286  num = (inst->module->sql_error)(handle->log_ctx, log, (sizeof(log) / sizeof(*log)), handle, inst->config);
287  if (num == 0) {
288  MOD_ROPTIONAL(RERROR, ERROR, "Unknown error");
289  return;
290  }
291 
292  driver = inst->config->sql_driver_name;
293 
294  for (i = 0; i < num; i++) {
295  if (force_debug) goto debug;
296 
297  switch (log[i].type) {
298  case L_ERR:
299  MOD_ROPTIONAL(RERROR, ERROR, "%s: %s", driver, log[i].msg);
300  break;
301 
302  case L_WARN:
303  MOD_ROPTIONAL(RWARN, WARN, "%s: %s", driver, log[i].msg);
304  break;
305 
306  case L_INFO:
307  MOD_ROPTIONAL(RINFO, INFO, "%s: %s", driver, log[i].msg);
308  break;
309 
310  case L_DBG:
311  default:
312  debug:
313  MOD_ROPTIONAL(RDEBUG, DEBUG, "%s: %s", driver, log[i].msg);
314  break;
315  }
316  }
317 
318  talloc_free_children(handle->log_ctx);
319 }
320 
321 /** Call the driver's sql_query method, reconnecting if necessary.
322  *
323  * @note Caller must call ``(inst->module->sql_finish_query)(handle, inst->config);``
324  * after they're done with the result.
325  *
326  * @param handle to query the database with. *handle should not be NULL, as this indicates
327  * previous reconnection attempt has failed.
328  * @param request Current request.
329  * @param inst #rlm_sql_t instance data.
330  * @param query to execute. Should not be zero length.
331  * @return
332  * - #RLM_SQL_OK on success.
333  * - #RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL).
334  * - #RLM_SQL_QUERY_INVALID, #RLM_SQL_ERROR on invalid query or connection error.
335  * - #RLM_SQL_ALT_QUERY on constraints violation.
336  */
337 sql_rcode_t rlm_sql_query(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query)
338 {
339  int ret = RLM_SQL_ERROR;
340  int i, count;
341 
342  /* Caller should check they have a valid handle */
343  rad_assert(*handle);
344 
345  /* There's no query to run, return an error */
346  if (query[0] == '\0') {
347  if (request) REDEBUG("Zero length query");
348  return RLM_SQL_QUERY_INVALID;
349  }
350 
351  /*
352  * inst->pool may be NULL is this function is called by mod_conn_create.
353  */
354  count = inst->pool ? fr_connection_pool_state(inst->pool)->num : 0;
355 
356  /*
357  * Here we try with each of the existing connections, then try to create
358  * a new connection, then give up.
359  */
360  for (i = 0; i < (count + 1); i++) {
361  MOD_ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query);
362 
363  ret = (inst->module->sql_query)(*handle, inst->config, query);
364  switch (ret) {
365  case RLM_SQL_OK:
366  break;
367 
368  /*
369  * Run through all available sockets until we exhaust all existing
370  * sockets in the pool and fail to establish a *new* connection.
371  */
372  case RLM_SQL_RECONNECT:
373  *handle = fr_connection_reconnect(inst->pool, *handle);
374  /* Reconnection failed */
375  if (!*handle) return RLM_SQL_RECONNECT;
376  /* Reconnection succeeded, try again with the new handle */
377  continue;
378 
379  /*
380  * These are bad and should make rlm_sql return invalid
381  */
383  rlm_sql_print_error(inst, request, *handle, false);
384  (inst->module->sql_finish_query)(*handle, inst->config);
385  break;
386 
387  /*
388  * Server or client errors.
389  *
390  * If the driver claims to be able to distinguish between
391  * duplicate row errors and other errors, and we hit a
392  * general error treat it as a failure.
393  *
394  * Otherwise rewrite it to RLM_SQL_ALT_QUERY.
395  */
396  case RLM_SQL_ERROR:
398  rlm_sql_print_error(inst, request, *handle, false);
399  (inst->module->sql_finish_query)(*handle, inst->config);
400  break;
401  }
402  ret = RLM_SQL_ALT_QUERY;
403  /* FALL-THROUGH */
404 
405  /*
406  * Driver suggested using an alternative query
407  */
408  case RLM_SQL_ALT_QUERY:
409  rlm_sql_print_error(inst, request, *handle, true);
410  (inst->module->sql_finish_query)(*handle, inst->config);
411  break;
412 
413  }
414 
415  return ret;
416  }
417 
418  MOD_ROPTIONAL(RERROR, ERROR, "Hit reconnection limit");
419 
420  return RLM_SQL_ERROR;
421 }
422 
423 /** Call the driver's sql_select_query method, reconnecting if necessary.
424  *
425  * @note Caller must call ``(inst->module->sql_finish_select_query)(handle, inst->config);``
426  * after they're done with the result.
427  *
428  * @param inst #rlm_sql_t instance data.
429  * @param request Current request.
430  * @param handle to query the database with. *handle should not be NULL, as this indicates
431  * previous reconnection attempt has failed.
432  * @param query to execute. Should not be zero length.
433  * @return
434  * - #RLM_SQL_OK on success.
435  * - #RLM_SQL_RECONNECT if a new handle is required (also sets *handle = NULL).
436  * - #RLM_SQL_QUERY_INVALID, #RLM_SQL_ERROR on invalid query or connection error.
437  */
438 sql_rcode_t rlm_sql_select_query(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query)
439 {
440  int ret = RLM_SQL_ERROR;
441  int i, count;
442 
443  /* Caller should check they have a valid handle */
444  rad_assert(*handle);
445 
446  /* There's no query to run, return an error */
447  if (query[0] == '\0') {
448  if (request) REDEBUG("Zero length query");
449 
450  return RLM_SQL_QUERY_INVALID;
451  }
452 
453  /*
454  * inst->pool may be NULL is this function is called by mod_conn_create.
455  */
456  count = inst->pool ? fr_connection_pool_state(inst->pool)->num : 0;
457 
458  /*
459  * For sanity, for when no connections are viable, and we can't make a new one
460  */
461  for (i = 0; i < (count + 1); i++) {
462  MOD_ROPTIONAL(RDEBUG2, DEBUG2, "Executing select query: %s", query);
463 
464  ret = (inst->module->sql_select_query)(*handle, inst->config, query);
465  switch (ret) {
466  case RLM_SQL_OK:
467  break;
468 
469  /*
470  * Run through all available sockets until we exhaust all existing
471  * sockets in the pool and fail to establish a *new* connection.
472  */
473  case RLM_SQL_RECONNECT:
474  *handle = fr_connection_reconnect(inst->pool, *handle);
475  /* Reconnection failed */
476  if (!*handle) return RLM_SQL_RECONNECT;
477  /* Reconnection succeeded, try again with the new handle */
478  continue;
479 
481  case RLM_SQL_ERROR:
482  default:
483  rlm_sql_print_error(inst, request, *handle, false);
484  (inst->module->sql_finish_select_query)(*handle, inst->config);
485  break;
486  }
487 
488  return ret;
489  }
490 
491  MOD_ROPTIONAL(RERROR, ERROR, "Hit reconnection limit");
492 
493  return RLM_SQL_ERROR;
494 }
495 
496 
497 /*************************************************************************
498  *
499  * Function: sql_getvpdata
500  *
501  * Purpose: Get any group check or reply pairs
502  *
503  *************************************************************************/
504 int sql_getvpdata(TALLOC_CTX *ctx, rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle,
505  VALUE_PAIR **pair, char const *query)
506 {
507  rlm_sql_row_t row;
508  int rows = 0;
509  sql_rcode_t rcode;
510 
511  rad_assert(request);
512 
513  rcode = rlm_sql_select_query(inst, request, handle, query);
514  if (rcode != RLM_SQL_OK) return -1; /* error handled by rlm_sql_select_query */
515 
516  while (rlm_sql_fetch_row(&row, inst, request, handle) == 0) {
517  if (!row) break;
518  if (sql_fr_pair_list_afrom_str(ctx, request, pair, row) != 0) {
519  REDEBUG("Error parsing user data from database result");
520 
521  (inst->module->sql_finish_select_query)(*handle, inst->config);
522 
523  return -1;
524  }
525  rows++;
526  }
527  (inst->module->sql_finish_select_query)(*handle, inst->config);
528 
529  return rows;
530 }
531 
532 /*
533  * Log the query to a file.
534  */
535 void rlm_sql_query_log(rlm_sql_t const *inst, REQUEST *request,
536  sql_acct_section_t *section, char const *query)
537 {
538  int fd;
539  char const *filename = NULL;
540  char *expanded = NULL;
541  size_t len;
542  bool failed = false; /* Write the log message outside of the critical region */
543 
544  filename = inst->config->logfile;
545  if (section && section->logfile) filename = section->logfile;
546 
547  if (!filename || !*filename) {
548  return;
549  }
550 
551  if (radius_axlat(&expanded, request, filename, NULL, NULL) < 0) {
552  return;
553  }
554 
555  fd = exfile_open(inst->ef, filename, 0640, true);
556  if (fd < 0) {
557  ERROR("rlm_sql (%s): Couldn't open logfile '%s': %s", inst->name,
558  expanded, fr_syserror(errno));
559 
560  talloc_free(expanded);
561  return;
562  }
563 
564  len = strlen(query);
565  if ((write(fd, query, len) < 0) || (write(fd, ";\n", 2) < 0)) {
566  failed = true;
567  }
568 
569  if (failed) {
570  ERROR("rlm_sql (%s): Failed writing to logfile '%s': %s", inst->name, expanded,
571  fr_syserror(errno));
572  }
573 
574  talloc_free(expanded);
575  exfile_close(inst->ef, fd);
576 }
exfile_t * ef
Definition: rlm_sql.h:226
ssize_t ssize_t ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
rlm_sql_t * inst
The rlm_sql instance this connection belongs to.
Definition: rlm_sql.h:155
General connection/server error.
Definition: rlm_sql.h:46
sql_rcode_t(* sql_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query)
Definition: rlm_sql.h:198
#define RERROR(fmt,...)
Definition: log.h:207
Only displayed when debugging is enabled.
Definition: log.h:41
Definition: token.h:34
sql_rcode_t(* sql_finish_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
Definition: rlm_sql.h:213
Prototypes and functions for the SQL module.
char ** rlm_sql_row_t
Definition: rlm_sql.h:59
void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench) CC_HINT(nonnull(3))
Execute a trigger - call an executable to process an event.
Definition: exec.c:686
int sql_fr_pair_list_afrom_str(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **head, rlm_sql_row_t row)
Definition: sql.c:128
#define RLM_SQL_RCODE_FLAGS_ALT_QUERY
Can distinguish between other errors and those.
Definition: rlm_sql.h:164
#define RWARN(fmt,...)
Definition: log.h:206
#define INFO(fmt,...)
Definition: log.h:143
Warning.
Definition: log.h:37
char const * logfile
Keep a log of all SQL queries executed Useful for batch insertion with the NULL drivers.
Definition: rlm_sql.h:121
static int _mod_conn_free(rlm_sql_handle_t *conn)
Definition: sql.c:56
int sql_getvpdata(TALLOC_CTX *ctx, rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle, VALUE_PAIR **pair, char const *query)
Definition: sql.c:504
Error message.
Definition: log.h:36
void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
Create a new connection pool handle.
Definition: sql.c:67
static float timeout
Definition: radclient.c:43
#define inst
sql_rcode_t(* sql_fetch_row)(rlm_sql_row_t *out, rlm_sql_handle_t *handle, rlm_sql_config_t *config)
Definition: rlm_sql.h:206
sql_rcode_t rlm_sql_select_query(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query)
Call the driver's sql_select_query method, reconnecting if necessary.
Definition: sql.c:438
Key constraint violation.
Definition: rlm_sql.h:49
sql_rcode_t(* sql_socket_init)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, struct timeval const *timeout)
Definition: rlm_sql.h:195
#define rad_assert(expr)
Definition: rad_assert.h:38
Stale connection, should reconnect.
Definition: rlm_sql.h:48
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
CONF_SECTION * cs
Definition: rlm_sql.h:222
#define DEBUG(fmt,...)
Definition: log.h:175
sql_rcode_t
Definition: rlm_sql.h:44
#define MOD_ROPTIONAL(_l_request, _l_global, fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:338
int fr_pair_mark_xlat(VALUE_PAIR *vp, char const *value)
Mark a valuepair for xlat expansion.
Definition: pair.c:598
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
Definition: pair.c:659
int exfile_open(exfile_t *lf, char const *filename, mode_t permissions, bool append)
Open a new log file, or maybe an existing one.
Definition: exfile.c:142
#define DEBUG2(fmt,...)
Definition: log.h:176
Definition: rlm_sql.h:61
Definition: token.h:43
void rlm_sql_print_error(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t *handle, bool force_debug)
Retrieve any errors from the SQL driver.
Definition: sql.c:280
sql_error_t sql_error
Get any errors from the previous query.
Definition: rlm_sql.h:210
int exfile_close(exfile_t *lf, int fd)
Close the log file.
Definition: exfile.c:356
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
Success.
Definition: rlm_sql.h:47
const FR_NAME_NUMBER sql_rcode_table[]
Definition: sql.c:46
rlm_sql_config_t * config
Definition: rlm_sql.h:221
int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, size_t len)
Convert string value to native attribute value.
Definition: pair.c:1840
void * conn
Database specific connection handle.
Definition: rlm_sql.h:153
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
sql_rcode_t(* sql_select_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query)
Definition: rlm_sql.h:199
#define RDEBUG2(fmt,...)
Definition: log.h:244
void rlm_sql_query_log(rlm_sql_t const *inst, REQUEST *request, sql_acct_section_t *section, char const *query)
Definition: sql.c:535
FR_TOKEN gettoken(char const **ptr, char *buf, int buflen, bool unescape)
Definition: token.c:405
sql_rcode_t rlm_sql_fetch_row(rlm_sql_row_t *out, rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle)
Call the driver's sql_fetch_row function.
Definition: sql.c:249
uint32_t num
Number of connections in the pool.
Definition: connection.h:55
Query syntax error.
Definition: rlm_sql.h:45
uint8_t token[4]
Definition: eap_pwd.h:625
#define WARN(fmt,...)
Definition: log.h:144
#define REDEBUG(fmt,...)
Definition: log.h:254
char const * name
Module instance name.
Definition: rlm_sql.h:237
TALLOC_CTX * log_ctx
Talloc pool used to avoid mallocing memory on when log strings need to be copied. ...
Definition: rlm_sql.h:156
char const * connect_query
Query executed after establishing new connection.
Definition: rlm_sql.h:132
char const * logfile
Definition: rlm_sql.h:78
enum fr_token FR_TOKEN
#define RINFO(fmt,...)
Definition: log.h:205
char const * sql_driver_name
SQL driver module name e.g. rlm_sql_sqlite.
Definition: rlm_sql.h:84
sql_rcode_t(* sql_finish_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
Definition: rlm_sql.h:212
#define MAX_STRING_LEN
Definition: libradius.h:120
Informational message.
Definition: log.h:35
#define RCSID(id)
Definition: build.h:135
rlm_sql_module_t * module
Definition: rlm_sql.h:229
fr_connection_pool_state_t const * fr_connection_pool_state(fr_connection_pool_t *pool)
Get the number of connections currently in the pool.
Definition: connection.c:1081
fr_connection_pool_t * pool
Definition: rlm_sql.h:220
VALUE_PAIR * fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op)
Create a VALUE_PAIR from ASCII strings.
Definition: pair.c:338
void * fr_connection_reconnect(fr_connection_pool_t *pool, void *conn)
Reconnect a suspected inviable connection.
Definition: connection.c:1367
#define RDEBUG(fmt,...)
Definition: log.h:243
sql_rcode_t rlm_sql_query(rlm_sql_t const *inst, REQUEST *request, rlm_sql_handle_t **handle, char const *query)
Call the driver's sql_query method, reconnecting if necessary.
Definition: sql.c:337
#define ERROR(fmt,...)
Definition: log.h:145