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