All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_files.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: d30bb6c90bfed3efcc84f26060ee7612d18fa89c $
19  * @file rlm_files.c
20  * @brief Process simple 'users' policy files.
21  *
22  * @copyright 2000,2006 The FreeRADIUS server project
23  * @copyright 2000 Jeff Carneal <jeff@apex.net>
24  */
25 RCSID("$Id: d30bb6c90bfed3efcc84f26060ee7612d18fa89c $")
26 
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 
30 #include <ctype.h>
31 #include <fcntl.h>
32 
33 typedef struct rlm_files_t {
34  char const *compat_mode;
35 
36  char const *key;
37 
38  char const *filename;
40 
41  /* autz */
42  char const *usersfile;
44 
45 
46  /* authenticate */
47  char const *auth_usersfile;
49 
50  /* preacct */
51  char const *acctusersfile;
53 
54 #ifdef WITH_PROXY
55  /* pre-proxy */
56  char const *preproxy_usersfile;
58 
59  /* post-proxy */
60  char const *postproxy_usersfile;
62 #endif
63 
64  /* post-authenticate */
65  char const *postauth_usersfile;
67 } rlm_files_t;
68 
69 
70 /*
71  * See if a VALUE_PAIR list contains Fall-Through = Yes
72  */
73 static int fall_through(VALUE_PAIR *vp)
74 {
75  VALUE_PAIR *tmp;
76  tmp = fr_pair_find_by_num(vp, 0, PW_FALL_THROUGH, TAG_ANY);
77 
78  return tmp ? tmp->vp_integer : 0;
79 }
80 
81 static const CONF_PARSER module_config[] = {
82  { FR_CONF_OFFSET("filename", PW_TYPE_FILE_INPUT, rlm_files_t, filename) },
83  { FR_CONF_OFFSET("usersfile", PW_TYPE_FILE_INPUT, rlm_files_t, usersfile) },
84  { FR_CONF_OFFSET("acctusersfile", PW_TYPE_FILE_INPUT, rlm_files_t, acctusersfile) },
85 #ifdef WITH_PROXY
86  { FR_CONF_OFFSET("preproxy_usersfile", PW_TYPE_FILE_INPUT, rlm_files_t, preproxy_usersfile) },
87  { FR_CONF_OFFSET("postproxy_usersfile", PW_TYPE_FILE_INPUT, rlm_files_t, postproxy_usersfile) },
88 #endif
89  { FR_CONF_OFFSET("auth_usersfile", PW_TYPE_FILE_INPUT, rlm_files_t, auth_usersfile) },
90  { FR_CONF_OFFSET("postauth_usersfile", PW_TYPE_FILE_INPUT, rlm_files_t, postauth_usersfile) },
91  { FR_CONF_OFFSET("compat", PW_TYPE_STRING | PW_TYPE_DEPRECATED, rlm_files_t, compat_mode) },
94 };
95 
96 
97 static int pairlist_cmp(void const *a, void const *b)
98 {
99  return strcmp(((PAIR_LIST const *)a)->name,
100  ((PAIR_LIST const *)b)->name);
101 }
102 
103 static int getusersfile(TALLOC_CTX *ctx, char const *filename, rbtree_t **ptree, char const *compat_mode_str)
104 {
105  int rcode;
106  PAIR_LIST *users = NULL;
107  PAIR_LIST *entry, *next;
108  PAIR_LIST *user_list, *default_list, **default_tail;
109  rbtree_t *tree;
110 
111  if (!filename) {
112  *ptree = NULL;
113  return 0;
114  }
115 
116  rcode = pairlist_read(ctx, filename, &users, 1);
117  if (rcode < 0) {
118  return -1;
119  }
120 
121  /*
122  * Walk through the 'users' file list, if we're debugging,
123  * or if we're in compat_mode.
124  */
125  if ((rad_debug_lvl) ||
126  (compat_mode_str && (strcmp(compat_mode_str, "cistron") == 0))) {
127  VALUE_PAIR *vp;
128  bool compat_mode = false;
129 
130  if (compat_mode_str && (strcmp(compat_mode_str, "cistron") == 0)) {
131  compat_mode = true;
132  }
133 
134  entry = users;
135  while (entry) {
136  vp_cursor_t cursor;
137  if (compat_mode) {
138  DEBUG("[%s]:%d Cistron compatibility checks for entry %s ...",
139  filename, entry->lineno,
140  entry->name);
141  }
142 
143  /*
144  * Look for improper use of '=' in the
145  * check items. They should be using
146  * '==' for on-the-wire RADIUS attributes,
147  * and probably ':=' for server
148  * configuration items.
149  */
150  for (vp = fr_cursor_init(&cursor, &entry->check); vp; vp = fr_cursor_next(&cursor)) {
151  /*
152  * Ignore attributes which are set
153  * properly.
154  */
155  if (vp->op != T_OP_EQ) {
156  continue;
157  }
158 
159  /*
160  * If it's a vendor attribute,
161  * or it's a wire protocol,
162  * ensure it has '=='.
163  */
164  if ((vp->da->vendor != 0) ||
165  (vp->da->attr < 0x100)) {
166  if (!compat_mode) {
167  WARN("[%s]:%d Changing '%s =' to '%s =='\n\tfor comparing RADIUS attribute in check item list for user %s",
168  filename, entry->lineno,
169  vp->da->name, vp->da->name,
170  entry->name);
171  } else {
172  DEBUG("\tChanging '%s =' to '%s =='",
173  vp->da->name, vp->da->name);
174  }
175  vp->op = T_OP_CMP_EQ;
176  continue;
177  }
178 
179  /*
180  * Cistron Compatibility mode.
181  *
182  * Re-write selected attributes
183  * to be '+=', instead of '='.
184  *
185  * All others get set to '=='
186  */
187  if (compat_mode) {
188  /*
189  * Non-wire attributes become +=
190  *
191  * On the write attributes
192  * become ==
193  */
194  if ((vp->da->attr >= 0x100) &&
195  (vp->da->attr <= 0xffff) &&
196  (vp->da->attr != PW_HINT) &&
197  (vp->da->attr != PW_HUNTGROUP_NAME)) {
198  DEBUG("\tChanging '%s =' to '%s +='", vp->da->name, vp->da->name);
199 
200  vp->op = T_OP_ADD;
201  } else {
202  DEBUG("\tChanging '%s =' to '%s =='", vp->da->name, vp->da->name);
203 
204  vp->op = T_OP_CMP_EQ;
205  }
206  }
207  } /* end of loop over check items */
208 
209  /*
210  * Look for server configuration items
211  * in the reply list.
212  *
213  * It's a common enough mistake, that it's
214  * worth doing.
215  */
216  for (vp = fr_cursor_init(&cursor, &entry->reply); vp; vp = fr_cursor_next(&cursor)) {
217  /*
218  * If it's NOT a vendor attribute,
219  * and it's NOT a wire protocol
220  * and we ignore Fall-Through,
221  * then bitch about it, giving a
222  * good warning message.
223  */
224  if ((vp->da->vendor == 0) &&
225  (vp->da->attr > 1000)) {
226  WARN("[%s]:%d Check item \"%s\"\n"
227  "\tfound in reply item list for user \"%s\".\n"
228  "\tThis attribute MUST go on the first line"
229  " with the other check items", filename, entry->lineno, vp->da->name,
230  entry->name);
231  }
232  }
233 
234  entry = entry->next;
235  }
236  }
237 
238  tree = rbtree_create(ctx, pairlist_cmp, NULL, RBTREE_FLAG_NONE);
239  if (!tree) {
240  pairlist_free(&users);
241  return -1;
242  }
243 
244  default_list = NULL;
245  default_tail = &default_list;
246 
247  /*
248  * We've read the entries in linearly, but putting them
249  * into an indexed data structure would be much faster.
250  * Let's go fix that now.
251  */
252  for (entry = users; entry != NULL; entry = next) {
253  /*
254  * Remove this entry from the input list.
255  */
256  next = entry->next;
257  entry->next = NULL;
258  (void) talloc_steal(tree, entry);
259 
260  /*
261  * DEFAULT entries get their own list.
262  */
263  if (strcmp(entry->name, "DEFAULT") == 0) {
264  if (!default_list) {
265  default_list = entry;
266 
267  /*
268  * Insert the first DEFAULT into the tree.
269  */
270  if (!rbtree_insert(tree, entry)) {
271  error:
272  pairlist_free(&entry);
273  pairlist_free(&next);
274  rbtree_free(tree);
275  return -1;
276  }
277 
278  } else {
279  /*
280  * Tack this entry onto the tail
281  * of the DEFAULT list.
282  */
283  *default_tail = entry;
284  }
285 
286  default_tail = &entry->next;
287  continue;
288  }
289 
290  /*
291  * Not DEFAULT, must be a normal user.
292  */
293  user_list = rbtree_finddata(tree, entry);
294  if (!user_list) {
295  /*
296  * Insert the first one.
297  */
298  if (!rbtree_insert(tree, entry)) goto error;
299  } else {
300  /*
301  * Find the tail of this list, and add it
302  * there.
303  */
304  while (user_list->next) user_list = user_list->next;
305 
306  user_list->next = entry;
307  }
308  }
309 
310  *ptree = tree;
311 
312  return 0;
313 }
314 
315 
316 
317 /*
318  * (Re-)read the "users" file into memory.
319  */
320 static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
321 {
322  rlm_files_t *inst = instance;
323 
324 #undef READFILE
325 #define READFILE(_x, _y) do { if (getusersfile(inst, inst->_x, &inst->_y, inst->compat_mode) != 0) { ERROR("Failed reading %s", inst->_x); return -1;} } while (0)
326 
327  READFILE(filename, common);
328  READFILE(usersfile, users);
329  READFILE(acctusersfile, acctusers);
330 
331 #ifdef WITH_PROXY
332  READFILE(preproxy_usersfile, preproxy_users);
333  READFILE(postproxy_usersfile, postproxy_users);
334 #endif
335 
336  READFILE(auth_usersfile, auth_users);
337  READFILE(postauth_usersfile, postauth_users);
338 
339  return 0;
340 }
341 
342 /*
343  * Common code called by everything below.
344  */
345 static rlm_rcode_t file_common(rlm_files_t *inst, REQUEST *request, char const *filename, rbtree_t *tree,
346  RADIUS_PACKET *request_packet, RADIUS_PACKET *reply_packet)
347 {
348  char const *name, *match;
349  VALUE_PAIR *check_tmp;
350  VALUE_PAIR *reply_tmp;
351  PAIR_LIST const *user_pl, *default_pl;
352  bool found = false;
353  PAIR_LIST my_pl;
354  char buffer[256];
355 
356  if (!inst->key) {
357  VALUE_PAIR *namepair;
358 
359  namepair = request->username;
360  name = namepair ? namepair->vp_strvalue : "NONE";
361  } else {
362  int len;
363 
364  len = radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL);
365  if (len < 0) {
366  return RLM_MODULE_FAIL;
367  }
368 
369  name = len ? buffer : "NONE";
370  }
371 
372  if (!tree) return RLM_MODULE_NOOP;
373 
374  my_pl.name = name;
375  user_pl = rbtree_finddata(tree, &my_pl);
376  my_pl.name = "DEFAULT";
377  default_pl = rbtree_finddata(tree, &my_pl);
378 
379  /*
380  * Find the entry for the user.
381  */
382  while (user_pl || default_pl) {
383  vp_cursor_t cursor;
384  VALUE_PAIR *vp;
385  PAIR_LIST const *pl;
386 
387  /*
388  * Figure out which entry to match on.
389  */
390 
391  if (!default_pl && user_pl) {
392  pl = user_pl;
393  match = name;
394  user_pl = user_pl->next;
395 
396  } else if (!user_pl && default_pl) {
397  pl = default_pl;
398  match = "DEFAULT";
399  default_pl = default_pl->next;
400 
401  } else if (user_pl->lineno < default_pl->lineno) {
402  pl = user_pl;
403  match = name;
404  user_pl = user_pl->next;
405 
406  } else {
407  pl = default_pl;
408  match = "DEFAULT";
409  default_pl = default_pl->next;
410  }
411 
412  check_tmp = fr_pair_list_copy(request, pl->check);
413  for (vp = fr_cursor_init(&cursor, &check_tmp);
414  vp;
415  vp = fr_cursor_next(&cursor)) {
416  if (radius_xlat_do(request, vp) < 0) {
417  RWARN("Failed parsing expanded value for check item, skipping entry: %s", fr_strerror());
418  fr_pair_list_free(&check_tmp);
419  continue;
420  }
421  }
422 
423  if (paircompare(request, request_packet->vps, check_tmp, &reply_packet->vps) == 0) {
424  RDEBUG2("%s: Matched entry %s at line %d", filename, match, pl->lineno);
425  found = true;
426 
427  /* ctx may be reply or proxy */
428  reply_tmp = fr_pair_list_copy(reply_packet, pl->reply);
429  radius_pairmove(request, &reply_packet->vps, reply_tmp, true);
430  fr_pair_list_move(request, &request->config, &check_tmp);
431  fr_pair_list_free(&check_tmp);
432 
433  /*
434  * Fallthrough?
435  */
436  if (!fall_through(pl->reply))
437  break;
438  }
439  }
440 
441  /*
442  * Remove server internal parameters.
443  */
444  fr_pair_delete_by_num(&reply_packet->vps, 0, PW_FALL_THROUGH, TAG_ANY);
445 
446  /*
447  * See if we succeeded.
448  */
449  if (!found)
450  return RLM_MODULE_NOOP; /* on to the next module */
451 
452  return RLM_MODULE_OK;
453 
454 }
455 
456 
457 /*
458  * Find the named user in the database. Create the
459  * set of attribute-value pairs to check and reply with
460  * for this user from the database. The main code only
461  * needs to check the password, the rest is done here.
462  */
463 static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request)
464 {
465  rlm_files_t *inst = instance;
466 
467  return file_common(inst, request, "users",
468  inst->users ? inst->users : inst->common,
469  request->packet, request->reply);
470 }
471 
472 
473 /*
474  * Pre-Accounting - read the acct_users file for check_items and
475  * config. Reply items are Not Recommended(TM) in acct_users,
476  * except for Fallthrough, which should work
477  */
478 static rlm_rcode_t CC_HINT(nonnull) mod_preacct(void *instance, REQUEST *request)
479 {
480  rlm_files_t *inst = instance;
481 
482  return file_common(inst, request, "acct_users",
483  inst->acctusers ? inst->acctusers : inst->common,
484  request->packet, request->reply);
485 }
486 
487 #ifdef WITH_PROXY
488 static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void *instance, REQUEST *request)
489 {
490  rlm_files_t *inst = instance;
491 
492  return file_common(inst, request, "preproxy_users",
493  inst->preproxy_users ? inst->preproxy_users : inst->common,
494  request->packet, request->proxy);
495 }
496 
497 static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *instance, REQUEST *request)
498 {
499  rlm_files_t *inst = instance;
500 
501  return file_common(inst, request, "postproxy_users",
502  inst->postproxy_users ? inst->postproxy_users : inst->common,
503  request->proxy_reply, request->reply);
504 }
505 #endif
506 
507 static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
508 {
509  rlm_files_t *inst = instance;
510 
511  return file_common(inst, request, "auth_users",
512  inst->auth_users ? inst->auth_users : inst->common,
513  request->packet, request->reply);
514 }
515 
516 static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request)
517 {
518  rlm_files_t *inst = instance;
519 
520  return file_common(inst, request, "postauth_users",
521  inst->postauth_users ? inst->postauth_users : inst->common,
522  request->packet, request->reply);
523 }
524 
525 
526 /* globally exported name */
527 extern module_t rlm_files;
528 module_t rlm_files = {
530  .name = "files",
531  .type = RLM_TYPE_HUP_SAFE,
532  .inst_size = sizeof(rlm_files_t),
533  .config = module_config,
534  .instantiate = mod_instantiate,
535  .methods = {
538  [MOD_PREACCT] = mod_preacct,
539 
540 #ifdef WITH_PROXY
541  [MOD_PRE_PROXY] = mod_pre_proxy,
542  [MOD_POST_PROXY] = mod_post_proxy,
543 #endif
545  },
546 };
547 
static rlm_rcode_t file_common(rlm_files_t *inst, REQUEST *request, char const *filename, rbtree_t *tree, RADIUS_PACKET *request_packet, RADIUS_PACKET *reply_packet)
Definition: rlm_files.c:345
void fr_pair_list_free(VALUE_PAIR **)
Free memory used by a valuepair list.
Definition: pair.c:544
5 methods index for preproxy section.
Definition: modules.h:46
#define PW_TYPE_FILE_INPUT
File matching value must exist, and must be readable.
Definition: conffile.h:204
void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from, bool do_xlat) CC_HINT(nonnull)
Definition: evaluate.c:774
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Definition: radiusd.h:227
rbtree_t * common
Definition: rlm_files.c:39
void rbtree_free(rbtree_t *tree)
Definition: rbtree.c:84
char const * name
Definition: tmpl.h:120
The module is OK, continue.
Definition: radiusd.h:91
VALUE_PAIR * check
Definition: tmpl.h:121
static rlm_rcode_t mod_post_auth(void *instance, REQUEST *request) CC_HINT(nonnull)
Metadata exported by the module.
Definition: modules.h:134
#define RWARN(fmt,...)
Definition: log.h:206
7 methods index for postauth section.
Definition: modules.h:48
static char const * name
int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check, VALUE_PAIR **rep_list)
Compare two pair lists except for the password information.
Definition: pair.c:479
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
Handle authorization requests using Couchbase document data.
VALUE_PAIR * username
Cached username VALUE_PAIR from request RADIUS_PACKET.
Definition: radiusd.h:222
char const * acctusersfile
Definition: rlm_files.c:51
#define UNUSED
Definition: libradius.h:134
#define RLM_MODULE_INIT
Definition: modules.h:86
#define READFILE(_x, _y)
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
Definition: libradius.h:162
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
rbtree_t * users
Definition: rlm_files.c:43
void pairlist_free(PAIR_LIST **)
Definition: files.c:65
char const * compat_mode
Definition: rlm_files.c:34
VALUE_PAIR * fr_cursor_init(vp_cursor_t *cursor, VALUE_PAIR *const *node)
Setup a cursor to iterate over attribute pairs.
Definition: cursor.c:60
rbtree_t * postauth_users
Definition: rlm_files.c:66
rbtree_t * postproxy_users
Definition: rlm_files.c:61
char const * preproxy_usersfile
Definition: rlm_files.c:56
#define PW_TYPE_DEPRECATED
If a matching CONF_PAIR is found, error out with a deprecated message.
Definition: conffile.h:199
#define inst
void * rbtree_finddata(rbtree_t *tree, void const *data)
Find the user data.
Definition: rbtree.c:537
Definition: token.h:46
#define RLM_TYPE_HUP_SAFE
Will be restarted on HUP.
Definition: modules.h:79
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
Definition: pair.h:144
char const * filename
Definition: rlm_files.c:38
rbtree_t * auth_users
Definition: rlm_files.c:48
VALUE_PAIR * fr_pair_list_copy(TALLOC_CTX *ctx, VALUE_PAIR *from)
Copy a pairlist.
Definition: pair.c:1394
struct pair_list * next
Definition: tmpl.h:124
#define DEBUG(fmt,...)
Definition: log.h:175
rbtree_t * rbtree_create(TALLOC_CTX *ctx, rb_comparator_t compare, rb_free_t node_free, int flags)
Create a new RED-BLACK tree.
Definition: rbtree.c:112
static rlm_rcode_t CC_HINT(nonnull)
Definition: rlm_files.c:463
rbtree_t * preproxy_users
Definition: rlm_files.c:57
char const * usersfile
Definition: rlm_files.c:42
#define PW_TYPE_XLAT
string will be dynamically expanded.
Definition: conffile.h:207
char const * postauth_usersfile
Definition: rlm_files.c:65
unsigned int attr
Attribute number.
Definition: dict.h:79
Definition: token.h:43
static int fall_through(VALUE_PAIR *vp)
Definition: rlm_files.c:73
unsigned int vendor
Vendor that defines this attribute.
Definition: dict.h:78
#define RBTREE_FLAG_NONE
Definition: libradius.h:525
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
0 methods index for authenticate section.
Definition: modules.h:41
char const * auth_usersfile
Definition: rlm_files.c:47
module_t rlm_files
Definition: rlm_files.c:528
FR_TOKEN op
Operator to use when moving or inserting valuepair into a list.
Definition: pair.h:118
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
int radius_xlat_do(REQUEST *request, VALUE_PAIR *vp)
Expands an attribute marked with fr_pair_mark_xlat.
Definition: pair.c:655
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
static rs_t * conf
Definition: radsniff.c:46
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag)
Delete matching pairs.
Definition: pair.c:797
char const * key
Definition: rlm_files.c:36
Module succeeded without doing anything.
Definition: radiusd.h:96
#define RDEBUG2(fmt,...)
Definition: log.h:244
void fr_pair_list_move(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from)
Move pairs from source list to destination list respecting operator.
Definition: pair.c:1508
char name[1]
Attribute name.
Definition: dict.h:89
uint64_t magic
Used to validate module struct.
Definition: modules.h:135
Module failed, don't reply.
Definition: radiusd.h:90
#define TAG_ANY
Definition: pair.h:191
int lineno
Definition: tmpl.h:123
static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
Definition: rlm_files.c:320
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
log_lvl_t rad_debug_lvl
Global debugging level.
Definition: log.c:49
VALUE_PAIR * fr_cursor_next(vp_cursor_t *cursor)
Advanced the cursor to the next VALUE_PAIR.
Definition: cursor.c:263
bool rbtree_insert(rbtree_t *tree, void *data)
Definition: rbtree.c:329
#define WARN(fmt,...)
Definition: log.h:144
static int pairlist_cmp(void const *a, void const *b)
Definition: rlm_files.c:97
rbtree_t * acctusers
Definition: rlm_files.c:52
6 methods index for postproxy section.
Definition: modules.h:47
2 methods index for preacct section.
Definition: modules.h:43
static rbtree_t * pl
Definition: process.c:53
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
char const * postproxy_usersfile
Definition: rlm_files.c:60
struct rlm_files_t rlm_files_t
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
Definition: pair.h:113
static const CONF_PARSER module_config[]
Definition: rlm_files.c:81
String of printable characters.
Definition: radius.h:33
1 methods index for authorize section.
Definition: modules.h:42
static int getusersfile(TALLOC_CTX *ctx, char const *filename, rbtree_t **ptree, char const *compat_mode_str)
Definition: rlm_files.c:103
#define RCSID(id)
Definition: build.h:135
VALUE_PAIR * reply
Definition: tmpl.h:122
int pairlist_read(TALLOC_CTX *ctx, char const *file, PAIR_LIST **list, int complain)
Definition: files.c:80