The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_passwd.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: 6e6a1dfa8f816ec1f2514f7ae609f5544153fa23 $
19  * @file rlm_passwd.c
20  * @brief Enables authentication against unix passwd files.
21  *
22  * @copyright 2000,2006 The FreeRADIUS server project
23  */
24 RCSID("$Id: 6e6a1dfa8f816ec1f2514f7ae609f5544153fa23 $")
25 
26 #define LOG_PREFIX "passwd"
27 
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/server/module_rlm.h>
30 #include <freeradius-devel/util/debug.h>
31 
32 struct mypasswd {
33  struct mypasswd *next;
34  char *listflag;
35  char *field[1];
36 };
37 
38 struct hashtable {
39  int tablesize;
40  int key_field;
42  int islist;
43  int ignorenis;
44  char * filename;
45  struct mypasswd **table;
46  char buffer[1024];
47  FILE *fp;
48  char delimiter;
49 };
50 
51 static fr_dict_t const *dict_freeradius;
52 
55  { .out = &dict_freeradius, .proto = "freeradius" },
56  { NULL }
57 };
58 
59 #ifdef TEST
60 
61 void printpw(struct mypasswd *pw, int num_fields){
62  int i;
63  if (pw) {
64  for( i = 0; i < num_fields; i++ ) printf("%s:", pw->field[i]);
65  printf("\n");
66  }
67  else printf ("Not found\n");
68  fflush(stdout);
69 }
70 #endif
71 
72 
73 static struct mypasswd *mypasswd_alloc(char const* buffer, int num_fields, size_t* len)
74 {
75  struct mypasswd *t;
76  /* reserve memory for (struct mypasswd) + listflag (num_fields * sizeof (char*)) +
77  ** fields (num_fields * sizeof (char)) + strlen (inst->format) + 1 */
78 
79  *len = sizeof(struct mypasswd) + num_fields * sizeof (char*) + num_fields * sizeof (char ) + strlen(buffer) + 1;
80  MEM(t = (struct mypasswd *)talloc_zero_array(NULL, uint8_t, *len));
81 
82  return t;
83 }
84 
85 static int string_to_entry(char const* string, int num_fields, char delimiter,
86  struct mypasswd *passwd, size_t bufferlen)
87 {
88  char *str;
89  size_t len, i;
90  int fn=0;
91  char *data_beg;
92 
93 
94  len = strlen(string);
95  if(!len) return 0;
96  if (string[len-1] == '\n') len--;
97  if(!len) return 0;
98  if (string[len-1] == '\r') len--;
99  if(!len) return 0;
100  if (!passwd ||
101  bufferlen < (len + num_fields * sizeof (char*) + num_fields * sizeof (char) + sizeof (struct mypasswd) + 1) ) return 0;
102  passwd->next = NULL;
103  data_beg=(char *)passwd + sizeof(struct mypasswd);
104  str = data_beg + num_fields * sizeof (char) + num_fields * sizeof (char*);
105  memcpy (str, string, len);
106  str[len] = 0;
107  passwd->field[fn++] = str;
108  passwd->listflag = data_beg + num_fields * sizeof (char *);
109  for(i=0; i < len; i++){
110  if (str[i] == delimiter) {
111  str[i] = 0;
112  passwd->field[fn++] = str + i + 1;
113  if (fn == num_fields) break;
114  }
115  }
116  for (; fn < num_fields; fn++) passwd->field[fn] = NULL;
117  return len + num_fields * sizeof (char) + num_fields * sizeof (char*) + sizeof (struct mypasswd) + 1;
118 }
119 
120 
121 static void destroy_password (struct mypasswd * pass)
122 {
123  struct mypasswd *p;
124 
125  while ((p = pass) != NULL) {
126  pass = pass->next;
127  talloc_free(p);
128  }
129 }
130 
131 
132 static unsigned int hash(char const * username, unsigned int tablesize)
133 {
135 
136  return h % tablesize;
137 }
138 
139 static void release_hash_table(struct hashtable * ht){
140  int i;
141 
142  if (!ht) return;
143  for (i = 0; i < ht->tablesize; i++)
144  if (ht->table[i])
145  destroy_password(ht->table[i]);
146  if (ht->fp) {
147  fclose(ht->fp);
148  ht->fp = NULL;
149  }
150  ht->tablesize = 0;
151 }
152 
153 static void release_ht(struct hashtable * ht){
154  if (!ht) return;
155  release_hash_table(ht);
156  talloc_free(ht);
157 }
158 
159 static struct hashtable * build_hash_table (char const * file, int num_fields,
160  int key_field, int islist, int tablesize, int ignorenis, char delimiter)
161 {
162  struct hashtable* ht;
163  size_t len;
164  unsigned int h;
165  struct mypasswd *hashentry, *hashentry1;
166  char *list;
167  char *nextlist=0;
168  int i;
169  char buffer[1024];
170 
171  MEM(ht = talloc_zero(NULL, struct hashtable));
172  MEM(ht->filename = talloc_typed_strdup(ht, file));
173 
174  ht->tablesize = tablesize;
175  ht->num_fields = num_fields;
176  ht->key_field = key_field;
177  ht->islist = islist;
178  ht->ignorenis = ignorenis;
179 
180  if (delimiter) ht->delimiter = delimiter;
181  else ht->delimiter = ':';
182  if(!tablesize) return ht;
183  if(!(ht->fp = fopen(file,"r"))) {
184  talloc_free(ht);
185  return NULL;
186  }
187 
188  /*
189  * @todo: This code is SHIT. It's badly formatted. It's
190  * hard to understand. It re-implements tons of things
191  * which are already in the server core.
192  */
193  memset(ht->buffer, 0, 1024);
194  MEM(ht->table = talloc_zero_array(ht, struct mypasswd *, tablesize));
195  while (fgets(buffer, 1024, ht->fp)) {
196  if(*buffer && *buffer!='\n' && (!ignorenis || (*buffer != '+' && *buffer != '-')) ){
197  hashentry = mypasswd_alloc(buffer, num_fields, &len);
198  if (!hashentry){
199  release_hash_table(ht);
200  return ht;
201  }
202 
203  len = string_to_entry(buffer, num_fields, ht->delimiter, hashentry, len);
204  if (!hashentry->field[key_field] || *hashentry->field[key_field] == '\0') {
205  talloc_free(hashentry);
206  continue;
207  }
208 
209  if (islist) {
210  list = hashentry->field[key_field];
211  for (nextlist = list; *nextlist && *nextlist!=','; nextlist++);
212  if (*nextlist) *nextlist++ = 0;
213  else nextlist = 0;
214  }
215  h = hash(hashentry->field[key_field], tablesize);
216  hashentry->next = ht->table[h];
217  ht->table[h] = hashentry;
218  if (islist) {
219  for (list=nextlist; nextlist; list = nextlist){
220  for (nextlist = list; *nextlist && *nextlist!=','; nextlist++);
221  if (*nextlist) *nextlist++ = 0;
222  else nextlist = 0;
223  if(!(hashentry1 = mypasswd_alloc("", num_fields, &len))){
224  release_hash_table(ht);
225  return ht;
226  }
227  for (i=0; i<num_fields; i++) hashentry1->field[i] = hashentry->field[i];
228  hashentry1->field[key_field] = list;
229  h = hash(list, tablesize);
230  hashentry1->next = ht->table[h];
231  ht->table[h] = hashentry1;
232  }
233  }
234  }
235  }
236  fclose(ht->fp);
237  ht->fp = NULL;
238  return ht;
239 #undef passwd
240 }
241 
242 static struct mypasswd * get_next(char *name, struct hashtable *ht,
243  struct mypasswd **last_found)
244 {
245  struct mypasswd * passwd;
246  struct mypasswd * hashentry;
247  char buffer[1024];
248  char *list, *nextlist;
249 
250  if (ht->tablesize > 0) {
251  /* get saved address of next item to check from buffer */
252  hashentry = *last_found;
253  for (; hashentry; hashentry = hashentry->next) {
254  if (!strcmp(hashentry->field[ht->key_field], name)) {
255  /* save new address */
256  *last_found = hashentry->next;
257  return hashentry;
258  }
259  }
260  return NULL;
261  }
262  /* printf("try to find in file\n"); */
263  if (!ht->fp) return NULL;
264 
265  passwd = (struct mypasswd *) ht->buffer;
266 
267  while (fgets(buffer, 1024,ht->fp)) {
268  if(*buffer && *buffer!='\n' && string_to_entry(buffer, ht->num_fields, ht->delimiter, passwd, sizeof(ht->buffer)-1) &&
269  (!ht->ignorenis || (*buffer !='-' && *buffer != '+') ) ){
270  if(!ht->islist) {
271  if(!strcmp(passwd->field[ht->key_field], name))
272  return passwd;
273  }
274  else {
275  for (list = passwd->field[ht->key_field], nextlist = list; nextlist; list = nextlist) {
276  for(nextlist = list; *nextlist && *nextlist!=','; nextlist++);
277  if(!*nextlist) {
278  nextlist = 0;
279  } else {
280  *nextlist++ = 0;
281  }
282  if (!strcmp(list, name)) {
283  return passwd;
284  }
285  }
286  }
287 
288  }
289  }
290  fclose(ht->fp);
291  ht->fp = NULL;
292  return NULL;
293 }
294 
295 static struct mypasswd * get_pw_nam(char * name, struct hashtable* ht,
296  struct mypasswd **last_found)
297 {
298  int h;
299  struct mypasswd * hashentry;
300 
301  if (!ht || !name || (*name == '\0')) return NULL;
302  *last_found = NULL;
303  if (ht->tablesize > 0) {
304  h = hash (name, ht->tablesize);
305  for (hashentry = ht->table[h]; hashentry; hashentry = hashentry->next) {
306  if (!strcmp(hashentry->field[ht->key_field], name)){
307  /* save address of next item to check into buffer */
308  *last_found=hashentry->next;
309  return hashentry;
310  }
311  }
312 
313  return NULL;
314  }
315  if (ht->fp) {
316  fclose(ht->fp);
317  ht->fp = NULL;
318  }
319  if (!(ht->fp=fopen(ht->filename, "r"))) return NULL;
320  return get_next(name, ht, last_found);
321 }
322 
323 #ifdef TEST
324 
325 #define MALLOC_CHECK_ 1
326 
327 int main(void){
328  struct hashtable *ht;
329  char *buffer;
330  struct mypasswd* pw, *last_found;
331  int i;
332 
333  ht = build_hash_table("/etc/group", 4, 3, 1, 100, 0, ":");
334  if(!ht) {
335  printf("Hash table not built\n");
336  return -1;
337  }
338  for (i = 0; i < ht->tablesize; i++) {
339  if (ht->table[i]) {
340  printf("%d:\n", i);
341  for (pw = ht->table[i]; pw; pw = pw->next) {
342  printpw(pw, 4);
343  }
344  }
345  }
346 
347  while(fgets(buffer, 1024, stdin)){
348  buffer[strlen(buffer)-1] = 0;
349  pw = get_pw_nam(buffer, ht, &last_found);
350  printpw(pw,4);
351  while ((pw = get_next(buffer, ht, &last_found))) printpw(pw,4);
352  }
353  release_ht(ht);
354 }
355 
356 #else /* TEST */
357 typedef struct {
358  struct hashtable *ht;
359  struct mypasswd *pwd_fmt;
360  char const *filename;
361  char const *format;
362  char const *delimiter;
371 } rlm_passwd_t;
372 
373 static const conf_parser_t module_config[] = {
376  { FR_CONF_OFFSET("delimiter", rlm_passwd_t, delimiter), .dflt = ":" },
377 
378  { FR_CONF_OFFSET("ignore_nislike", rlm_passwd_t, ignore_nislike), .dflt = "yes" },
379 
380  { FR_CONF_OFFSET("ignore_empty", rlm_passwd_t, ignore_empty), .dflt = "yes" },
381 
382  { FR_CONF_OFFSET("allow_multiple_keys", rlm_passwd_t, allow_multiple), .dflt = "no" },
383 
384  { FR_CONF_OFFSET("hash_size", rlm_passwd_t, hash_size), .dflt = "100" },
386 };
387 
388 static int mod_instantiate(module_inst_ctx_t const *mctx)
389 {
390  int num_fields = 0, key_field = -1, listable = 0;
391  char const *s;
392  char *lf = NULL; /* destination list flags temporary */
393  size_t len;
394  int i;
395  fr_dict_attr_t const *da;
396  rlm_passwd_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_passwd_t);
397  CONF_SECTION *conf = mctx->inst->conf;
398 
399  fr_assert(inst->filename && *inst->filename);
400  fr_assert(inst->format && *inst->format);
401 
402  if (inst->hash_size == 0) {
403  cf_log_err(conf, "Invalid value '0' for hash_size");
404  return -1;
405  }
406 
407  lf = talloc_typed_strdup(inst, inst->format);
408  if (!lf) {
409  ERROR("Memory allocation failed for lf");
410  return -1;
411  }
412  memset(lf, 0, strlen(inst->format));
413 
414  s = inst->format - 1;
415  do {
416  if(s == inst->format - 1 || *s == ':'){
417  if(*(s+1) == '*'){
418  key_field = num_fields;
419  s++;
420  }
421  if(*(s+1) == ','){
422  listable = 1;
423  s++;
424  }
425  if(*(s+1) == '='){
426  lf[num_fields]=1;
427  s++;
428  }
429  if(*(s+1) == '~'){
430  lf[num_fields]=2;
431  s++;
432  }
433  num_fields++;
434  }
435  s++;
436  } while(*s);
437 
438  if(key_field < 0) {
439  cf_log_err(conf, "no field marked as key in format: %s",
440  inst->format);
441  return -1;
442  }
443 
444  inst->ht = build_hash_table(inst->filename, num_fields, key_field, listable,
445  inst->hash_size, inst->ignore_nislike, *inst->delimiter);
446  if (!inst->ht){
447  ERROR("Can't build hashtable from passwd file");
448  return -1;
449  }
450 
451  inst->pwd_fmt = mypasswd_alloc(inst->format, num_fields, &len);
452  if (!inst->pwd_fmt){
453  ERROR("Memory allocation failed");
454  release_ht(inst->ht);
455  inst->ht = NULL;
456  return -1;
457  }
458  if (!string_to_entry(inst->format, num_fields, ':', inst->pwd_fmt , len)) {
459  ERROR("Unable to convert format entry");
460  release_ht(inst->ht);
461  inst->ht = NULL;
462  return -1;
463  }
464 
465  memcpy(inst->pwd_fmt->listflag, lf, num_fields);
466 
467  talloc_free(lf);
468  for (i=0; i<num_fields; i++) {
469  if (*inst->pwd_fmt->field[i] == '*') inst->pwd_fmt->field[i]++;
470  if (*inst->pwd_fmt->field[i] == ',') inst->pwd_fmt->field[i]++;
471  if (*inst->pwd_fmt->field[i] == '=') inst->pwd_fmt->field[i]++;
472  if (*inst->pwd_fmt->field[i] == '~') inst->pwd_fmt->field[i]++;
473  }
474  if (!*inst->pwd_fmt->field[key_field]) {
475  cf_log_err(conf, "key field is empty");
476  release_ht(inst->ht);
477  inst->ht = NULL;
478  return -1;
479  }
480 
482  inst->pwd_fmt->field[key_field], true, true);
483  if (!da) {
484  PERROR("Unable to resolve attribute");
485  release_ht(inst->ht);
486  inst->ht = NULL;
487  return -1;
488  }
489 
490  inst->keyattr = da;
491  inst->num_fields = num_fields;
492  inst->key_field = key_field;
493  inst->listable = listable;
494 
495  DEBUG3("num_fields: %d key_field %d(%s) listable: %s", num_fields, key_field,
496  inst->pwd_fmt->field[key_field], listable ? "yes" : "no");
497 
498  return 0;
499 
500 #undef inst
501 }
502 
503 static int mod_detach(module_detach_ctx_t const *mctx)
504 {
505  rlm_passwd_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_passwd_t);
506  if (inst->ht) {
507  release_ht(inst->ht);
508  inst->ht = NULL;
509  }
510  talloc_free(inst->pwd_fmt);
511  return 0;
512 }
513 
514 static void result_add(TALLOC_CTX *ctx, rlm_passwd_t const *inst, request_t *request,
515  fr_pair_list_t *vps, struct mypasswd * pw, char when, char const *listname)
516 {
517  uint32_t i;
518  fr_pair_t *vp;
519 
520  for (i = 0; i < inst->num_fields; i++) {
521  if (inst->pwd_fmt->field[i] && *inst->pwd_fmt->field[i] && pw->field[i] &&
522  (i != inst->key_field) && inst->pwd_fmt->listflag[i] == when) {
523  if (!inst->ignore_empty || pw->field[i][0] != 0 ) { /* if value in key/value pair is not empty */
524  fr_dict_attr_t const *da = fr_dict_attr_by_name(NULL, fr_dict_root(request->dict), inst->pwd_fmt->field[i]);
525  size_t len;
526 
527  if (!da) {
528  REDEBUG("Ignoring unknown attribute '%s'", inst->pwd_fmt->field[i]);
529  continue;
530  }
531 
532  MEM(vp = fr_pair_afrom_da(ctx, da));
533 
534  len = strlen(pw->field[i]);
535 
536  switch (vp->vp_type) {
537  case FR_TYPE_STRING:
538  fr_pair_value_bstrndup(vp, pw->field[i], len, true);
539  break;
540 
541  case FR_TYPE_OCTETS:
542  fr_pair_value_memdup(vp, (uint8_t const *) pw->field[i], len, true);
543  break;
544 
545  default:
546  if (fr_pair_value_from_str(vp, pw->field[i], len, NULL, false) < 0) {
547  talloc_free(vp);
548  RPEDEBUG("Failed parsing '%s'", pw->field[i]);
549  continue;
550  }
551  }
552 
553  PAIR_VERIFY(vp);
554  (void) fr_pair_append(vps, vp);
555 
556  RDEBUG2("Added %s.%s: = %s ", listname, inst->pwd_fmt->field[i], pw->field[i]);
557  } else
558  RDEBUG2("NOOP %s.%s = %s ", listname, inst->pwd_fmt->field[i], pw->field[i]);
559  }
560  }
561 }
562 
563 static unlang_action_t CC_HINT(nonnull) mod_passwd_map(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
564 {
566 
567  char buffer[1024];
568  fr_pair_t *key, *i;
569  struct mypasswd *pw, *last_found;
570  fr_dcursor_t cursor;
571  int found = 0;
572 
573  key = fr_pair_find_by_da(&request->request_pairs, NULL, inst->keyattr);
574  if (!key) RETURN_MODULE_NOTFOUND;
575 
576  for (i = fr_pair_dcursor_by_da_init(&cursor, &request->request_pairs, inst->keyattr);
577  i;
578  i = fr_dcursor_next(&cursor)) {
579  /*
580  * Ensure we have the string form of the attribute
581  */
582 #ifdef STATIC_ANALYZER
583  /*
584  * static analyzer misses that fr_pair_print_value_quoted
585  * always terminates the buffer.
586  */
587  buffer[0] = '\0';
588 #endif
590  pw = get_pw_nam(buffer, inst->ht, &last_found);
591  if (!pw) continue;
592 
593  do {
594  result_add(request->control_ctx, inst, request, &request->control_pairs, pw, 0, "config");
595  result_add(request->reply_ctx, inst, request, &request->reply_pairs, pw, 1, "reply_items");
596  result_add(request->request_ctx, inst, request, &request->request_pairs, pw, 2, "request_items");
597  } while ((pw = get_next(buffer, inst->ht, &last_found)));
598 
599  found++;
600 
601  if (!inst->allow_multiple) break;
602  }
603 
604  if (!found) RETURN_MODULE_NOTFOUND;
605 
607 }
608 
609 extern module_rlm_t rlm_passwd;
611  .common = {
612  .magic = MODULE_MAGIC_INIT,
613  .name = "passwd",
614  .inst_size = sizeof(rlm_passwd_t),
617  .detach = mod_detach
618  },
619  .method_names = (module_method_name_t[]){
620  { .name1 = CF_IDENT_ANY, .name2 = CF_IDENT_ANY, .method = mod_passwd_map },
622  }
623 };
624 #endif /* TEST */
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
int const char * file
Definition: acutest.h:702
while(1)
Definition: acutest.h:856
#define RCSID(id)
Definition: build.h:444
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#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:406
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition: cf_parse.h:412
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define CF_IDENT_ANY
Definition: cf_util.h:78
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
Definition: dcursor.h:287
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
int main(int argc, char **argv)
Definition: dhcpclient.c:521
fr_dict_attr_t const * fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err, fr_dict_t const *dict_def, char const *attr, bool internal, bool foreign))
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
Definition: dict_util.c:2678
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
Definition: dict_util.c:2860
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
CONF_SECTION *_CONST conf
Module's instance configuration.
Definition: dl_module.h:166
dl_module_inst_t const * inst
Definition: dl_module.h:87
uint32_t fr_hash_string(char const *p)
Definition: hash.c:859
#define PERROR(_fmt,...)
Definition: log.h:228
#define DEBUG3(_fmt,...)
Definition: log.h:266
#define RPEDEBUG(fmt,...)
Definition: log.h:376
talloc_free(reap)
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:52
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:51
Specifies a module method identifier.
Definition: module_method.c:36
module_t common
Common fields presented by all modules.
Definition: module_rlm.h:37
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition: pair.c:688
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:278
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition: pair.c:2978
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition: pair.c:1340
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
Definition: pair.c:2781
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
Definition: pair.c:2586
static const conf_parser_t config[]
Definition: base.c:188
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
static rs_t * conf
Definition: radsniff.c:53
#define RETURN_MODULE_OK
Definition: rcode.h:57
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
#define RETURN_MODULE_NOTFOUND
Definition: rcode.h:61
static int mod_detach(module_detach_ctx_t const *mctx)
Definition: rlm_passwd.c:503
int num_fields
Definition: rlm_passwd.c:41
char * field[1]
Definition: rlm_passwd.c:35
char const * format
Definition: rlm_passwd.c:361
uint32_t num_fields
Definition: rlm_passwd.c:366
uint32_t hash_size
Definition: rlm_passwd.c:365
fr_dict_attr_t const * keyattr
Definition: rlm_passwd.c:369
module_rlm_t rlm_passwd
Definition: rlm_passwd.c:610
int ignorenis
Definition: rlm_passwd.c:43
char const * filename
Definition: rlm_passwd.c:360
bool ignore_nislike
Definition: rlm_passwd.c:364
FILE * fp
Definition: rlm_passwd.c:47
char buffer[1024]
Definition: rlm_passwd.c:46
uint32_t listable
Definition: rlm_passwd.c:368
static fr_dict_t const * dict_freeradius
Definition: rlm_passwd.c:51
bool allow_multiple
Definition: rlm_passwd.c:363
static struct mypasswd * get_pw_nam(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition: rlm_passwd.c:295
static struct mypasswd * mypasswd_alloc(char const *buffer, int num_fields, size_t *len)
Definition: rlm_passwd.c:73
static unlang_action_t mod_passwd_map(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: rlm_passwd.c:563
int tablesize
Definition: rlm_passwd.c:39
uint32_t key_field
Definition: rlm_passwd.c:367
char * listflag
Definition: rlm_passwd.c:34
struct mypasswd ** table
Definition: rlm_passwd.c:45
struct mypasswd * pwd_fmt
Definition: rlm_passwd.c:359
int islist
Definition: rlm_passwd.c:42
static struct hashtable * build_hash_table(char const *file, int num_fields, int key_field, int islist, int tablesize, int ignorenis, char delimiter)
Definition: rlm_passwd.c:159
struct mypasswd * next
Definition: rlm_passwd.c:33
bool ignore_empty
Definition: rlm_passwd.c:370
int key_field
Definition: rlm_passwd.c:40
static int string_to_entry(char const *string, int num_fields, char delimiter, struct mypasswd *passwd, size_t bufferlen)
Definition: rlm_passwd.c:85
struct hashtable * ht
Definition: rlm_passwd.c:358
char delimiter
Definition: rlm_passwd.c:48
static unsigned int hash(char const *username, unsigned int tablesize)
Definition: rlm_passwd.c:132
static void destroy_password(struct mypasswd *pass)
Definition: rlm_passwd.c:121
char * filename
Definition: rlm_passwd.c:44
char const * delimiter
Definition: rlm_passwd.c:362
static struct mypasswd * get_next(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition: rlm_passwd.c:242
static void release_ht(struct hashtable *ht)
Definition: rlm_passwd.c:153
static const conf_parser_t module_config[]
Definition: rlm_passwd.c:373
static void result_add(TALLOC_CTX *ctx, rlm_passwd_t const *inst, request_t *request, fr_pair_list_t *vps, struct mypasswd *pw, char when, char const *listname)
Definition: rlm_passwd.c:514
static void release_hash_table(struct hashtable *ht)
Definition: rlm_passwd.c:139
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_passwd.c:388
fr_dict_autoload_t rlm_passwd_dict[]
Definition: rlm_passwd.c:54
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1312
username
Definition: rlm_securid.c:420
#define FR_SBUFF_OUT(_start, _len_or_end)
#define MODULE_NAME_TERMINATOR
Definition: module.h:135
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:333
#define talloc_get_type_abort_const
Definition: talloc.h:270
@ T_BARE_WORD
Definition: token.h:120
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
Definition: pair.h:627
#define PAIR_VERIFY(_x)
Definition: pair.h:190
ssize_t fr_pair_print_value_quoted(fr_sbuff_t *out, fr_pair_t const *vp, fr_token_t quote)
Print the value of an attribute to a string.
Definition: pair_print.c:40
int nonnull(2, 5))
int format(printf, 5, 0))