The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
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: 727587dc4ad1b7d5750e8c5d2ebacf1e8fdbce16 $
19 * @file rlm_passwd.c
20 * @brief Enables authentication against unix passwd files.
21 *
22 * @copyright 2000,2006 The FreeRADIUS server project
23 */
24RCSID("$Id: 727587dc4ad1b7d5750e8c5d2ebacf1e8fdbce16 $")
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
32struct mypasswd {
33 struct mypasswd *next;
34 char *listflag;
35 char *field[1];
36};
37
38struct hashtable {
42 int islist;
44 char * filename;
45 struct mypasswd **table;
46 char buffer[1024];
47 FILE *fp;
49};
50
52
55 { .out = &dict_freeradius, .proto = "freeradius" },
56 { NULL }
57};
58
59#ifdef TEST
60
61void 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
73static 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
85static 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
121static 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
132static unsigned int hash(char const * username, unsigned int tablesize)
133{
135
136 return h % tablesize;
137}
138
139static 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
153static void release_ht(struct hashtable * ht){
154 if (!ht) return;
156 talloc_free(ht);
157}
158
159static 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));
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){
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))){
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
242static 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
295static 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
327int 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 */
372
373static 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
388static 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->mi->data, rlm_passwd_t);
397 CONF_SECTION *conf = mctx->mi->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
503static int mod_detach(module_detach_ctx_t const *mctx)
504{
505 rlm_passwd_t *inst = talloc_get_type_abort(mctx->mi->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
514static 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) {
548 RPEDEBUG("Failed parsing '%s'", pw->field[i]);
549 continue;
550 }
551 }
552
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
563static 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
611 .common = {
612 .magic = MODULE_MAGIC_INIT,
613 .name = "passwd",
614 .inst_size = sizeof(rlm_passwd_t),
617 .detach = mod_detach
618 },
619 .method_group = {
620 .bindings = (module_method_binding_t[]){
621 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_passwd_map },
623 }
624 }
625};
626#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:576
int const char * file
Definition acutest.h:702
#define RCSID(id)
Definition build.h:483
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#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:418
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition cf_parse.h:424
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#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:288
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
int main(int argc, char **argv)
Definition dhcpclient.c:524
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:3081
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:3263
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2400
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
uint32_t fr_hash_string(char const *p)
Definition hash.c:865
#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.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for detach calls.
Definition module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
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:2981
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:693
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:1345
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:283
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:2784
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:2589
static const conf_parser_t config[]
Definition base.c:183
#define fr_assert(_expr)
Definition rad_assert.h:38
#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 struct mypasswd * get_next(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition rlm_passwd.c:242
static fr_dict_t const * dict_freeradius
Definition rlm_passwd.c:51
bool allow_multiple
Definition rlm_passwd.c:363
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
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 * mypasswd_alloc(char const *buffer, int num_fields, size_t *len)
Definition rlm_passwd.c:73
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
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
static struct mypasswd * get_pw_nam(char *name, struct hashtable *ht, struct mypasswd **last_found)
Definition rlm_passwd.c:295
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:1310
username
#define FR_SBUFF_OUT(_start, _len_or_end)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:329
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:151
Named methods exported by a module.
Definition module.h:173
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:445
#define talloc_get_type_abort_const
Definition talloc.h:282
@ 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:628
#define PAIR_VERIFY(_x)
Definition pair.h:191
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:53
int nonnull(2, 5))
int format(printf, 5, 0))