MXS-1346: Refactor dbfwfilter user template creation
The user templates now use ValueList instead of STRLINK to store the string values and they are stored as a list of shared pointers. Minor cleanups to the user creation related grammar rules.
This commit is contained in:
@ -71,6 +71,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <tr1/memory>
|
||||||
|
|
||||||
#include <maxscale/filter.h>
|
#include <maxscale/filter.h>
|
||||||
#include <maxscale/atomic.h>
|
#include <maxscale/atomic.h>
|
||||||
@ -298,18 +299,22 @@ thread_local int thr_rule_version = 0;
|
|||||||
thread_local RULE *thr_rules = NULL;
|
thread_local RULE *thr_rules = NULL;
|
||||||
thread_local HASHTABLE *thr_users = NULL;
|
thread_local HASHTABLE *thr_users = NULL;
|
||||||
|
|
||||||
|
typedef std::list<std::string> ValueList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A temporary template structure used in the creation of actual users.
|
* A temporary template structure used in the creation of actual users.
|
||||||
* This is also used to link the user definitions with the rules.
|
* This is also used to link the user definitions with the rules.
|
||||||
* @see struct user_t
|
* @see struct user_t
|
||||||
*/
|
*/
|
||||||
typedef struct user_template
|
struct UserTemplate
|
||||||
{
|
{
|
||||||
char *name;
|
std::string name; /** Name of the user */
|
||||||
enum match_type type; /** Matching type */
|
enum match_type type; /** Matching type */
|
||||||
STRLINK *rulenames; /** names of the rules */
|
ValueList rulenames; /** Names of the rules */
|
||||||
struct user_template *next;
|
};
|
||||||
} user_template_t;
|
|
||||||
|
typedef std::tr1::shared_ptr<UserTemplate> SUserTemplate;
|
||||||
|
typedef std::list<SUserTemplate> TemplateList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A user definition
|
* A user definition
|
||||||
@ -1097,18 +1102,16 @@ char* get_regex_string(char** saved)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::list<std::string> ValueList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure used to hold rules and users that are being parsed
|
* Structure used to hold rules and users that are being parsed
|
||||||
*/
|
*/
|
||||||
struct parser_stack
|
struct parser_stack
|
||||||
{
|
{
|
||||||
RULE* rule;
|
RULE* rule;
|
||||||
STRLINK* user;
|
ValueList user;
|
||||||
STRLINK* active_rules;
|
ValueList active_rules;
|
||||||
enum match_type active_mode;
|
enum match_type active_mode;
|
||||||
user_template_t* templates;
|
TemplateList templates;
|
||||||
ValueList values;
|
ValueList values;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
@ -1259,18 +1262,11 @@ static void rule_free_all(RULE* rule)
|
|||||||
* @param scanner Current scanner
|
* @param scanner Current scanner
|
||||||
* @param name Name of the user
|
* @param name Name of the user
|
||||||
*/
|
*/
|
||||||
bool add_active_user(void* scanner, const char* name)
|
void add_active_user(void* scanner, const char* name)
|
||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
ss_dassert(rstack);
|
ss_dassert(rstack);
|
||||||
STRLINK *tmp = strlink_push(rstack->user, name);
|
rstack->user.push_back(name);
|
||||||
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
rstack->user = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1278,18 +1274,11 @@ bool add_active_user(void* scanner, const char* name)
|
|||||||
* @param scanner Current scanner
|
* @param scanner Current scanner
|
||||||
* @param name Name of the rule
|
* @param name Name of the rule
|
||||||
*/
|
*/
|
||||||
bool add_active_rule(void* scanner, const char* name)
|
void add_active_rule(void* scanner, const char* name)
|
||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
ss_dassert(rstack);
|
ss_dassert(rstack);
|
||||||
STRLINK *tmp = strlink_push(rstack->active_rules, name);
|
rstack->active_rules.push_back(name);
|
||||||
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
rstack->active_rules = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1333,57 +1322,22 @@ bool create_user_templates(void* scanner)
|
|||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
ss_dassert(rstack);
|
ss_dassert(rstack);
|
||||||
user_template_t* templates = NULL;
|
|
||||||
STRLINK* user = rstack->user;
|
|
||||||
|
|
||||||
while (user)
|
for (ValueList::const_iterator it = rstack->user.begin(); it != rstack->user.end(); it++)
|
||||||
{
|
{
|
||||||
user_template_t* newtemp = (user_template_t*)MXS_MALLOC(sizeof(user_template_t));
|
SUserTemplate newtemp = SUserTemplate(new UserTemplate);
|
||||||
STRLINK* tmp;
|
newtemp->name = *it;
|
||||||
if (newtemp && (newtemp->name = MXS_STRDUP(user->value)) &&
|
newtemp->rulenames = rstack->active_rules;
|
||||||
(newtemp->rulenames = strlink_reverse_clone(rstack->active_rules)))
|
newtemp->type = rstack->active_mode;
|
||||||
{
|
rstack->templates.push_back(newtemp);
|
||||||
newtemp->type = rstack->active_mode;
|
|
||||||
newtemp->next = templates;
|
|
||||||
templates = newtemp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (newtemp)
|
|
||||||
{
|
|
||||||
MXS_FREE(newtemp->name);
|
|
||||||
MXS_FREE(newtemp);
|
|
||||||
}
|
|
||||||
MXS_FREE(templates->name);
|
|
||||||
strlink_free(templates->rulenames);
|
|
||||||
MXS_FREE(templates);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
user = user->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templates->next = rstack->templates;
|
rstack->user.clear();
|
||||||
rstack->templates = templates;
|
rstack->active_rules.clear();
|
||||||
|
|
||||||
strlink_free(rstack->user);
|
|
||||||
strlink_free(rstack->active_rules);
|
|
||||||
rstack->user = NULL;
|
|
||||||
rstack->active_rules = NULL;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_user_templates(user_template_t *templates)
|
|
||||||
{
|
|
||||||
while (templates)
|
|
||||||
{
|
|
||||||
user_template_t *tmp = templates;
|
|
||||||
templates = templates->next;
|
|
||||||
strlink_free(tmp->rulenames);
|
|
||||||
MXS_FREE(tmp->name);
|
|
||||||
MXS_FREE(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_matching_mode(void* scanner, enum match_type mode)
|
void set_matching_mode(void* scanner, enum match_type mode)
|
||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
@ -1552,24 +1506,25 @@ bool define_regex_rule(void* scanner, char* pattern)
|
|||||||
* @param rules List of all rules
|
* @param rules List of all rules
|
||||||
* @return True on success, false on error.
|
* @return True on success, false on error.
|
||||||
*/
|
*/
|
||||||
static bool process_user_templates(HASHTABLE *users, user_template_t *templates,
|
static bool process_user_templates(HASHTABLE *users, const TemplateList& templates,
|
||||||
RULE* rules)
|
RULE* rules)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
if (templates == NULL)
|
if (templates.size() == 0)
|
||||||
{
|
{
|
||||||
MXS_ERROR("No user definitions found in the rule file.");
|
MXS_ERROR("No user definitions found in the rule file.");
|
||||||
rval = false;
|
rval = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (templates)
|
for (TemplateList::const_iterator it = templates.begin(); it != templates.end(); it++)
|
||||||
{
|
{
|
||||||
DBFW_USER *user = (DBFW_USER*)hashtable_fetch(users, templates->name);
|
const SUserTemplate& ut = *it;
|
||||||
|
DBFW_USER *user = (DBFW_USER*)hashtable_fetch(users, (void*)ut->name.c_str());
|
||||||
|
|
||||||
if (user == NULL)
|
if (user == NULL)
|
||||||
{
|
{
|
||||||
if ((user = (DBFW_USER*)MXS_MALLOC(sizeof(DBFW_USER))) && (user->name = MXS_STRDUP(templates->name)))
|
if ((user = (DBFW_USER*)MXS_MALLOC(sizeof(DBFW_USER))) && (user->name = MXS_STRDUP(ut->name.c_str())))
|
||||||
{
|
{
|
||||||
user->rules_and = NULL;
|
user->rules_and = NULL;
|
||||||
user->rules_or = NULL;
|
user->rules_or = NULL;
|
||||||
@ -1587,13 +1542,21 @@ static bool process_user_templates(HASHTABLE *users, user_template_t *templates,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RULE_BOOK *foundrules = NULL;
|
RULE_BOOK *foundrules = NULL;
|
||||||
RULE *rule;
|
|
||||||
STRLINK *names = templates->rulenames;
|
|
||||||
|
|
||||||
while (names && (rule = find_rule_by_name(rules, names->value)))
|
for (ValueList::const_iterator r_it = ut->rulenames.begin();
|
||||||
|
r_it != ut->rulenames.end(); r_it++)
|
||||||
{
|
{
|
||||||
foundrules = rulebook_push(foundrules, rule);
|
RULE* rule = find_rule_by_name(rules, r_it->c_str());
|
||||||
names = names->next;
|
|
||||||
|
if (rule)
|
||||||
|
{
|
||||||
|
foundrules = rulebook_push(foundrules, rule);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR("Could not find definition for rule '%s'.", r_it->c_str());
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundrules)
|
if (foundrules)
|
||||||
@ -1605,7 +1568,7 @@ static bool process_user_templates(HASHTABLE *users, user_template_t *templates,
|
|||||||
tail = tail->next;
|
tail = tail->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (templates->type)
|
switch (ut->type)
|
||||||
{
|
{
|
||||||
case FWTOK_MATCH_ANY:
|
case FWTOK_MATCH_ANY:
|
||||||
tail->next = user->rules_or;
|
tail->next = user->rules_or;
|
||||||
@ -1623,13 +1586,6 @@ static bool process_user_templates(HASHTABLE *users, user_template_t *templates,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_ERROR("Could not find definition for rule '%s'.", names->value);
|
|
||||||
rval = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
templates = templates->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
@ -1652,9 +1608,6 @@ static bool process_rule_file(const char* filename, RULE** rules, HASHTABLE **us
|
|||||||
struct parser_stack pstack;
|
struct parser_stack pstack;
|
||||||
|
|
||||||
pstack.rule = NULL;
|
pstack.rule = NULL;
|
||||||
pstack.user = NULL;
|
|
||||||
pstack.active_rules = NULL;
|
|
||||||
pstack.templates = NULL;
|
|
||||||
|
|
||||||
dbfw_yylex_init(&scanner);
|
dbfw_yylex_init(&scanner);
|
||||||
YY_BUFFER_STATE buf = dbfw_yy_create_buffer(file, YY_BUF_SIZE, scanner);
|
YY_BUFFER_STATE buf = dbfw_yy_create_buffer(file, YY_BUF_SIZE, scanner);
|
||||||
@ -1681,10 +1634,6 @@ static bool process_rule_file(const char* filename, RULE** rules, HASHTABLE **us
|
|||||||
hashtable_free(new_users);
|
hashtable_free(new_users);
|
||||||
MXS_ERROR("Failed to process rule file '%s'.", filename);
|
MXS_ERROR("Failed to process rule file '%s'.", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_user_templates(pstack.templates);
|
|
||||||
strlink_free(pstack.active_rules);
|
|
||||||
strlink_free(pstack.user);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -49,8 +49,8 @@ bool add_at_times_rule(void* scanner, const char* range);
|
|||||||
void add_on_queries_rule(void* scanner, const char* sql);
|
void add_on_queries_rule(void* scanner, const char* sql);
|
||||||
|
|
||||||
/** User creation functions */
|
/** User creation functions */
|
||||||
bool add_active_user(void* scanner, const char* name);
|
void add_active_user(void* scanner, const char* name);
|
||||||
bool add_active_rule(void* scanner, const char* name);
|
void add_active_rule(void* scanner, const char* name);
|
||||||
void set_matching_mode(void* scanner, enum match_type mode);
|
void set_matching_mode(void* scanner, enum match_type mode);
|
||||||
bool create_user_templates(void* scanner);
|
bool create_user_templates(void* scanner);
|
||||||
|
|
||||||
|
@ -93,14 +93,22 @@ user
|
|||||||
{if (!create_user_templates(scanner)){YYERROR;}}
|
{if (!create_user_templates(scanner)){YYERROR;}}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
uservalue
|
||||||
|
: FWTOK_USER {add_active_user(scanner, $1);}
|
||||||
|
;
|
||||||
|
|
||||||
userlist
|
userlist
|
||||||
: FWTOK_USER {if (!add_active_user(scanner, $1)){YYERROR;}}
|
: uservalue
|
||||||
| userlist FWTOK_USER {if (!add_active_user(scanner, $2)){YYERROR;}}
|
| userlist uservalue
|
||||||
|
;
|
||||||
|
|
||||||
|
namevalue
|
||||||
|
: rulename {add_active_rule(scanner, $1);}
|
||||||
;
|
;
|
||||||
|
|
||||||
namelist
|
namelist
|
||||||
: rulename {if (!add_active_rule(scanner, $1)){YYERROR;}}
|
: namevalue
|
||||||
| namelist rulename {if (!add_active_rule(scanner, $2)){YYERROR;}}
|
| namelist namevalue
|
||||||
;
|
;
|
||||||
|
|
||||||
cond
|
cond
|
||||||
|
Reference in New Issue
Block a user