451 lines
9.8 KiB
C
451 lines
9.8 KiB
C
/*
|
|
* $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;
|
|
}
|