Radcli library 1.3.1
A simple radius library
Loading...
Searching...
No Matches
dict.c
1/*
2 * Copyright (C) 1995,1996,1997 Lars Fenneberg
3 *
4 * Copyright 1992 Livingston Enterprises, Inc.
5 *
6 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
7 * and Merit Network, Inc. All Rights Reserved
8 *
9 * See the file COPYRIGHT for the respective terms and conditions.
10 * If the file is missing contact me at lf@elemental.net
11 * and I'll send you a copy.
12 *
13 */
14
22#include <config.h>
23#include <includes.h>
24#include <radcli/radcli.h>
25#include "util.h"
26
38DICT_ATTR *rc_dict_addattr(rc_handle *rh, char const * namestr, uint32_t value, int type, uint32_t vendorspec)
39{
40 DICT_ATTR *attr;
41
42 if (strlen (namestr) > RC_NAME_LENGTH)
43 {
44 rc_log(LOG_ERR, "rc_dict_addattr: invalid attribute length");
45 return NULL;
46 }
47
48 if (type < 0 || type >= PW_TYPE_MAX)
49 {
50 rc_log(LOG_ERR, "rc_dict_addattr: invalid attribute type");
51 return NULL;
52 }
53
54 /* Create a new attribute for the list */
55 if ((attr = malloc(sizeof (DICT_ATTR))) == NULL)
56 {
57 rc_log(LOG_CRIT, "rc_dict_addattr: out of memory");
58 return NULL;
59 }
60
61 strlcpy(attr->name, namestr, sizeof(attr->name));
62 attr->value = VATTRID_SET(value, vendorspec);
63 attr->type = type;
64
65 /* Insert it into the list */
66 attr->next = rh->dictionary_attributes;
67 rh->dictionary_attributes = attr;
68 return attr;
69}
70
81DICT_VALUE *rc_dict_addval(rc_handle *rh, char const * attrstr, char const * namestr, uint32_t value)
82{
83 DICT_VALUE *dval;
84
85 if (strlen(attrstr) > RC_NAME_LENGTH)
86 {
87 rc_log(LOG_ERR, "rc_dict_addval: invalid attribute length");
88 return NULL;
89 }
90
91 if (strlen(namestr) > RC_NAME_LENGTH)
92 {
93 rc_log(LOG_ERR, "rc_dict_addval: invalid name length");
94 return NULL;
95 }
96
97 /* Create a new VALUE entry for the list */
98 if ((dval = malloc(sizeof (DICT_VALUE))) == NULL)
99 {
100 rc_log(LOG_CRIT, "rc_dict_addval: out of memory");
101 return NULL;
102 }
103 strlcpy(dval->attrname, attrstr, sizeof(dval->attrname));
104 strlcpy(dval->name, namestr, sizeof(dval->name));
105 dval->value = value;
106
107 /* Insert it into the list */
108 dval->next = rh->dictionary_values;
109 rh->dictionary_values = dval;
110 return dval;
111}
112
122DICT_VENDOR *rc_dict_addvend(rc_handle *rh, char const * namestr, uint32_t vendorspec)
123{
124 DICT_VENDOR *dvend;
125
126 if (strlen(namestr) > RC_NAME_LENGTH)
127 {
128 rc_log(LOG_ERR, "rc_dict_addvend: invalid vendor name length");
129 return NULL;
130 }
131
132 /* Create a new VENDOR entry for the list */
133 dvend = malloc(sizeof(DICT_VENDOR));
134 if (dvend == NULL)
135 {
136 rc_log(LOG_CRIT, "rc_dict_init: out of memory");
137 return NULL;
138 }
139 strlcpy(dvend->vendorname, namestr, sizeof(dvend->vendorname));
140 dvend->vendorpec = vendorspec;
141
142 /* Insert it into the list */
143 dvend->next = rh->dictionary_vendors;
144 rh->dictionary_vendors = dvend;
145 return dvend;
146}
147
158static int rc_dict_init(rc_handle *rh, FILE *dictfd, char const *filename)
159{
160 char dummystr[AUTH_ID_LEN];
161 char namestr[AUTH_ID_LEN];
162 char valstr[AUTH_ID_LEN];
163 char attrstr[AUTH_ID_LEN];
164 char typestr[AUTH_ID_LEN];
165 char optstr[AUTH_ID_LEN];
166 char ifilename[PATH_MAX] = {0};
167 char *cp;
168 int line_no = 0;
169 DICT_ATTR *attr;
170 DICT_VALUE *dval;
171 DICT_VENDOR *dvend;
172 char buffer[256];
173 uint32_t value;
174 int type;
175 unsigned attr_vendorspec = 0;
176 const char *pfilename = filename;
177
178 if (pfilename == NULL)
179 {
180 pfilename = "memory";
181 }
182
183 while (fgets (buffer, sizeof (buffer), dictfd) != NULL)
184 {
185 line_no++;
186
187 /* Skip empty space */
188 if (*buffer == '#' || *buffer == '\0' || *buffer == '\n' || \
189 *buffer == '\r')
190 {
191 continue;
192 }
193
194 /* Strip out comments */
195 cp = strchr(buffer, '#');
196 if (cp != NULL)
197 {
198 *cp = '\0';
199 }
200
201 if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
202 {
203 optstr[0] = '\0';
204 /* Read the ATTRIBUTE line */
205 if (sscanf (buffer, "%63s%63s%63s%63s%63s", dummystr, namestr,
206 valstr, typestr, optstr) < 4)
207 {
208 rc_log(LOG_ERR,
209 "rc_dict_init: invalid attribute on line %d of "
210 "dictionary %s", line_no, pfilename);
211 return -1;
212 }
213
214 /*
215 * Validate all entries
216 */
217 if (strlen (namestr) > RC_NAME_LENGTH)
218 {
219 rc_log(LOG_ERR,
220 "rc_dict_init: invalid name length on line %d of "
221 "dictionary %s", line_no, pfilename);
222 return -1;
223 }
224
225 if (!isdigit (*valstr))
226 {
227 rc_log(LOG_ERR,
228 "rc_dict_init: invalid value on line %d of dictionary %s",
229 line_no, pfilename);
230 return -1;
231 }
232 value = atoi (valstr);
233
234 if (strcmp (typestr, "string") == 0)
235 {
236 type = PW_TYPE_STRING;
237 }
238 else if (strcmp (typestr, "integer") == 0)
239 {
240 type = PW_TYPE_INTEGER;
241 }
242 else if (strcmp (typestr, "ipaddr") == 0)
243 {
244 type = PW_TYPE_IPADDR;
245 }
246 else if (strcmp (typestr, "ipv4addr") == 0)
247 {
248 type = PW_TYPE_IPADDR;
249 }
250 else if (strcmp (typestr, "ipv6addr") == 0)
251 {
252 type = PW_TYPE_IPV6ADDR;
253 }
254 else if (strcmp (typestr, "ipv6prefix") == 0)
255 {
256 type = PW_TYPE_IPV6PREFIX;
257 }
258 else if (strcmp (typestr, "date") == 0)
259 {
260 type = PW_TYPE_DATE;
261 }
262 else
263 {
264 rc_log(LOG_ERR,
265 "rc_dict_init: invalid type on line %d of dictionary %s",
266 line_no, pfilename);
267 return -1;
268 }
269
270 dvend = NULL;
271 if (optstr[0] != '\0') {
272 char *cp1;
273 for (cp1 = optstr; cp1 != NULL; cp1 = cp) {
274 cp = strchr(cp1, ',');
275 if (cp != NULL) {
276 *cp = '\0';
277 cp++;
278 }
279 if (strncmp(cp1, "vendor=", 7) == 0)
280 cp1 += 7;
281 dvend = rc_dict_findvend(rh, cp1);
282 if (dvend == NULL) {
283 rc_log(LOG_ERR,
284 "rc_dict_init: unknown Vendor-Id %s on line %d of "
285 "dictionary %s", cp1, line_no, pfilename);
286 return -1;
287 }
288 }
289 }
290
291 /* Create a new attribute for the list */
292 if ((attr = malloc (sizeof (DICT_ATTR))) == NULL)
293 {
294 rc_log(LOG_CRIT, "rc_dict_init: out of memory");
295 return -1;
296 }
297 strcpy (attr->name, namestr);
298 attr->type = type;
299
300 if (dvend != NULL) {
301 attr->value = VATTRID_SET(value, dvend->vendorpec);
302 } else {
303 attr->value = VATTRID_SET(value, attr_vendorspec);
304 }
305
306 /* Insert it into the list */
307 attr->next = rh->dictionary_attributes;
308 rh->dictionary_attributes = attr;
309 }
310 else if (strncmp (buffer, "VALUE", 5) == 0)
311 {
312 /* Read the VALUE line */
313 if (sscanf (buffer, "%63s%63s%63s%63s", dummystr, attrstr,
314 namestr, valstr) != 4)
315 {
316 rc_log(LOG_ERR,
317 "rc_dict_init: invalid value entry on line %d of "
318 "dictionary %s", line_no, pfilename);
319 return -1;
320 }
321
322 /*
323 * Validate all entries
324 */
325 if (strlen (attrstr) > RC_NAME_LENGTH)
326 {
327 rc_log(LOG_ERR,
328 "rc_dict_init: invalid attribute length on line %d of "
329 "dictionary %s", line_no, pfilename);
330 return -1;
331 }
332
333 if (strlen (namestr) > RC_NAME_LENGTH)
334 {
335 rc_log(LOG_ERR,
336 "rc_dict_init: invalid name length on line %d of "
337 "dictionary %s", line_no, pfilename);
338 return -1;
339 }
340
341 if (!isdigit (*valstr))
342 {
343 rc_log(LOG_ERR,
344 "rc_dict_init: invalid value on line %d of dictionary %s",
345 line_no, pfilename);
346 return -1;
347 }
348 value = atoi (valstr);
349
350 /* Create a new VALUE entry for the list */
351 if ((dval = malloc (sizeof (DICT_VALUE))) == NULL)
352 {
353 rc_log(LOG_CRIT, "rc_dict_init: out of memory");
354 return -1;
355 }
356 strcpy (dval->attrname, attrstr);
357 strcpy (dval->name, namestr);
358 dval->value = value;
359
360 /* Insert it into the list */
361 dval->next = rh->dictionary_values;
362 rh->dictionary_values = dval;
363 }
364 else if ((filename != NULL) &&
365 (strncmp (buffer, "$INCLUDE", 8) == 0))
366 {
367 /* Read the $INCLUDE line */
368 if (sscanf (buffer, "%63s%63s", dummystr, namestr) != 2)
369 {
370 rc_log(LOG_ERR,
371 "rc_dict_init: invalid include entry on line %d of "
372 "dictionary %s", line_no, pfilename);
373 return -1;
374 }
375 strncpy(ifilename, namestr, sizeof(ifilename));
376 /* Append directory if necessary */
377 if (namestr[0] != '/') {
378 cp = strrchr(filename, '/');
379 if (cp != NULL) {
380 *cp = '\0';
381 snprintf(ifilename, sizeof(ifilename), "%s/%s", filename, namestr);
382 *cp = '/';
383 }
384 }
385 if (rc_read_dictionary(rh, ifilename) < 0)
386 {
387 return -1;
388 }
389 }
390 else if (strncmp (buffer, "END-VENDOR", 10) == 0)
391 {
392 attr_vendorspec = 0;
393 }
394 else if (strncmp (buffer, "BEGIN-VENDOR", 12) == 0)
395 {
396 DICT_VENDOR *v;
397 /* Read the vendor name */
398 if (sscanf (buffer+12, "%63s", dummystr) != 1)
399 {
400 rc_log(LOG_ERR,
401 "rc_dict_init: invalid Vendor-Id on line %d of "
402 "dictionary %s", line_no, pfilename);
403 return -1;
404 }
405
406 v = rc_dict_findvend(rh, dummystr);
407 if (v == NULL) {
408 rc_log(LOG_ERR,
409 "rc_dict_init: unknown Vendor %s on line %d of "
410 "dictionary %s", dummystr, line_no, pfilename);
411 return -1;
412 }
413
414 attr_vendorspec = v->vendorpec;
415 }
416 else if (strncmp (buffer, "VENDOR", 6) == 0)
417 {
418 /* Read the VALUE line */
419 if (sscanf (buffer, "%63s%63s%63s", dummystr, attrstr, valstr) != 3)
420 {
421 rc_log(LOG_ERR,
422 "rc_dict_init: invalid Vendor-Id on line %d of "
423 "dictionary %s", line_no, pfilename);
424 return -1;
425 }
426
427 /* Validate all entries */
428 if (strlen (attrstr) > RC_NAME_LENGTH)
429 {
430 rc_log(LOG_ERR,
431 "rc_dict_init: invalid attribute length on line %d of "
432 "dictionary %s", line_no, pfilename);
433 return -1;
434 }
435
436 if (!isdigit (*valstr))
437 {
438 rc_log(LOG_ERR,
439 "rc_dict_init: invalid Vendor-Id on line %d of "
440 "dictionary %s", line_no, pfilename);
441 return -1;
442 }
443 value = atoi (valstr);
444
445 /* Create a new VENDOR entry for the list */
446 dvend = malloc(sizeof(DICT_VENDOR));
447 if (dvend == NULL)
448 {
449 rc_log(LOG_CRIT, "rc_dict_init: out of memory");
450 return -1;
451 }
452 strcpy (dvend->vendorname, attrstr);
453 dvend->vendorpec = value;
454
455 /* Insert it into the list */
456 dvend->next = rh->dictionary_vendors;
457 rh->dictionary_vendors = dvend;
458 }
459 }
460 return 0;
461}
462
472int rc_read_dictionary (rc_handle *rh, char const *filename)
473{
474 FILE *dictfd;
475 int ret_val = 0;
476
477 if (rh->first_dict_read != NULL && strcmp(filename, rh->first_dict_read) == 0)
478 return 0;
479
480 if ((dictfd = fopen (filename, "r")) == NULL)
481 {
482 rc_log(LOG_ERR, "rc_read_dictionary couldn't open dictionary %s: %s",
483 filename, strerror(errno));
484 return -1;
485 }
486
487 ret_val = rc_dict_init(rh, dictfd, filename);
488
489 fclose (dictfd);
490
491 if (rh->first_dict_read == NULL)
492 rh->first_dict_read = strdup(filename);
493
494 return ret_val;
495}
496
507int rc_read_dictionary_from_buffer (rc_handle *rh, char const *buf, size_t size)
508{
509 FILE *dictfd;
510 int ret_val = 0;
511
512 if ((dictfd = fmemopen ((void *)buf, size, "r")) == NULL)
513 {
514 rc_log(LOG_ERR, "rc_read_dictionary_from_buffer failed to read "
515 "input buffer %s", strerror(errno));
516 return -1;
517 }
518
519 ret_val = rc_dict_init(rh, dictfd, NULL);
520
521 fclose (dictfd);
522
523 return ret_val;
524}
525
532DICT_ATTR *rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
533{
534 DICT_ATTR *attr;
535
536 attr = rh->dictionary_attributes;
537 while (attr != NULL)
538 {
539 if (attr->value == attribute)
540 {
541 return attr;
542 }
543 attr = attr->next;
544 }
545 return NULL;
546}
547
555DICT_ATTR *rc_dict_findattr(rc_handle const *rh, char const *attrname)
556{
557 DICT_ATTR *attr;
558
559 attr = rh->dictionary_attributes;
560 while (attr != NULL)
561 {
562 if (strcasecmp (attr->name, attrname) == 0)
563 {
564 return attr;
565 }
566 attr = attr->next;
567 }
568 return NULL;
569}
570
571
578DICT_VALUE *rc_dict_findval(rc_handle const *rh, char const *valname)
579{
580 DICT_VALUE *val;
581 val = rh->dictionary_values;
582 while (val != NULL)
583 {
584 if (strcasecmp (val->name, valname) == 0)
585 {
586 return val;
587 }
588 val = val->next;
589 }
590 return NULL;
591}
592
599DICT_VENDOR *rc_dict_findvend(rc_handle const *rh, char const *vendorname)
600{
601 DICT_VENDOR *vend;
602
603 for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
604 if (strcasecmp(vend->vendorname, vendorname) == 0)
605 return vend;
606 return NULL;
607}
608
615DICT_VENDOR *rc_dict_getvend (rc_handle const *rh, uint32_t vendorspec)
616{
617 DICT_VENDOR *vend;
618
619 for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
620 if (vend->vendorpec == vendorspec)
621 return vend;
622 return NULL;
623}
624
632DICT_VALUE *rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
633{
634 DICT_VALUE *val;
635
636 val = rh->dictionary_values;
637 while (val != NULL)
638 {
639 if (strcmp (val->attrname, attrname) == 0 &&
640 val->value == value)
641 {
642 return val;
643 }
644 val = val->next;
645 }
646 return NULL;
647}
648
653void rc_dict_free(rc_handle *rh)
654{
655 DICT_ATTR *attr, *nattr;
656 DICT_VALUE *val, *nval;
657 DICT_VENDOR *vend, *nvend;
658
659 for (attr = rh->dictionary_attributes; attr != NULL; attr = nattr) {
660 nattr = attr->next;
661 free(attr);
662 }
663 for (val = rh->dictionary_values; val != NULL; val = nval) {
664 nval = val->next;
665 free(val);
666 }
667 for (vend = rh->dictionary_vendors; vend != NULL; vend = nvend) {
668 nvend = vend->next;
669 free(vend);
670 }
671 rh->dictionary_attributes = NULL;
672 rh->dictionary_values = NULL;
673 rh->dictionary_vendors = NULL;
674}
DICT_VALUE * rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
Definition: dict.c:632
DICT_ATTR * rc_dict_addattr(rc_handle *rh, char const *namestr, uint32_t value, int type, uint32_t vendorspec)
Definition: dict.c:38
DICT_VENDOR * rc_dict_findvend(rc_handle const *rh, char const *vendorname)
Definition: dict.c:599
int rc_read_dictionary_from_buffer(rc_handle *rh, char const *buf, size_t size)
Definition: dict.c:507
DICT_VALUE * rc_dict_findval(rc_handle const *rh, char const *valname)
Definition: dict.c:578
int rc_read_dictionary(rc_handle *rh, char const *filename)
Definition: dict.c:472
DICT_VENDOR * rc_dict_getvend(rc_handle const *rh, uint32_t vendorspec)
Definition: dict.c:615
DICT_ATTR * rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
Definition: dict.c:532
void rc_dict_free(rc_handle *rh)
Definition: dict.c:653
DICT_VALUE * rc_dict_addval(rc_handle *rh, char const *attrstr, char const *namestr, uint32_t value)
Definition: dict.c:81
DICT_VENDOR * rc_dict_addvend(rc_handle *rh, char const *namestr, uint32_t vendorspec)
Definition: dict.c:122
DICT_ATTR * rc_dict_findattr(rc_handle const *rh, char const *attrname)
Definition: dict.c:555
@ PW_TYPE_IPADDR
The attribute is an IPv4 address in host-byte order.
Definition: radcli.h:115
@ PW_TYPE_IPV6ADDR
The attribute is an 128-bit IPv6 address.
Definition: radcli.h:117
@ PW_TYPE_MAX
Maximum number of types (last+1)
Definition: radcli.h:119
@ PW_TYPE_IPV6PREFIX
The attribute is an IPv6 prefix; the lvalue will indicate its size.
Definition: radcli.h:118
@ PW_TYPE_INTEGER
The attribute is a 32-bit integer.
Definition: radcli.h:114
@ PW_TYPE_DATE
The attribute contains a 32-bit number indicating the seconds since epoch.
Definition: radcli.h:116
@ PW_TYPE_STRING
The attribute is a printable string.
Definition: radcli.h:113
rc_attr_type type
string, int, etc..
Definition: radcli.h:434
uint64_t value
attribute index and vendor number; use VENDOR() and ATTRID() to separate.
Definition: radcli.h:433
char name[RC_NAME_LENGTH+1]
attribute name.
Definition: radcli.h:432