--- /dev/null
+/*
+ * $Id: dict.c,v 1.1 2002/01/22 16:03:02 dfs 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 <config.h>
+#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;
+
+ if ((dictfd = fopen (filename, "r")) == (FILE *) NULL)
+ {
+ rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s",
+ filename, strerror(errno));
+ return (-1);
+ }
+
+ line_no = 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) {
+ rc_log(LOG_ERR, "rc_read_dictionary: invalid vendor on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+ /* Validate entry */
+ if (strlen (namestr) > NAME_LENGTH) {
+ rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+ /* Create new vendor entry */
+ vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT));
+ if (!vdict) {
+ rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+ return (-1);
+ }
+ 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)
+ {
+ rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ /*
+ * Validate all entries
+ */
+ if (strlen (namestr) > NAME_LENGTH)
+ {
+ rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ if (strlen (vendorstr) > NAME_LENGTH)
+ {
+ rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ if (!isdigit (*valstr))
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid value on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+ 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
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid type on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ /* Search for vendor if supplied */
+ if (*vendorstr) {
+ vdict = rc_dict_findvendor(vendorstr);
+ if (!vdict) {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: unknown vendor on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+ } else {
+ vdict = NULL;
+ }
+ /* Create a new attribute for the list */
+ if ((attr =
+ (DICT_ATTR *) malloc (sizeof (DICT_ATTR)))
+ == (DICT_ATTR *) NULL)
+ {
+ rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+ return (-1);
+ }
+ 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)
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ /*
+ * Validate all entries
+ */
+ if (strlen (attrstr) > NAME_LENGTH)
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ if (strlen (namestr) > NAME_LENGTH)
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+
+ if (!isdigit (*valstr))
+ {
+ rc_log(LOG_ERR,
+ "rc_read_dictionary: invalid value on line %d of dictionary %s",
+ line_no, filename);
+ return (-1);
+ }
+ value = atoi (valstr);
+
+ /* Create a new VALUE entry for the list */
+ if ((dval =
+ (DICT_VALUE *) malloc (sizeof (DICT_VALUE)))
+ == (DICT_VALUE *) NULL)
+ {
+ rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+ return (-1);
+ }
+ strcpy (dval->attrname, attrstr);
+ strcpy (dval->name, namestr);
+ dval->value = value;
+
+ /* Insert it into the list */
+ dval->next = dictionary_values;
+ dictionary_values = dval;
+ }
+ }
+ fclose (dictfd);
+ return (0);
+}
+
+/*
+ * 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;
+}