1 /*
2 * $Id: dict.c,v 1.1 2004/11/14 07:26:26 paulus Exp $
3 *
4 * Copyright (C) 2002 Roaring Penguin Software Inc.
5 *
6 * Copyright (C) 1995,1996,1997 Lars Fenneberg
7 *
8 * Copyright 1992 Livingston Enterprises, Inc.
9 *
10 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
11 * and Merit Network, Inc. All Rights Reserved
12 *
13 * See the file COPYRIGHT for the respective terms and conditions.
14 * If the file is missing contact me at lf@elemental.net
15 * and I'll send you a copy.
16 *
17 */
18
19 #include <includes.h>
20 #include <radiusclient.h>
21
22 static DICT_ATTR *dictionary_attributes = NULL;
23 static DICT_VALUE *dictionary_values = NULL;
24 static VENDOR_DICT *vendor_dictionaries = NULL;
25
26 /*
27 * Function: rc_read_dictionary
28 *
29 * Purpose: Initialize the dictionary. Read all ATTRIBUTES into
30 * the dictionary_attributes list. Read all VALUES into
31 * the dictionary_values list. Construct VENDOR dictionaries
32 * as required.
33 *
34 */
35
rc_read_dictionary(char * filename)36 int rc_read_dictionary (char *filename)
37 {
38 FILE *dictfd;
39 char dummystr[AUTH_ID_LEN];
40 char namestr[AUTH_ID_LEN];
41 char valstr[AUTH_ID_LEN];
42 char attrstr[AUTH_ID_LEN];
43 char typestr[AUTH_ID_LEN];
44 char vendorstr[AUTH_ID_LEN];
45 int line_no;
46 DICT_ATTR *attr;
47 DICT_VALUE *dval;
48 VENDOR_DICT *vdict;
49 char buffer[256];
50 int value;
51 int type;
52 int n;
53 int retcode;
54 if ((dictfd = fopen (filename, "r")) == (FILE *) NULL)
55 {
56 error( "rc_read_dictionary: couldn't open dictionary %s: %s",
57 filename, strerror(errno));
58 return (-1);
59 }
60
61 line_no = 0;
62 retcode = 0;
63 while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL)
64 {
65 line_no++;
66
67 /* Skip empty space */
68 if (*buffer == '#' || *buffer == '\0' || *buffer == '\n')
69 {
70 continue;
71 }
72
73 if (strncmp (buffer, "VENDOR", 6) == 0) {
74 /* Read the VENDOR line */
75 if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) {
76 error("rc_read_dictionary: invalid vendor on line %d of dictionary %s",
77 line_no, filename);
78 retcode = -1;
79 break;
80 }
81 /* Validate entry */
82 if (strlen (namestr) > NAME_LENGTH) {
83 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
84 line_no, filename);
85 retcode = -1;
86 break;
87 }
88 /* Create new vendor entry */
89 vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT));
90 if (!vdict) {
91 novm("rc_read_dictionary");
92 retcode = -1;
93 break;
94 }
95 strcpy(vdict->vendorname, namestr);
96 vdict->vendorcode = value;
97 vdict->attributes = NULL;
98 vdict->next = vendor_dictionaries;
99 vendor_dictionaries = vdict;
100 }
101 else if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
102 {
103
104 /* Read the ATTRIBUTE line. It is one of:
105 * ATTRIBUTE attr_name attr_val type OR
106 * ATTRIBUTE attr_name attr_val type vendor */
107 vendorstr[0] = 0;
108 n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr);
109 if (n != 4 && n != 5)
110 {
111 error("rc_read_dictionary: invalid attribute on line %d of dictionary %s",
112 line_no, filename);
113 retcode = -1;
114 break;
115 }
116
117 /*
118 * Validate all entries
119 */
120 if (strlen (namestr) > NAME_LENGTH)
121 {
122 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
123 line_no, filename);
124 retcode = -1;
125 break;
126 }
127
128 if (strlen (vendorstr) > NAME_LENGTH)
129 {
130 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
131 line_no, filename);
132 retcode = -1;
133 break;
134 }
135
136 if (!isdigit (*valstr))
137 {
138 error("rc_read_dictionary: invalid value on line %d of dictionary %s",
139 line_no, filename);
140 retcode = -1;
141 break;
142 }
143 value = atoi (valstr);
144
145 if (strcmp (typestr, "string") == 0)
146 {
147 type = PW_TYPE_STRING;
148 }
149 else if (strcmp (typestr, "integer") == 0)
150 {
151 type = PW_TYPE_INTEGER;
152 }
153 else if (strcmp (typestr, "ipaddr") == 0)
154 {
155 type = PW_TYPE_IPADDR;
156 }
157 else if (strcmp (typestr, "date") == 0)
158 {
159 type = PW_TYPE_DATE;
160 }
161 else
162 {
163 error("rc_read_dictionary: invalid type on line %d of dictionary %s",
164 line_no, filename);
165 retcode = -1;
166 break;
167 }
168
169 /* Search for vendor if supplied */
170 if (*vendorstr) {
171 vdict = rc_dict_findvendor(vendorstr);
172 if (!vdict) {
173 error("rc_read_dictionary: unknown vendor on line %d of dictionary %s",
174 line_no, filename);
175 retcode = -1;
176 break;
177 }
178 } else {
179 vdict = NULL;
180 }
181 /* Create a new attribute for the list */
182 if ((attr =
183 (DICT_ATTR *) malloc (sizeof (DICT_ATTR)))
184 == (DICT_ATTR *) NULL)
185 {
186 novm("rc_read_dictionary");
187 retcode = -1;
188 break;
189 }
190 strcpy (attr->name, namestr);
191 if (vdict) {
192 attr->vendorcode = vdict->vendorcode;
193 } else {
194 attr->vendorcode = VENDOR_NONE;
195 }
196 attr->value = value;
197 attr->type = type;
198
199 /* Insert it into the list */
200 if (vdict) {
201 attr->next = vdict->attributes;
202 vdict->attributes = attr;
203 } else {
204 attr->next = dictionary_attributes;
205 dictionary_attributes = attr;
206 }
207 }
208 else if (strncmp (buffer, "VALUE", 5) == 0)
209 {
210 /* Read the VALUE line */
211 if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr,
212 namestr, valstr) != 4)
213 {
214 error("rc_read_dictionary: invalid value entry on line %d of dictionary %s",
215 line_no, filename);
216 retcode = -1;
217 break;
218 }
219
220 /*
221 * Validate all entries
222 */
223 if (strlen (attrstr) > NAME_LENGTH)
224 {
225 error("rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
226 line_no, filename);
227 retcode = -1;
228 break;
229 }
230
231 if (strlen (namestr) > NAME_LENGTH)
232 {
233 error("rc_read_dictionary: invalid name length on line %d of dictionary %s",
234 line_no, filename);
235 retcode = -1;
236 break;
237 }
238
239 if (!isdigit (*valstr))
240 {
241 error("rc_read_dictionary: invalid value on line %d of dictionary %s",
242 line_no, filename);
243 retcode = -1;
244 break;
245 }
246 value = atoi (valstr);
247
248 /* Create a new VALUE entry for the list */
249 if ((dval =
250 (DICT_VALUE *) malloc (sizeof (DICT_VALUE)))
251 == (DICT_VALUE *) NULL)
252 {
253 novm("rc_read_dictionary");
254 retcode = -1;
255 break;
256 }
257 strcpy (dval->attrname, attrstr);
258 strcpy (dval->name, namestr);
259 dval->value = value;
260
261 /* Insert it into the list */
262 dval->next = dictionary_values;
263 dictionary_values = dval;
264 }
265 else if (strncmp (buffer, "INCLUDE", 7) == 0)
266 {
267 /* Read the INCLUDE line */
268 if (sscanf (buffer, "%s%s", dummystr, namestr) != 2)
269 {
270 error("rc_read_dictionary: invalid include entry on line %d of dictionary %s",
271 line_no, filename);
272 retcode = -1;
273 break;
274 }
275 if (rc_read_dictionary(namestr) == -1)
276 {
277 retcode = -1;
278 break;
279 }
280 }
281 }
282 fclose (dictfd);
283 return retcode;
284 }
285
286 /*
287 * Function: rc_dict_getattr
288 *
289 * Purpose: Return the full attribute structure based on the
290 * attribute id number and vendor code. If vendor code is VENDOR_NONE,
291 * non-vendor-specific attributes are used
292 *
293 */
294
rc_dict_getattr(int attribute,int vendor)295 DICT_ATTR *rc_dict_getattr (int attribute, int vendor)
296 {
297 DICT_ATTR *attr;
298 VENDOR_DICT *dict;
299
300 if (vendor == VENDOR_NONE) {
301 attr = dictionary_attributes;
302 while (attr != (DICT_ATTR *) NULL) {
303 if (attr->value == attribute) {
304 return (attr);
305 }
306 attr = attr->next;
307 }
308 } else {
309 dict = rc_dict_getvendor(vendor);
310 if (!dict) {
311 return NULL;
312 }
313 attr = dict->attributes;
314 while (attr) {
315 if (attr->value == attribute) {
316 return attr;
317 }
318 attr = attr->next;
319 }
320 }
321 return NULL;
322 }
323
324 /*
325 * Function: rc_dict_findattr
326 *
327 * Purpose: Return the full attribute structure based on the
328 * attribute name.
329 *
330 */
331
rc_dict_findattr(char * attrname)332 DICT_ATTR *rc_dict_findattr (char *attrname)
333 {
334 DICT_ATTR *attr;
335 VENDOR_DICT *dict;
336
337 attr = dictionary_attributes;
338 while (attr != (DICT_ATTR *) NULL)
339 {
340 if (strcasecmp (attr->name, attrname) == 0)
341 {
342 return (attr);
343 }
344 attr = attr->next;
345 }
346
347 /* Search vendor-specific dictionaries */
348 dict = vendor_dictionaries;
349 while (dict) {
350 attr = dict->attributes;
351 while (attr) {
352 if (strcasecmp (attr->name, attrname) == 0) {
353 return (attr);
354 }
355 attr = attr->next;
356 }
357 dict = dict->next;
358 }
359 return ((DICT_ATTR *) NULL);
360 }
361
362
363 /*
364 * Function: rc_dict_findval
365 *
366 * Purpose: Return the full value structure based on the
367 * value name.
368 *
369 */
370
rc_dict_findval(char * valname)371 DICT_VALUE *rc_dict_findval (char *valname)
372 {
373 DICT_VALUE *val;
374
375 val = dictionary_values;
376 while (val != (DICT_VALUE *) NULL)
377 {
378 if (strcasecmp (val->name, valname) == 0)
379 {
380 return (val);
381 }
382 val = val->next;
383 }
384 return ((DICT_VALUE *) NULL);
385 }
386
387 /*
388 * Function: dict_getval
389 *
390 * Purpose: Return the full value structure based on the
391 * actual value and the associated attribute name.
392 *
393 */
394
rc_dict_getval(UINT4 value,char * attrname)395 DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname)
396 {
397 DICT_VALUE *val;
398
399 val = dictionary_values;
400 while (val != (DICT_VALUE *) NULL)
401 {
402 if (strcmp (val->attrname, attrname) == 0 &&
403 val->value == value)
404 {
405 return (val);
406 }
407 val = val->next;
408 }
409 return ((DICT_VALUE *) NULL);
410 }
411
412 /*
413 * Function: rc_dict_findvendor
414 *
415 * Purpose: Return the vendor's dictionary given the vendor name.
416 *
417 */
rc_dict_findvendor(char * vendorname)418 VENDOR_DICT * rc_dict_findvendor (char *vendorname)
419 {
420 VENDOR_DICT *dict;
421
422 dict = vendor_dictionaries;
423 while (dict) {
424 if (!strcmp(vendorname, dict->vendorname)) {
425 return dict;
426 }
427 dict = dict->next;
428 }
429 return NULL;
430 }
431
432 /*
433 * Function: rc_dict_getvendor
434 *
435 * Purpose: Return the vendor's dictionary given the vendor ID
436 *
437 */
rc_dict_getvendor(int id)438 VENDOR_DICT * rc_dict_getvendor (int id)
439 {
440 VENDOR_DICT *dict;
441
442 dict = vendor_dictionaries;
443 while (dict) {
444 if (id == dict->vendorcode) {
445 return dict;
446 }
447 dict = dict->next;
448 }
449 return NULL;
450 }
451