diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2010-09-13 01:19:42 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2010-09-13 01:19:42 +0400 |
commit | f39fda2ddb7a8b80a33f155994f27794dd84a198 (patch) | |
tree | 1e13a8f658504a0f0e4f1cd2a0cf26d9f0d1dcec /accel-pptpd/radius/dict.c | |
parent | 65a665f6c655766a6d990e8aba47a811d0c3fecc (diff) | |
download | accel-ppp-xebd-f39fda2ddb7a8b80a33f155994f27794dd84a198.tar.gz accel-ppp-xebd-f39fda2ddb7a8b80a33f155994f27794dd84a198.zip |
log_pgsql: fixed bug - msg->tpd is uninitialized when general_log is called
radius: upgraded dictionary to support vendor-specific
Diffstat (limited to 'accel-pptpd/radius/dict.c')
-rw-r--r-- | accel-pptpd/radius/dict.c | 272 |
1 files changed, 176 insertions, 96 deletions
diff --git a/accel-pptpd/radius/dict.c b/accel-pptpd/radius/dict.c index 0e96962..2792351 100644 --- a/accel-pptpd/radius/dict.c +++ b/accel-pptpd/radius/dict.c @@ -2,6 +2,7 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#include <limits.h> #include "list.h" #include "radius.h" @@ -30,13 +31,13 @@ static int split(char *buf, char **ptr) for (i = 0; i < 3; i++) { buf = skip_word(buf); if (!*buf) - return -1; + return i; *buf = 0; buf = skip_space(buf + 1); if (!*buf) - return -1; + return i; ptr[i] = buf; } @@ -47,14 +48,14 @@ static int split(char *buf, char **ptr) //else if (*buf) // return -1; - return 0; + return i; } -struct rad_dict_attr_t *find_attr(struct rad_dict_t *dict, const char *name) +struct rad_dict_attr_t *find_attr(struct list_head *items, const char *name) { struct rad_dict_attr_t *attr; - list_for_each_entry(attr, &dict->items, entry) + list_for_each_entry(attr, items, entry) if (!strcmp(attr->name, name)) return attr; @@ -62,124 +63,191 @@ struct rad_dict_attr_t *find_attr(struct rad_dict_t *dict, const char *name) } #define BUF_SIZE 1024 -int rad_dict_load(const char *fname) + +static char *path, *fname1, *buf; +static int dict_load(const char *fname) { FILE *f; - char *buf, *ptr[3], *endptr; - int n = 0; + char *ptr[3], *endptr; + int r, n = 0; struct rad_dict_attr_t *attr; struct rad_dict_value_t *val; - + struct rad_dict_vendor_t *vendor; + struct list_head *items; + f = fopen(fname, "r"); if (!f) { log_error("radius: open dictioanary '%s': %s\n", fname, strerror(errno)); return -1; } - buf = malloc(BUF_SIZE); - if (!buf) { - log_emerg("radius: out of memory\n"); - fclose(f); - return -1; - } + items = &dict->items; - dict = malloc(sizeof(*dict)); - if (!dict) { - log_emerg("radius: out of memory\n"); - fclose(f); - free(buf); - return -1; - } - - INIT_LIST_HEAD(&dict->items); - while (fgets(buf, BUF_SIZE, f)) { n++; if (buf[0] == '#' || buf[0] == '\n' || buf[0] == 0) continue; - if (split(buf, ptr)) { - log_error("radius:%s:%i: syntaxis error\n", fname, n); - goto out_err; - } - if (!strcmp(buf, "ATTRIBUTE")) { - attr = malloc(sizeof(*attr)); - if (!attr) { - log_emerg("radius: out of memory\n"); - goto out_err; - } - memset(attr, 0, sizeof(*attr)); - INIT_LIST_HEAD(&attr->values); - list_add_tail(&attr->entry, &dict->items); - attr->name = strdup(ptr[0]); - attr->id = strtol(ptr[1], &endptr, 10); - if (*endptr != 0) { - log_error("radius:%s:%i: syntaxis error\n", fname, n); - goto out_err; - } - if (!strcmp(ptr[2], "integer")) - attr->type = ATTR_TYPE_INTEGER; - else if (!strcmp(ptr[2], "string")) - attr->type = ATTR_TYPE_STRING; - else if (!strcmp(ptr[2], "date")) - attr->type = ATTR_TYPE_DATE; - else if (!strcmp(ptr[2], "ipaddr")) - attr->type = ATTR_TYPE_IPADDR; - else if (!strcmp(ptr[2], "octets")) - attr->type = ATTR_TYPE_OCTETS; - else { - log_error("radius:%s:%i: unknown attribute type\n", fname, n); - goto out_err; - } - } else if (!strcmp(buf, "VALUE")) { - attr = find_attr(dict, ptr[0]); - if (!attr) { - log_error("radius:%s:%i: unknown attribute\n", fname, n); - goto out_err; - } - val = malloc(sizeof(*val)); - if (!val) { - log_emerg("radius: out of memory\n"); - goto out_err; - } - memset(val, 0, sizeof(*val)); - list_add_tail(&val->entry, &attr->values); - val->name = strdup(ptr[1]); - switch (attr->type) { - case ATTR_TYPE_INTEGER: - val->val.integer = strtol(ptr[2], &endptr, 10); - if (*endptr != 0) { - log_error("radius:%s:%i: syntaxis error\n", fname, n); - goto out_err; + r = split(buf, ptr); + if (r == 1) { + if (!strcmp(buf, "BEGIN-VENDOR")) { + vendor = rad_dict_find_vendor_name(ptr[0]); + if (!vendor) { + log_error("radius:%s:%i: vendor not found\n", fname, n); + goto out_err; + } + items = &vendor->items; + } else if (!strcmp(buf, "END-VENDOR")) + items = &dict->items; + else if (!strcmp(buf, "$INCLUDE")) { + for (r = strlen(path) - 1; r; r--) + if (path[r] == '/') { + path[r + 1] = 0; + break; } - break; - case ATTR_TYPE_STRING: - val->val.string = strdup(ptr[2]); - break; - case ATTR_TYPE_DATE: - log_warn("radius:%s:%i: VALUE of type 'date' is not implemented yet\n", fname, n); - break; - case ATTR_TYPE_IPADDR: - log_warn("radius:%s:%i: VALUE of type 'ipaddr' is not implemented yet\n", fname, n); - break; - } - } else { - log_error("radius:%s:%i: syntaxis error\n"); - goto out_err; - } + strcpy(fname1, path); + strcat(fname1, ptr[0]); + if (dict_load(fname1)) + goto out_err; + } else + goto out_err_syntax; + } else if (r == 2) { + if (!strcmp(buf, "VENDOR")) { + vendor = malloc(sizeof(*vendor)); + if (!vendor) { + log_emerg("radius: out of memory\n"); + goto out_err; + } + vendor->id = strtol(ptr[1], &endptr, 10); + if (*endptr != 0) + goto out_err_syntax; + vendor->name = strdup(ptr[0]); + if (!vendor->name) { + log_emerg("radius: out of memory\n"); + goto out_err; + } + INIT_LIST_HEAD(&vendor->items); + list_add_tail(&vendor->entry, &dict->vendors); + } else + goto out_err_syntax; + } else if (r == 3) { + if (!strcmp(buf, "ATTRIBUTE")) { + attr = malloc(sizeof(*attr)); + if (!attr) { + log_emerg("radius: out of memory\n"); + goto out_err; + } + memset(attr, 0, sizeof(*attr)); + INIT_LIST_HEAD(&attr->values); + list_add_tail(&attr->entry, items); + attr->name = strdup(ptr[0]); + attr->id = strtol(ptr[1], &endptr, 10); + if (*endptr != 0) + goto out_err_syntax; + if (!strcmp(ptr[2], "integer")) + attr->type = ATTR_TYPE_INTEGER; + else if (!strcmp(ptr[2], "string")) + attr->type = ATTR_TYPE_STRING; + else if (!strcmp(ptr[2], "date")) + attr->type = ATTR_TYPE_DATE; + else if (!strcmp(ptr[2], "ipaddr")) + attr->type = ATTR_TYPE_IPADDR; + else if (!strcmp(ptr[2], "octets")) + attr->type = ATTR_TYPE_OCTETS; + else { + log_error("radius:%s:%i: unknown attribute type\n", fname, n); + goto out_err; + } + } else if (!strcmp(buf, "VALUE")) { + attr = find_attr(items, ptr[0]); + if (!attr) { + log_error("radius:%s:%i: unknown attribute\n", fname, n); + goto out_err; + } + val = malloc(sizeof(*val)); + if (!val) { + log_emerg("radius: out of memory\n"); + goto out_err; + } + memset(val, 0, sizeof(*val)); + list_add_tail(&val->entry, &attr->values); + val->name = strdup(ptr[1]); + switch (attr->type) { + case ATTR_TYPE_INTEGER: + val->val.integer = strtol(ptr[2], &endptr, 10); + if (*endptr != 0) + goto out_err_syntax; + break; + case ATTR_TYPE_STRING: + val->val.string = strdup(ptr[2]); + break; + case ATTR_TYPE_DATE: + log_warn("radius:%s:%i: VALUE of type 'date' is not implemented yet\n", fname, n); + break; + case ATTR_TYPE_IPADDR: + log_warn("radius:%s:%i: VALUE of type 'ipaddr' is not implemented yet\n", fname, n); + break; + } + } else + goto out_err_syntax; + } else + goto out_err_syntax; } - free(buf); fclose(f); return 0; +out_err_syntax: + log_error("radius:%s:%i: syntaxis error\n", fname, n); out_err: - rad_dict_free(dict); - free(buf); fclose(f); return -1; } +int rad_dict_load(const char *fname) +{ + int r = -1; + + dict = malloc(sizeof(*dict)); + if (!dict) { + log_emerg("radius: out of memory\n"); + return -1; + } + INIT_LIST_HEAD(&dict->items); + INIT_LIST_HEAD(&dict->vendors); + + path = malloc(PATH_MAX); + if (!path) { + log_emerg("radius: out of memory\n"); + goto out_free_dict; + } + + fname1 = malloc(PATH_MAX); + if (!fname1) { + log_emerg("radius: out of memory\n"); + goto out_free_path; + } + + buf = malloc(BUF_SIZE); + if (!buf) { + log_emerg("radius: out of memory\n"); + goto out_free_fname1; + } + + strcpy(path, fname); + + r = dict_load(fname); + +out_free_fname1: + free(fname1); +out_free_path: + free(path); +out_free_dict: + if (r) + rad_dict_free(dict); + return r; +} + void rad_dict_free(struct rad_dict_t *dict) { struct rad_dict_attr_t *attr; @@ -246,3 +314,15 @@ struct rad_dict_value_t *rad_dict_find_val(struct rad_dict_attr_t *attr, rad_val return NULL; } + +struct rad_dict_vendor_t *rad_dict_find_vendor_name(const char *name) +{ + struct rad_dict_vendor_t *vendor; + + list_for_each_entry(vendor, &dict->vendors, entry) { + if (!strcmp(vendor->name, name)) + return vendor; + } + + return NULL; +} |