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