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