| /* |
| * $Id: dict.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ |
| * |
| * Copyright (C) 2002 Roaring Penguin Software Inc. |
| * |
| * Copyright (C) 1995,1996,1997 Lars Fenneberg |
| * |
| * Copyright 1992 Livingston Enterprises, Inc. |
| * |
| * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan |
| * and Merit Network, Inc. All Rights Reserved |
| * |
| * See the file COPYRIGHT for the respective terms and conditions. |
| * If the file is missing contact me at lf@elemental.net |
| * and I'll send you a copy. |
| * |
| */ |
| |
| #include <includes.h> |
| #include <radiusclient.h> |
| |
| static DICT_ATTR *dictionary_attributes = NULL; |
| static DICT_VALUE *dictionary_values = NULL; |
| static VENDOR_DICT *vendor_dictionaries = NULL; |
| |
| /* |
| * Function: rc_read_dictionary |
| * |
| * Purpose: Initialize the dictionary. Read all ATTRIBUTES into |
| * the dictionary_attributes list. Read all VALUES into |
| * the dictionary_values list. Construct VENDOR dictionaries |
| * as required. |
| * |
| */ |
| |
| int rc_read_dictionary (char *filename) |
| { |
| FILE *dictfd; |
| char dummystr[AUTH_ID_LEN]; |
| char namestr[AUTH_ID_LEN]; |
| char valstr[AUTH_ID_LEN]; |
| char attrstr[AUTH_ID_LEN]; |
| char typestr[AUTH_ID_LEN]; |
| char vendorstr[AUTH_ID_LEN]; |
| int line_no; |
| DICT_ATTR *attr; |
| DICT_VALUE *dval; |
| VENDOR_DICT *vdict; |
| char buffer[256]; |
| int value; |
| int type; |
| int n; |
| int retcode; |
| if ((dictfd = fopen (filename, "r")) == (FILE *) NULL) |
| { |
| error( "rc_read_dictionary: couldn't open dictionary %s: %s", |
| filename, strerror(errno)); |
| return (-1); |
| } |
| |
| line_no = 0; |
| retcode = 0; |
| while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL) |
| { |
| line_no++; |
| |
| /* Skip empty space */ |
| if (*buffer == '#' || *buffer == '\0' || *buffer == '\n') |
| { |
| continue; |
| } |
| |
| if (strncmp (buffer, "VENDOR", 6) == 0) { |
| /* Read the VENDOR line */ |
| if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) { |
| error("rc_read_dictionary: invalid vendor on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| /* Validate entry */ |
| if (strlen (namestr) > NAME_LENGTH) { |
| error("rc_read_dictionary: invalid name length on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| /* Create new vendor entry */ |
| vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT)); |
| if (!vdict) { |
| novm("rc_read_dictionary"); |
| retcode = -1; |
| break; |
| } |
| strcpy(vdict->vendorname, namestr); |
| vdict->vendorcode = value; |
| vdict->attributes = NULL; |
| vdict->next = vendor_dictionaries; |
| vendor_dictionaries = vdict; |
| } |
| else if (strncmp (buffer, "ATTRIBUTE", 9) == 0) |
| { |
| |
| /* Read the ATTRIBUTE line. It is one of: |
| * ATTRIBUTE attr_name attr_val type OR |
| * ATTRIBUTE attr_name attr_val type vendor */ |
| vendorstr[0] = 0; |
| n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr); |
| if (n != 4 && n != 5) |
| { |
| error("rc_read_dictionary: invalid attribute on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| /* |
| * Validate all entries |
| */ |
| if (strlen (namestr) > NAME_LENGTH) |
| { |
| error("rc_read_dictionary: invalid name length on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| if (strlen (vendorstr) > NAME_LENGTH) |
| { |
| error("rc_read_dictionary: invalid name length on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| if (!isdigit (*valstr)) |
| { |
| error("rc_read_dictionary: invalid value on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| value = atoi (valstr); |
| |
| if (strcmp (typestr, "string") == 0) |
| { |
| type = PW_TYPE_STRING; |
| } |
| else if (strcmp (typestr, "integer") == 0) |
| { |
| type = PW_TYPE_INTEGER; |
| } |
| else if (strcmp (typestr, "ipaddr") == 0) |
| { |
| type = PW_TYPE_IPADDR; |
| } |
| else if (strcmp (typestr, "date") == 0) |
| { |
| type = PW_TYPE_DATE; |
| } |
| else |
| { |
| error("rc_read_dictionary: invalid type on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| /* Search for vendor if supplied */ |
| if (*vendorstr) { |
| vdict = rc_dict_findvendor(vendorstr); |
| if (!vdict) { |
| error("rc_read_dictionary: unknown vendor on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| } else { |
| vdict = NULL; |
| } |
| /* Create a new attribute for the list */ |
| if ((attr = |
| (DICT_ATTR *) malloc (sizeof (DICT_ATTR))) |
| == (DICT_ATTR *) NULL) |
| { |
| novm("rc_read_dictionary"); |
| retcode = -1; |
| break; |
| } |
| strcpy (attr->name, namestr); |
| if (vdict) { |
| attr->vendorcode = vdict->vendorcode; |
| } else { |
| attr->vendorcode = VENDOR_NONE; |
| } |
| attr->value = value; |
| attr->type = type; |
| |
| /* Insert it into the list */ |
| if (vdict) { |
| attr->next = vdict->attributes; |
| vdict->attributes = attr; |
| } else { |
| attr->next = dictionary_attributes; |
| dictionary_attributes = attr; |
| } |
| } |
| else if (strncmp (buffer, "VALUE", 5) == 0) |
| { |
| /* Read the VALUE line */ |
| if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr, |
| namestr, valstr) != 4) |
| { |
| error("rc_read_dictionary: invalid value entry on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| /* |
| * Validate all entries |
| */ |
| if (strlen (attrstr) > NAME_LENGTH) |
| { |
| error("rc_read_dictionary: invalid attribute length on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| if (strlen (namestr) > NAME_LENGTH) |
| { |
| error("rc_read_dictionary: invalid name length on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| |
| if (!isdigit (*valstr)) |
| { |
| error("rc_read_dictionary: invalid value on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| value = atoi (valstr); |
| |
| /* Create a new VALUE entry for the list */ |
| if ((dval = |
| (DICT_VALUE *) malloc (sizeof (DICT_VALUE))) |
| == (DICT_VALUE *) NULL) |
| { |
| novm("rc_read_dictionary"); |
| retcode = -1; |
| break; |
| } |
| strcpy (dval->attrname, attrstr); |
| strcpy (dval->name, namestr); |
| dval->value = value; |
| |
| /* Insert it into the list */ |
| dval->next = dictionary_values; |
| dictionary_values = dval; |
| } |
| else if (strncmp (buffer, "INCLUDE", 7) == 0) |
| { |
| /* Read the INCLUDE line */ |
| if (sscanf (buffer, "%s%s", dummystr, namestr) != 2) |
| { |
| error("rc_read_dictionary: invalid include entry on line %d of dictionary %s", |
| line_no, filename); |
| retcode = -1; |
| break; |
| } |
| if (rc_read_dictionary(namestr) == -1) |
| { |
| retcode = -1; |
| break; |
| } |
| } |
| } |
| fclose (dictfd); |
| return retcode; |
| } |
| |
| /* |
| * Function: rc_dict_getattr |
| * |
| * Purpose: Return the full attribute structure based on the |
| * attribute id number and vendor code. If vendor code is VENDOR_NONE, |
| * non-vendor-specific attributes are used |
| * |
| */ |
| |
| DICT_ATTR *rc_dict_getattr (int attribute, int vendor) |
| { |
| DICT_ATTR *attr; |
| VENDOR_DICT *dict; |
| |
| if (vendor == VENDOR_NONE) { |
| attr = dictionary_attributes; |
| while (attr != (DICT_ATTR *) NULL) { |
| if (attr->value == attribute) { |
| return (attr); |
| } |
| attr = attr->next; |
| } |
| } else { |
| dict = rc_dict_getvendor(vendor); |
| if (!dict) { |
| return NULL; |
| } |
| attr = dict->attributes; |
| while (attr) { |
| if (attr->value == attribute) { |
| return attr; |
| } |
| attr = attr->next; |
| } |
| } |
| return NULL; |
| } |
| |
| /* |
| * Function: rc_dict_findattr |
| * |
| * Purpose: Return the full attribute structure based on the |
| * attribute name. |
| * |
| */ |
| |
| DICT_ATTR *rc_dict_findattr (char *attrname) |
| { |
| DICT_ATTR *attr; |
| VENDOR_DICT *dict; |
| |
| attr = dictionary_attributes; |
| while (attr != (DICT_ATTR *) NULL) |
| { |
| if (strcasecmp (attr->name, attrname) == 0) |
| { |
| return (attr); |
| } |
| attr = attr->next; |
| } |
| |
| /* Search vendor-specific dictionaries */ |
| dict = vendor_dictionaries; |
| while (dict) { |
| attr = dict->attributes; |
| while (attr) { |
| if (strcasecmp (attr->name, attrname) == 0) { |
| return (attr); |
| } |
| attr = attr->next; |
| } |
| dict = dict->next; |
| } |
| return ((DICT_ATTR *) NULL); |
| } |
| |
| |
| /* |
| * Function: rc_dict_findval |
| * |
| * Purpose: Return the full value structure based on the |
| * value name. |
| * |
| */ |
| |
| DICT_VALUE *rc_dict_findval (char *valname) |
| { |
| DICT_VALUE *val; |
| |
| val = dictionary_values; |
| while (val != (DICT_VALUE *) NULL) |
| { |
| if (strcasecmp (val->name, valname) == 0) |
| { |
| return (val); |
| } |
| val = val->next; |
| } |
| return ((DICT_VALUE *) NULL); |
| } |
| |
| /* |
| * Function: dict_getval |
| * |
| * Purpose: Return the full value structure based on the |
| * actual value and the associated attribute name. |
| * |
| */ |
| |
| DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname) |
| { |
| DICT_VALUE *val; |
| |
| val = dictionary_values; |
| while (val != (DICT_VALUE *) NULL) |
| { |
| if (strcmp (val->attrname, attrname) == 0 && |
| val->value == value) |
| { |
| return (val); |
| } |
| val = val->next; |
| } |
| return ((DICT_VALUE *) NULL); |
| } |
| |
| /* |
| * Function: rc_dict_findvendor |
| * |
| * Purpose: Return the vendor's dictionary given the vendor name. |
| * |
| */ |
| VENDOR_DICT * rc_dict_findvendor (char *vendorname) |
| { |
| VENDOR_DICT *dict; |
| |
| dict = vendor_dictionaries; |
| while (dict) { |
| if (!strcmp(vendorname, dict->vendorname)) { |
| return dict; |
| } |
| dict = dict->next; |
| } |
| return NULL; |
| } |
| |
| /* |
| * Function: rc_dict_getvendor |
| * |
| * Purpose: Return the vendor's dictionary given the vendor ID |
| * |
| */ |
| VENDOR_DICT * rc_dict_getvendor (int id) |
| { |
| VENDOR_DICT *dict; |
| |
| dict = vendor_dictionaries; |
| while (dict) { |
| if (id == dict->vendorcode) { |
| return dict; |
| } |
| dict = dict->next; |
| } |
| return NULL; |
| } |