All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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: 8ca82f1c40e3db66f21a2ed7d36280afbbb219b8 $
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: 8ca82f1c40e3db66f21a2ed7d36280afbbb219b8 $")
25 
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/rad_assert.h>
29 
30 struct mypasswd {
31  struct mypasswd *next;
32  char *listflag;
33  char *field[1];
34 };
35 
36 struct hashtable {
37  int tablesize;
38  int keyfield;
39  int nfields;
40  int islist;
41  int ignorenis;
42  char * filename;
43  struct mypasswd **table;
44  char buffer[1024];
45  FILE *fp;
46  char delimiter;
47 };
48 
49 
50 #ifdef TEST
51 
52 #define rad_malloc(s) malloc(s)
53 
54 void printpw(struct mypasswd *pw, int nfields){
55  int i;
56  if (pw) {
57  for( i = 0; i < nfields; i++ ) printf("%s:", pw->field[i]);
58  printf("\n");
59  }
60  else printf ("Not found\n");
61  fflush(stdout);
62 }
63 #endif
64 
65 
66 static struct mypasswd * mypasswd_malloc(char const* buffer, int nfields, size_t* len)
67 {
68  struct mypasswd *t;
69  /* reserve memory for (struct mypasswd) + listflag (nfields * sizeof (char*)) +
70  ** fields (nfields * sizeof (char)) + strlen (inst->format) + 1 */
71 
72  *len=sizeof (struct mypasswd) + nfields * sizeof (char*) + nfields * sizeof (char ) + strlen(buffer) + 1;
73  t = (struct mypasswd *) rad_malloc(*len);
74  if (t) memset(t, 0, *len);
75  return (t);
76 }
77 
78 static int string_to_entry(char const* string, int nfields, char delimiter,
79  struct mypasswd *passwd, size_t bufferlen)
80 {
81  char *str;
82  size_t len, i;
83  int fn=0;
84  char *data_beg;
85 
86 
87  len = strlen(string);
88  if(!len) return 0;
89  if (string[len-1] == '\n') len--;
90  if(!len) return 0;
91  if (string[len-1] == '\r') len--;
92  if(!len) return 0;
93  if (!len || !passwd ||
94  bufferlen < (len + nfields * sizeof (char*) + nfields * sizeof (char) + sizeof (struct mypasswd) + 1) ) return 0;
95  passwd->next = NULL;
96  data_beg=(char *)passwd + sizeof(struct mypasswd);
97  str = data_beg + nfields * sizeof (char) + nfields * sizeof (char*);
98  memcpy (str, string, len);
99  str[len] = 0;
100  passwd->field[fn++] = str;
101  passwd->listflag = data_beg + nfields * sizeof (char *);
102  for(i=0; i < len; i++){
103  if (str[i] == delimiter) {
104  str[i] = 0;
105  passwd->field[fn++] = str + i + 1;
106  if (fn == nfields) break;
107  }
108  }
109  for (; fn < nfields; fn++) passwd->field[fn] = NULL;
110  return len + nfields * sizeof (char) + nfields * sizeof (char*) + sizeof (struct mypasswd) + 1;
111 }
112 
113 
114 static void destroy_password (struct mypasswd * pass)
115 {
116  struct mypasswd *p;
117  while ((p=pass)!=NULL) {
118  pass = pass->next;
119  free(p);
120  }
121 }
122 
123 
124 static unsigned int hash(char const * username, unsigned int tablesize)
125 {
126  int h=1;
127  while (*username) {
128  h = h * 7907 + *username++;
129  }
130  return h%tablesize;
131 }
132 
133 static void release_hash_table(struct hashtable * ht){
134  int i;
135 
136  if (!ht) return;
137  for (i = 0; i < ht->tablesize; i++)
138  if (ht->table[i])
139  destroy_password(ht->table[i]);
140  if (ht->table) {
141  free(ht->table);
142  ht->table = NULL;
143  }
144  if (ht->fp) {
145  fclose(ht->fp);
146  ht->fp = NULL;
147  }
148  ht->tablesize = 0;
149 }
150 
151 static void release_ht(struct hashtable * ht){
152  if (!ht) return;
153  release_hash_table(ht);
154  if (ht->filename) {
155  free(ht->filename);
156  ht->filename = NULL;
157  }
158  free(ht);
159 }
160 
161 static struct hashtable * build_hash_table (char const * file, int nfields,
162  int keyfield, int islist, int tablesize, int ignorenis, char delimiter)
163 {
164  struct hashtable* ht;
165  size_t len;
166  unsigned int h;
167  struct mypasswd *hashentry, *hashentry1;
168  char *list;
169  char *nextlist=0;
170  int i;
171  char buffer[1024];
172 
173  ht = (struct hashtable *) rad_malloc(sizeof(struct hashtable));
174  if(!ht) {
175  return NULL;
176  }
177  memset(ht, 0, sizeof(struct hashtable));
178  ht->filename = strdup(file);
179  if(!ht->filename) {
180  free(ht);
181  return NULL;
182  }
183  ht->tablesize = tablesize;
184  ht->nfields = nfields;
185  ht->keyfield = keyfield;
186  ht->islist = islist;
187  ht->ignorenis = ignorenis;
188  if (delimiter) ht->delimiter = delimiter;
189  else ht->delimiter = ':';
190  if(!tablesize) return ht;
191  if(!(ht->fp = fopen(file,"r"))) {
192  free(ht->filename);
193  free(ht);
194  return NULL;
195  }
196 
197  /*
198  * @todo: This code is SHIT. It's badly formatted. It's
199  * hard to understand. It re-implements tons of things
200  * which are already in the server core.
201  */
202  memset(ht->buffer, 0, 1024);
203  ht->table = (struct mypasswd **) rad_malloc (tablesize * sizeof(struct mypasswd *));
204  if (!ht->table) {
205  /*
206  * Unable allocate memory for hash table
207  * Still work without it
208  */
209  ht->tablesize = 0;
210  return ht;
211  }
212  memset(ht->table, 0, tablesize * sizeof(struct mypasswd *));
213  while (fgets(buffer, 1024, ht->fp)) {
214  if(*buffer && *buffer!='\n' && (!ignorenis || (*buffer != '+' && *buffer != '-')) ){
215  if(!(hashentry = mypasswd_malloc(buffer, nfields, &len))){
216  release_hash_table(ht);
217  return ht;
218  }
219  len = string_to_entry(buffer, nfields, ht->delimiter, hashentry, len);
220  if(!hashentry->field[keyfield] || *hashentry->field[keyfield] == '\0') {
221  free(hashentry);
222  continue;
223  }
224 
225  if (islist) {
226  list = hashentry->field[keyfield];
227  for (nextlist = list; *nextlist && *nextlist!=','; nextlist++);
228  if (*nextlist) *nextlist++ = 0;
229  else nextlist = 0;
230  }
231  h = hash(hashentry->field[keyfield], tablesize);
232  hashentry->next = ht->table[h];
233  ht->table[h] = hashentry;
234  if (islist) {
235  for(list=nextlist; nextlist; list = nextlist){
236  for (nextlist = list; *nextlist && *nextlist!=','; nextlist++);
237  if (*nextlist) *nextlist++ = 0;
238  else nextlist = 0;
239  if(!(hashentry1 = mypasswd_malloc("", nfields, &len))){
240  release_hash_table(ht);
241  return ht;
242  }
243  for (i=0; i<nfields; i++) hashentry1->field[i] = hashentry->field[i];
244  hashentry1->field[keyfield] = list;
245  h = hash(list, tablesize);
246  hashentry1->next = ht->table[h];
247  ht->table[h] = hashentry1;
248  }
249  }
250  }
251  }
252  fclose(ht->fp);
253  ht->fp = NULL;
254  return ht;
255 #undef passwd
256 }
257 
258 static struct mypasswd * get_next(char *name, struct hashtable *ht,
259  struct mypasswd **last_found)
260 {
261  struct mypasswd * passwd;
262  struct mypasswd * hashentry;
263  char buffer[1024];
264  char *list, *nextlist;
265 
266  if (ht->tablesize > 0) {
267  /* get saved address of next item to check from buffer */
268  hashentry = *last_found;
269  for (; hashentry; hashentry = hashentry->next) {
270  if (!strcmp(hashentry->field[ht->keyfield], name)) {
271  /* save new address */
272  *last_found = hashentry->next;
273  return hashentry;
274  }
275  }
276  return NULL;
277  }
278  /* printf("try to find in file\n"); */
279  if (!ht->fp) return NULL;
280 
281  passwd = (struct mypasswd *) ht->buffer;
282 
283  while (fgets(buffer, 1024,ht->fp)) {
284  if(*buffer && *buffer!='\n' && string_to_entry(buffer, ht->nfields, ht->delimiter, passwd, sizeof(ht->buffer)-1) &&
285  (!ht->ignorenis || (*buffer !='-' && *buffer != '+') ) ){
286  if(!ht->islist) {
287  if(!strcmp(passwd->field[ht->keyfield], name))
288  return passwd;
289  }
290  else {
291  for (list = passwd->field[ht->keyfield], nextlist = list; nextlist; list = nextlist) {
292  for(nextlist = list; *nextlist && *nextlist!=','; nextlist++);
293  if(!*nextlist) {
294  nextlist = 0;
295  } else {
296  *nextlist++ = 0;
297  }
298  if (!strcmp(list, name)) {
299  return passwd;
300  }
301  }
302  }
303 
304  }
305  }
306  fclose(ht->fp);
307  ht->fp = NULL;
308  return NULL;
309 }
310 
311 static struct mypasswd * get_pw_nam(char * name, struct hashtable* ht,
312  struct mypasswd **last_found)
313 {
314  int h;
315  struct mypasswd * hashentry;
316 
317  if (!ht || !name || *name == '\0') return NULL;
318  *last_found = NULL;
319  if (ht->tablesize > 0) {
320  h = hash (name, ht->tablesize);
321  for (hashentry = ht->table[h]; hashentry; hashentry = hashentry->next) {
322  if (!strcmp(hashentry->field[ht->keyfield], name)){
323  /* save address of next item to check into buffer */
324  *last_found=hashentry->next;
325  return hashentry;
326  }
327  }
328 
329  return NULL;
330  }
331  if (ht->fp) {
332  fclose(ht->fp);
333  ht->fp = NULL;
334  }
335  if (!(ht->fp=fopen(ht->filename, "r"))) return NULL;
336  return get_next(name, ht, last_found);
337 }
338 
339 #ifdef TEST
340 
341 #define MALLOC_CHECK_ 1
342 
343 int main(void){
344  struct hashtable *ht;
345  char *buffer;
346  struct mypasswd* pw, *last_found;
347  int i;
348 
349  ht = build_hash_table("/etc/group", 4, 3, 1, 100, 0, ":");
350  if(!ht) {
351  printf("Hash table not built\n");
352  return -1;
353  }
354  for (i = 0; i < ht->tablesize; i++) {
355  if (ht->table[i]) {
356  printf("%d:\n", i);
357  for (pw = ht->table[i]; pw; pw = pw->next) {
358  printpw(pw, 4);
359  }
360  }
361  }
362 
363  while(fgets(buffer, 1024, stdin)){
364  buffer[strlen(buffer)-1] = 0;
365  pw = get_pw_nam(buffer, ht, &last_found);
366  printpw(pw,4);
367  while ((pw = get_next(buffer, ht, &last_found))) printpw(pw,4);
368  }
369  release_ht(ht);
370 }
371 
372 #else /* TEST */
373 typedef struct rlm_passwd_t {
374  struct hashtable *ht;
375  struct mypasswd *pwdfmt;
376  char const *filename;
377  char const *format;
378  char const *delimiter;
381  uint32_t hash_size;
382  uint32_t nfields;
383  uint32_t keyfield;
384  uint32_t listable;
387 } rlm_passwd_t;
388 
389 static const CONF_PARSER module_config[] = {
390  { FR_CONF_OFFSET("filename", PW_TYPE_FILE_INPUT | PW_TYPE_REQUIRED, rlm_passwd_t, filename) },
392  { FR_CONF_OFFSET("delimiter", PW_TYPE_STRING, rlm_passwd_t, delimiter), .dflt = ":" },
393 
394  { FR_CONF_OFFSET("ignore_nislike", PW_TYPE_BOOLEAN, rlm_passwd_t, ignore_nislike), .dflt = "yes" },
395 
396  { FR_CONF_OFFSET("ignore_empty", PW_TYPE_BOOLEAN, rlm_passwd_t, ignore_empty), .dflt = "yes" },
397 
398  { FR_CONF_OFFSET("allow_multiple_keys", PW_TYPE_BOOLEAN, rlm_passwd_t, allow_multiple), .dflt = "no" },
399 
400  { FR_CONF_OFFSET("hash_size", PW_TYPE_INTEGER, rlm_passwd_t, hash_size), .dflt = "100" },
402 };
403 
404 static int mod_instantiate(CONF_SECTION *conf, void *instance)
405 {
406  int nfields=0, keyfield=-1, listable=0;
407  char const *s;
408  char *lf=NULL; /* destination list flags temporary */
409  size_t len;
410  int i;
411  fr_dict_attr_t const * da;
412  rlm_passwd_t *inst = instance;
413 
414  rad_assert(inst->filename && *inst->filename);
415  rad_assert(inst->format && *inst->format);
416 
417  if (inst->hash_size == 0) {
418  cf_log_err_cs(conf, "Invalid value '0' for hash_size");
419  return -1;
420  }
421 
422  lf = talloc_typed_strdup(inst, inst->format);
423  if ( !lf) {
424  ERROR("rlm_passwd: memory allocation failed for lf");
425  return -1;
426  }
427  memset(lf, 0, strlen(inst->format));
428  s = inst->format - 1;
429  do {
430  if(s == inst->format - 1 || *s == ':'){
431  if(*(s+1) == '*'){
432  keyfield = nfields;
433  s++;
434  }
435  if(*(s+1) == ','){
436  listable = 1;
437  s++;
438  }
439  if(*(s+1) == '='){
440  lf[nfields]=1;
441  s++;
442  }
443  if(*(s+1) == '~'){
444  lf[nfields]=2;
445  s++;
446  }
447  nfields++;
448  }
449  s++;
450  }while(*s);
451  if(keyfield < 0) {
452  cf_log_err_cs(conf, "no field marked as key in format: %s",
453  inst->format);
454  return -1;
455  }
456  if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hash_size, inst->ignore_nislike, *inst->delimiter)) ){
457  ERROR("rlm_passwd: can't build hashtable from passwd file");
458  return -1;
459  }
460  if (! (inst->pwdfmt = mypasswd_malloc(inst->format, nfields, &len)) ){
461  ERROR("rlm_passwd: memory allocation failed");
462  release_ht(inst->ht);
463  inst->ht = NULL;
464  return -1;
465  }
466  if (!string_to_entry(inst->format, nfields, ':', inst->pwdfmt , len)) {
467  ERROR("rlm_passwd: unable to convert format entry");
468  release_ht(inst->ht);
469  inst->ht = NULL;
470  return -1;
471  }
472 
473  memcpy(inst->pwdfmt->listflag, lf, nfields);
474 
475  talloc_free(lf);
476  for (i=0; i<nfields; i++) {
477  if (*inst->pwdfmt->field[i] == '*') inst->pwdfmt->field[i]++;
478  if (*inst->pwdfmt->field[i] == ',') inst->pwdfmt->field[i]++;
479  if (*inst->pwdfmt->field[i] == '=') inst->pwdfmt->field[i]++;
480  if (*inst->pwdfmt->field[i] == '~') inst->pwdfmt->field[i]++;
481  }
482  if (!*inst->pwdfmt->field[keyfield]) {
483  cf_log_err_cs(conf, "key field is empty");
484  release_ht(inst->ht);
485  inst->ht = NULL;
486  return -1;
487  }
488  if (! (da = fr_dict_attr_by_name(NULL, inst->pwdfmt->field[keyfield])) ) {
489  ERROR("rlm_passwd: unable to resolve attribute: %s", inst->pwdfmt->field[keyfield]);
490  release_ht(inst->ht);
491  inst->ht = NULL;
492  return -1;
493  }
494  inst->keyattr = da;
495  inst->nfields = nfields;
496  inst->keyfield = keyfield;
497  inst->listable = listable;
498  DEBUG2("rlm_passwd: nfields: %d keyfield %d(%s) listable: %s", nfields, keyfield, inst->pwdfmt->field[keyfield], listable?"yes":"no");
499  return 0;
500 
501 #undef inst
502 }
503 
504 static int mod_detach (void *instance) {
505 #define inst ((rlm_passwd_t *)instance)
506  if(inst->ht) {
507  release_ht(inst->ht);
508  inst->ht = NULL;
509  }
510  free(inst->pwdfmt);
511  return 0;
512 #undef inst
513 }
514 
515 static void addresult (TALLOC_CTX *ctx, rlm_passwd_t *inst, REQUEST *request,
516  VALUE_PAIR **vps, struct mypasswd * pw, char when, char const *listname)
517 {
518  uint32_t i;
519  VALUE_PAIR *vp;
520 
521  for (i = 0; i < inst->nfields; i++) {
522  if (inst->pwdfmt->field[i] && *inst->pwdfmt->field[i] && pw->field[i] && i != inst->keyfield && inst->pwdfmt->listflag[i] == when) {
523  if ( !inst->ignore_empty || pw->field[i][0] != 0 ) { /* if value in key/value pair is not empty */
524  vp = fr_pair_make(ctx, vps, inst->pwdfmt->field[i], pw->field[i], T_OP_EQ);
525  if (vp) {
526  RDEBUG("Added %s: '%s' to %s ", inst->pwdfmt->field[i], pw->field[i], listname);
527  }
528  } else
529  RDEBUG("NOOP %s: '%s' to %s ", inst->pwdfmt->field[i], pw->field[i], listname);
530  }
531  }
532 }
533 
534 static rlm_rcode_t CC_HINT(nonnull) mod_passwd_map(void *instance, REQUEST *request)
535 {
536 #define inst ((rlm_passwd_t *)instance)
537  char buffer[1024];
538  VALUE_PAIR *key, *i;
539  struct mypasswd * pw, *last_found;
540  vp_cursor_t cursor;
541 
542  key = fr_pair_find_by_da(request->packet->vps, inst->keyattr, TAG_ANY);
543  if (!key) {
544  return RLM_MODULE_NOTFOUND;
545  }
546 
547  for (i = fr_cursor_init(&cursor, &key);
548  i;
549  i = fr_cursor_next_by_num(&cursor, inst->keyattr->vendor, inst->keyattr->attr, TAG_ANY)) {
550  /*
551  * Ensure we have the string form of the attribute
552  */
553  fr_pair_value_snprint(buffer, sizeof(buffer), i, 0);
554  if (!(pw = get_pw_nam(buffer, inst->ht, &last_found)) ) {
555  continue;
556  }
557  do {
558  addresult(request, inst, request, &request->config, pw, 0, "config");
559  addresult(request->reply, inst, request, &request->reply->vps, pw, 1, "reply_items");
560  addresult(request->packet, inst, request, &request->packet->vps, pw, 2, "request_items");
561  } while ((pw = get_next(buffer, inst->ht, &last_found)));
562 
563  if (!inst->allow_multiple) {
564  break;
565  }
566  }
567 
568  return RLM_MODULE_OK;
569 
570 #undef inst
571 }
572 
573 extern module_t rlm_passwd;
574 module_t rlm_passwd = {
576  .name = "passwd",
577  .type = RLM_TYPE_HUP_SAFE,
578  .inst_size = sizeof(rlm_passwd_t),
579  .config = module_config,
580  .instantiate = mod_instantiate,
581  .detach = mod_detach,
582  .methods = {
583  [MOD_AUTHORIZE] = mod_passwd_map,
584  [MOD_ACCOUNTING] = mod_passwd_map,
585  [MOD_POST_AUTH] = mod_passwd_map,
586  [MOD_PRE_PROXY] = mod_passwd_map,
587  [MOD_POST_PROXY] = mod_passwd_map,
588 #ifdef WITH_COA
589  [MOD_RECV_COA] = mod_passwd_map,
590  [MOD_SEND_COA] = mod_passwd_map
591 #endif
592  },
593 };
594 #endif /* TEST */
module_t rlm_passwd
Definition: rlm_passwd.c:574
static const CONF_PARSER module_config[]
Definition: rlm_passwd.c:389
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
bool allow_multiple
Definition: rlm_passwd.c:379
static void destroy_password(struct mypasswd *pass)
Definition: rlm_passwd.c:114
char * field[1]
Definition: rlm_passwd.c:33
static void release_hash_table(struct hashtable *ht)
Definition: rlm_passwd.c:133
uint32_t hash_size
Definition: rlm_passwd.c:381
The module is OK, continue.
Definition: radiusd.h:91
static int mod_instantiate(CONF_SECTION *conf, void *instance)
Definition: rlm_passwd.c:404
Metadata exported by the module.
Definition: modules.h:134
Dictionary attribute.
Definition: dict.h:77
VALUE_PAIR * fr_cursor_next_by_num(vp_cursor_t *cursor, unsigned int vendor, unsigned int attr, int8_t tag)
Iterate over a collection of VALUE_PAIRs of a given type in the pairlist.
Definition: cursor.c:200
void * rad_malloc(size_t size)
Definition: util.c:411
static struct mypasswd * get_next(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition: rlm_passwd.c:258
bool ignore_empty
Definition: rlm_passwd.c:386
7 methods index for postauth section.
Definition: modules.h:48
static char const * name
static void release_ht(struct hashtable *ht)
Definition: rlm_passwd.c:151
#define RLM_MODULE_INIT
Definition: modules.h:86
void size_t fr_pair_value_snprint(char *out, size_t outlen, VALUE_PAIR const *vp, char quote)
Print the value of an attribute to a string.
Definition: pair.c:2107
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
char buffer[1024]
Definition: rlm_passwd.c:44
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
static struct mypasswd * get_pw_nam(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition: rlm_passwd.c:311
#define inst
Definition: token.h:46
#define RLM_TYPE_HUP_SAFE
Will be restarted on HUP.
Definition: modules.h:79
static int string_to_entry(char const *string, int nfields, char delimiter, struct mypasswd *passwd, size_t bufferlen)
Definition: rlm_passwd.c:78
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
uint32_t nfields
Definition: rlm_passwd.c:382
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
Definition: pair.h:144
static unsigned int hash(char const *username, unsigned int tablesize)
Definition: rlm_passwd.c:124
struct mypasswd ** table
Definition: rlm_passwd.c:43
#define rad_assert(expr)
Definition: rad_assert.h:38
struct hashtable * ht
Definition: rlm_passwd.c:374
int ignorenis
Definition: rlm_passwd.c:41
char delimiter
Definition: rlm_passwd.c:46
int keyfield
Definition: rlm_passwd.c:38
#define DEBUG2(fmt,...)
Definition: log.h:176
static rlm_rcode_t CC_HINT(nonnull)
Definition: rlm_passwd.c:534
int tablesize
Definition: rlm_passwd.c:37
struct rlm_passwd_t rlm_passwd_t
char const * delimiter
Definition: rlm_passwd.c:378
3 methods index for accounting section.
Definition: modules.h:44
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
struct mypasswd * next
Definition: rlm_passwd.c:31
static struct hashtable * build_hash_table(char const *file, int nfields, int keyfield, int islist, int tablesize, int ignorenis, char delimiter)
Definition: rlm_passwd.c:161
A truth value.
Definition: radius.h:56
int nfields
Definition: rlm_passwd.c:39
FILE * fp
Definition: rlm_passwd.c:45
32 Bit unsigned integer.
Definition: radius.h:34
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
static void addresult(TALLOC_CTX *ctx, rlm_passwd_t *inst, REQUEST *request, VALUE_PAIR **vps, struct mypasswd *pw, char when, char const *listname)
Definition: rlm_passwd.c:515
static rs_t * conf
Definition: radsniff.c:46
char * filename
Definition: rlm_passwd.c:42
VALUE_PAIR * fr_pair_find_by_da(VALUE_PAIR *head, fr_dict_attr_t const *da, int8_t tag)
Find the pair with the matching DAs.
Definition: pair.c:624
uint64_t magic
Used to validate module struct.
Definition: modules.h:135
#define TAG_ANY
Definition: pair.h:191
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
fr_dict_attr_t const * keyattr
Definition: rlm_passwd.c:385
6 methods index for postproxy section.
Definition: modules.h:47
char const * format
Definition: rlm_passwd.c:377
#define PW_TYPE_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: conffile.h:200
8 methods index for recvcoa section.
Definition: modules.h:50
char * listflag
Definition: rlm_passwd.c:32
int main(int argc, char *argv[])
Definition: radattr.c:959
struct mypasswd * pwdfmt
Definition: rlm_passwd.c:375
bool ignore_nislike
Definition: rlm_passwd.c:380
9 methods index for sendcoa section.
Definition: modules.h:51
uint32_t keyfield
Definition: rlm_passwd.c:383
String of printable characters.
Definition: radius.h:33
static int mod_detach(void *instance)
Definition: rlm_passwd.c:504
1 methods index for authorize section.
Definition: modules.h:42
User not found.
Definition: radiusd.h:95
#define RCSID(id)
Definition: build.h:135
static struct mypasswd * mypasswd_malloc(char const *buffer, int nfields, size_t *len)
Definition: rlm_passwd.c:66
int islist
Definition: rlm_passwd.c:40
char * talloc_typed_strdup(void const *t, char const *p)
Call talloc strdup, setting the type on the new chunk correctly.
Definition: missing.c:588
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
#define RDEBUG(fmt,...)
Definition: log.h:243
#define ERROR(fmt,...)
Definition: log.h:145
uint32_t listable
Definition: rlm_passwd.c:384
char const * filename
Definition: rlm_passwd.c:376
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_t *dict, char const *attr)
Locate a fr_dict_attr_t by its name.
Definition: dict.c:3493