/* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections * to external databases, read configuration files, set up * dictionary entries, etc. * * If configuration information is given in the config section * that must be referenced in later calls, store a handle to it * in *instance otherwise put a null pointer there. */ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance) { rlm_sqlcounter_t *data; DICT_ATTR *dattr; ATTR_FLAGS flags; time_t now; char buffer[MAX_STRING_LEN]; /* * Set up a storage area for instance data */ data = rad_malloc(sizeof(*data)); if (!data) { return -1; } memset(data, 0, sizeof(*data)); /* * If the configuration parameters can't be parsed, then * fail. */ if (cf_section_parse(conf, data, module_config) < 0) { free(data); return -1; } /* * No query, die. */ if (data->query == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'query' must be set."); return -1; } /* * Safe characters list for sql queries. Everything else is * replaced rwith their mime-encoded equivalents. */ allowed_chars = data->allowed_chars; /* * Discover the attribute number of the key. */ if (data->key_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'key' must be set."); return -1; } sql_escape_func(buffer, sizeof(buffer), data->key_name); if (strcmp(buffer, data->key_name) != 0) { radlog(L_ERR, "rlm_sqlcounter: The value for option 'key' is too long or contains unsafe characters."); return -1; } dattr = dict_attrbyname(data->key_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: No such attribute %s", data->key_name); return -1; } data->key_attr = dattr->attr; /* * Check the "sqlmod-inst" option. */ if (data->sqlmod_inst == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'sqlmod-inst' must be set."); return -1; } sql_escape_func(buffer, sizeof(buffer), data->sqlmod_inst); if (strcmp(buffer, data->sqlmod_inst) != 0) { radlog(L_ERR, "rlm_sqlcounter: The value for option 'sqlmod-inst' is too long or contains unsafe characters."); return -1; } /* * Create a new attribute for the counter. */ if (data->counter_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'counter-name' must be set."); return -1; } memset(&flags, 0, sizeof(flags)); dict_addattr(data->counter_name, 0, PW_TYPE_INTEGER, -1, flags); dattr = dict_attrbyname(data->counter_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: Failed to create counter attribute %s", data->counter_name); return -1; } data->dict_attr = dattr->attr; DEBUG2("rlm_sqlcounter: Counter attribute %s is number %d", data->counter_name, data->dict_attr); /* * Create a new attribute for the check item. */ if (data->check_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'check-name' must be set."); 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_sqlcounter: Failed to create check attribute %s", data->counter_name); return -1; } DEBUG2("rlm_sqlcounter: Check attribute %s is number %d", data->check_name, dattr->attr); /* * Discover the end of the current time period. */ if (data->reset == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'reset' must be set."); return -1; } now = time(NULL); data->reset_time = 0; if (find_next_reset(data,now) == -1) return -1; /* * Discover the beginning of the current time period. */ data->last_reset = 0; if (find_prev_reset(data,now) == -1) return -1; /* * Register the counter comparison operation. */ paircompare_register(data->dict_attr, 0, sqlcounter_cmp, data); *instance = data; return 0; }
/* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections * to external databases, read configuration files, set up * dictionary entries, etc. * * If configuration information is given in the config section * that must be referenced in later calls, store a handle to it * in *instance otherwise put a null pointer there. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_sqlcounter_t *inst = instance; DICT_ATTR const *da; ATTR_FLAGS flags; time_t now; rad_assert(inst->query && *inst->query); da = dict_attrbyname(inst->key_name); if (!da) { cf_log_err_cs(conf, "Invalid attribute '%s'", inst->key_name); return -1; } inst->key_attr = da; da = dict_attrbyname(inst->reply_name); if (!da) { cf_log_err_cs(conf, "Invalid attribute '%s'", inst->reply_name); return -1; } inst->reply_attr = da; /* * Create a new attribute for the counter. */ rad_assert(inst->counter_name && *inst->counter_name); memset(&flags, 0, sizeof(flags)); dict_addattr(inst->counter_name, -1, 0, PW_TYPE_INTEGER, flags); da = dict_attrbyname(inst->counter_name); if (!da) { cf_log_err_cs(conf, "Failed to create counter attribute %s", inst->counter_name); return -1; } inst->dict_attr = da; /* * Create a new attribute for the check item. */ rad_assert(inst->limit_name && *inst->limit_name); dict_addattr(inst->limit_name, -1, 0, PW_TYPE_INTEGER, flags); da = dict_attrbyname(inst->limit_name); if (!da) { cf_log_err_cs(conf, "Failed to create check attribute %s", inst->limit_name); return -1; } now = time(NULL); inst->reset_time = 0; if (find_next_reset(inst,now) == -1) { cf_log_err_cs(conf, "Invalid reset '%s'", inst->reset); return -1; } /* * Discover the beginning of the current time period. */ inst->last_reset = 0; if (find_prev_reset(inst, now) < 0) { cf_log_err_cs(conf, "Invalid reset '%s'", inst->reset); return -1; } /* * Register the counter comparison operation. */ paircompare_register(inst->dict_attr, NULL, true, sqlcounter_cmp, inst); return 0; }
/* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections * to external databases, read configuration files, set up * dictionary entries, etc. * * If configuration information is given in the config section * that must be referenced in later calls, store a handle to it * in *instance otherwise put a null pointer there. */ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance) { rlm_sqlcounter_t *data; DICT_ATTR *dattr; ATTR_FLAGS flags; time_t now; /* * Set up a storage area for instance data */ data = rad_malloc(sizeof(*data)); if (!data) { radlog(L_ERR, "rlm_sqlcounter: Not enough memory."); return -1; } memset(data, 0, sizeof(*data)); /* * If the configuration parameters can't be parsed, then * fail. */ if (cf_section_parse(conf, data, module_config) < 0) { radlog(L_ERR, "rlm_sqlcounter: Unable to parse parameters."); sqlcounter_detach(data); return -1; } /* * No query, die. */ if (data->query == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'query' must be set."); sqlcounter_detach(data); return -1; } /* * Discover the attribute number of the key. */ if (data->key_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'key' must be set."); sqlcounter_detach(data); return -1; } dattr = dict_attrbyname(data->key_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: No such attribute %s", data->key_name); sqlcounter_detach(data); return -1; } data->key_attr = dattr; dattr = dict_attrbyname(data->reply_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: No such attribute %s", data->reply_name); sqlcounter_detach(data); return -1; } data->reply_attr = dattr; DEBUG2("rlm_sqlcounter: Reply attribute %s is number %d", data->reply_name, dattr->attr); /* * Check the "sqlmod-inst" option. */ if (data->sqlmod_inst == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'sqlmod-inst' must be set."); sqlcounter_detach(data); return -1; } /* * Create a new attribute for the counter. */ if (data->counter_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'counter-name' must be set."); sqlcounter_detach(data); return -1; } memset(&flags, 0, sizeof(flags)); dict_addattr(data->counter_name, -1, 0, PW_TYPE_INTEGER, flags); dattr = dict_attrbyname(data->counter_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: Failed to create counter attribute %s", data->counter_name); sqlcounter_detach(data); return -1; } if (dattr->vendor != 0) { radlog(L_ERR, "Counter attribute must not be a VSA"); sqlcounter_detach(data); return -1; } data->dict_attr = dattr; /* * Create a new attribute for the check item. */ if (data->check_name == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'check-name' must be set."); sqlcounter_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_sqlcounter: Failed to create check attribute %s", data->check_name); sqlcounter_detach(data); return -1; } DEBUG2("rlm_sqlcounter: Check attribute %s is number %d", data->check_name, dattr->attr); /* * Discover the end of the current time period. */ if (data->reset == NULL) { radlog(L_ERR, "rlm_sqlcounter: 'reset' must be set."); sqlcounter_detach(data); return -1; } now = time(NULL); data->reset_time = 0; if (find_next_reset(data,now) == -1) { radlog(L_ERR, "rlm_sqlcounter: Failed to find the next reset time."); sqlcounter_detach(data); return -1; } /* * Discover the beginning of the current time period. */ data->last_reset = 0; if (find_prev_reset(data,now) == -1) { radlog(L_ERR, "rlm_sqlcounter: Failed to find the previous reset time."); sqlcounter_detach(data); return -1; } /* * Register the counter comparison operation. */ paircompare_register(data->dict_attr->attr, 0, sqlcounter_cmp, data); *instance = data; return 0; }
/* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections * to external databases, read configuration files, set up * dictionary entries, etc. * * If configuration information is given in the config section * that must be referenced in later calls, store a handle to it * in *instance otherwise put a null pointer there. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_sqlcounter_t *inst = instance; DICT_ATTR const *dattr; ATTR_FLAGS flags; time_t now; rad_assert(inst->query && *inst->query); dattr = dict_attrbyname(inst->key_name); rad_assert(dattr != NULL); if (dattr->vendor != 0) { cf_log_err_cs(conf, "Configuration item 'key' cannot be a VSA"); return -1; } inst->key_attr = dattr; dattr = dict_attrbyname(inst->reply_name); rad_assert(dattr != NULL); if (dattr->vendor != 0) { cf_log_err_cs(conf, "Configuration item 'reply_name' cannot be a VSA"); return -1; } inst->reply_attr = dattr; DEBUG2("rlm_sqlcounter: Reply attribute %s is number %d", inst->reply_name, dattr->attr); /* * Create a new attribute for the counter. */ rad_assert(inst->counter_name && *inst->counter_name); memset(&flags, 0, sizeof(flags)); dict_addattr(inst->counter_name, -1, 0, PW_TYPE_INTEGER, flags); dattr = dict_attrbyname(inst->counter_name); if (!dattr) { cf_log_err_cs(conf, "Failed to create counter attribute %s", inst->counter_name); return -1; } if (dattr->vendor != 0) { cf_log_err_cs(conf, "Counter attribute must not be a VSA"); return -1; } inst->dict_attr = dattr; /* * Create a new attribute for the check item. */ rad_assert(inst->check_name && *inst->check_name); dict_addattr(inst->check_name, 0, PW_TYPE_INTEGER, -1, flags); dattr = dict_attrbyname(inst->check_name); if (!dattr) { cf_log_err_cs(conf, "Failed to create check attribute %s", inst->check_name); return -1; } DEBUG2("rlm_sqlcounter: Check attribute %s is number %d", inst->check_name, dattr->attr); now = time(NULL); inst->reset_time = 0; if (find_next_reset(inst,now) == -1) { cf_log_err_cs(conf, "Invalid reset '%s'", inst->reset); return -1; } /* * Discover the beginning of the current time period. */ inst->last_reset = 0; if (find_prev_reset(inst, now) < 0) { cf_log_err_cs(conf, "Invalid reset '%s'", inst->reset); return -1; } /* * Register the counter comparison operation. */ paircompare_register(inst->dict_attr, NULL, true, sqlcounter_cmp, inst); return 0; }