summaryrefslogtreecommitdiff
path: root/accel-pptpd/radius/dict.c
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2010-09-13 01:19:42 +0400
committerDmitry Kozlov <xeb@mail.ru>2010-09-13 01:19:42 +0400
commitf39fda2ddb7a8b80a33f155994f27794dd84a198 (patch)
tree1e13a8f658504a0f0e4f1cd2a0cf26d9f0d1dcec /accel-pptpd/radius/dict.c
parent65a665f6c655766a6d990e8aba47a811d0c3fecc (diff)
downloadaccel-ppp-f39fda2ddb7a8b80a33f155994f27794dd84a198.tar.gz
accel-ppp-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.c272
1 files changed, 176 insertions, 96 deletions
diff --git a/accel-pptpd/radius/dict.c b/accel-pptpd/radius/dict.c
index 0e969627..27923518 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;
+}