* Fix memory leaks in counter_detach
* Call counter_detach if we fail in counter_instantiate
* More verbose logging when we fail in counter_instantiate
{ NULL, -1, 0, NULL, NULL }
};
{ NULL, -1, 0, NULL, NULL }
};
+static int counter_detach(void *instance);
+
/*
* See if the counter matches.
/*
* See if the counter matches.
return counter.user_counter - check->lvalue;
}
return counter.user_counter - check->lvalue;
}
static int add_defaults(rlm_counter_t *data)
{
datum key_datum;
static int add_defaults(rlm_counter_t *data)
{
datum key_datum;
*/
data = rad_malloc(sizeof(*data));
if (!data) {
*/
data = rad_malloc(sizeof(*data));
if (!data) {
+ radlog(L_ERR, "rlm_counter: rad_malloc() failed.");
return -1;
}
memset(data, 0, sizeof(*data));
return -1;
}
memset(data, 0, sizeof(*data));
*/
if (data->key_name == NULL) {
radlog(L_ERR, "rlm_counter: 'key' must be set.");
*/
if (data->key_name == NULL) {
radlog(L_ERR, "rlm_counter: 'key' must be set.");
+ counter_detach(data);
+ return -1;
}
dattr = dict_attrbyname(data->key_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: No such attribute %s",
data->key_name);
}
dattr = dict_attrbyname(data->key_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: No such attribute %s",
data->key_name);
return -1;
}
data->key_attr = dattr->attr;
return -1;
}
data->key_attr = dattr->attr;
*/
if (data->count_attribute == NULL) {
radlog(L_ERR, "rlm_counter: 'count-attribute' must be set.");
*/
if (data->count_attribute == NULL) {
radlog(L_ERR, "rlm_counter: 'count-attribute' must be set.");
+ counter_detach(data);
+ return -1;
}
dattr = dict_attrbyname(data->count_attribute);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: No such attribute %s",
data->count_attribute);
}
dattr = dict_attrbyname(data->count_attribute);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: No such attribute %s",
data->count_attribute);
return -1;
}
data->count_attr = dattr->attr;
return -1;
}
data->count_attr = dattr->attr;
*/
if (data->counter_name == NULL) {
radlog(L_ERR, "rlm_counter: 'counter-name' must be set.");
*/
if (data->counter_name == NULL) {
radlog(L_ERR, "rlm_counter: 'counter-name' must be set.");
+ counter_detach(data);
+ return -1;
}
memset(&flags, 0, sizeof(flags));
}
memset(&flags, 0, sizeof(flags));
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: Failed to create counter attribute %s",
data->counter_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: Failed to create counter attribute %s",
data->counter_name);
return -1;
}
data->dict_attr = dattr->attr;
return -1;
}
data->dict_attr = dattr->attr;
*/
if (data->check_name == NULL) {
radlog(L_ERR, "rlm_counter: 'check-name' must be set.");
*/
if (data->check_name == NULL) {
radlog(L_ERR, "rlm_counter: 'check-name' must be set.");
+ counter_detach(data);
+ return -1;
}
dict_addattr(data->check_name, 0, PW_TYPE_INTEGER, -1, flags);
dattr = dict_attrbyname(data->check_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: Failed to create check attribute %s",
data->counter_name);
}
dict_addattr(data->check_name, 0, PW_TYPE_INTEGER, -1, flags);
dattr = dict_attrbyname(data->check_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_counter: Failed to create check attribute %s",
data->counter_name);
return -1;
}
data->check_attr = dattr->attr;
return -1;
}
data->check_attr = dattr->attr;
if ((dval = dict_valbyname(PW_SERVICE_TYPE, data->service_type)) == NULL) {
radlog(L_ERR, "rlm_counter: Failed to find attribute number for %s",
data->service_type);
if ((dval = dict_valbyname(PW_SERVICE_TYPE, data->service_type)) == NULL) {
radlog(L_ERR, "rlm_counter: Failed to find attribute number for %s",
data->service_type);
return -1;
}
data->service_val = dval->value;
return -1;
}
data->service_val = dval->value;
*/
if (data->reset == NULL) {
radlog(L_ERR, "rlm_counter: 'reset' must be set.");
*/
if (data->reset == NULL) {
radlog(L_ERR, "rlm_counter: 'reset' must be set.");
+ counter_detach(data);
+ return -1;
}
now = time(NULL);
data->reset_time = 0;
data->last_reset = now;
}
now = time(NULL);
data->reset_time = 0;
data->last_reset = now;
- if (find_next_reset(data,now) == -1)
+ if (find_next_reset(data,now) == -1){
+ radlog(L_ERR, "rlm_counter: find_next_reset() returned -1. Exiting.");
+ counter_detach(data);
if (data->filename == NULL) {
radlog(L_ERR, "rlm_counter: 'filename' must be set.");
if (data->filename == NULL) {
radlog(L_ERR, "rlm_counter: 'filename' must be set.");
+ counter_detach(data);
+ return -1;
}
data->gdbm = gdbm_open(data->filename, sizeof(int),
GDBM_WRCREAT | GDBM_COUNTER_OPTS, 0600, NULL);
if (data->gdbm == NULL) {
radlog(L_ERR, "rlm_counter: Failed to open file %s: %s",
data->filename, strerror(errno));
}
data->gdbm = gdbm_open(data->filename, sizeof(int),
GDBM_WRCREAT | GDBM_COUNTER_OPTS, 0600, NULL);
if (data->gdbm == NULL) {
radlog(L_ERR, "rlm_counter: Failed to open file %s: %s",
data->filename, strerror(errno));
return -1;
}
if (gdbm_setopt(data->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
return -1;
}
if (gdbm_setopt(data->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
data->last_reset = now;
ret = reset_db(data);
data->last_reset = now;
ret = reset_db(data);
- if (ret != RLM_MODULE_OK)
+ if (ret != RLM_MODULE_OK){
+ radlog(L_ERR, "rlm_counter: reset_db() failed");
+ counter_detach(data);
}
else
data->reset_time = next_reset;
}
else
data->reset_time = next_reset;
}
else{
ret = add_defaults(data);
}
else{
ret = add_defaults(data);
- if (ret != RLM_MODULE_OK)
+ if (ret != RLM_MODULE_OK){
+ radlog(L_ERR, "rlm_counter: add_defaults() failed");
+ counter_detach(data);
rlm_counter_t *data = (rlm_counter_t *) instance;
paircompare_unregister(data->dict_attr, counter_cmp);
rlm_counter_t *data = (rlm_counter_t *) instance;
paircompare_unregister(data->dict_attr, counter_cmp);
- gdbm_close(data->gdbm);
+ if (data->gdbm)
+ gdbm_close(data->gdbm);
free(data->filename);
free(data->reset);
free(data->key_name);
free(data->count_attribute);
free(data->counter_name);
free(data->filename);
free(data->reset);
free(data->key_name);
free(data->count_attribute);
free(data->counter_name);
+ free(data->check_name);
+ free(data->service_type);
pthread_mutex_destroy(&data->mutex);
free(instance);
pthread_mutex_destroy(&data->mutex);
free(instance);