MXS-1583 Treat independent 'users' line in OR-fashion
If there are several 'users' lines in a rule file, for a particular user, the rules each matching line will be checked independently until a rule match is found. That is, the rules of each 'users' line are treated in an OR-fashion with respect to each other.
This commit is contained in:
@ -355,6 +355,12 @@ After the matching part comes the rules keyword after which a list of rule names
|
|||||||
is expected. This allows reusing of the rules and enables varying levels of
|
is expected. This allows reusing of the rules and enables varying levels of
|
||||||
query restriction.
|
query restriction.
|
||||||
|
|
||||||
|
If a particular _NAME_ appears on several `users` lines, then when an
|
||||||
|
actual user matches that name, the rules of each line are checked
|
||||||
|
independently until there is a match for the statement in question. That
|
||||||
|
is, the rules of each `users` line are treated in an _OR_ fashion with
|
||||||
|
respect to each other.
|
||||||
|
|
||||||
## Module commands
|
## Module commands
|
||||||
|
|
||||||
Read [Module Commands](../Reference/Module-Commands.md) documentation for
|
Read [Module Commands](../Reference/Module-Commands.md) documentation for
|
||||||
|
|||||||
@ -1029,7 +1029,7 @@ static bool process_user_templates(UserMap& users, const TemplateList& templates
|
|||||||
|
|
||||||
if (newrules.size() > 0)
|
if (newrules.size() > 0)
|
||||||
{
|
{
|
||||||
user->append_rules(ut->type, newrules);
|
user->add_rules(ut->type, newrules);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,20 +31,20 @@ const char* User::name() const
|
|||||||
return m_name.c_str();
|
return m_name.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void User::append_rules(match_type mode, const RuleList& rules)
|
void User::add_rules(match_type mode, const RuleList& rules)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case FWTOK_MATCH_ANY:
|
case FWTOK_MATCH_ANY:
|
||||||
rules_or.insert(rules_or.end(), rules.begin(), rules.end());
|
rules_or_vector.push_back(rules);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FWTOK_MATCH_ALL:
|
case FWTOK_MATCH_ALL:
|
||||||
rules_and.insert(rules_and.end(), rules.begin(), rules.end());
|
rules_and_vector.push_back(rules);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FWTOK_MATCH_STRICT_ALL:
|
case FWTOK_MATCH_STRICT_ALL:
|
||||||
rules_strict_and.insert(rules_strict_and.end(), rules.begin(), rules.end());
|
rules_strict_and_vector.push_back(rules);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -73,28 +73,39 @@ bool User::match_any(Dbfw* my_instance, DbfwSession* my_session,
|
|||||||
|
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
|
|
||||||
if (rules_or.size() > 0 && should_match(queue))
|
for (RuleListVector::iterator i = rules_or_vector.begin(); i != rules_or_vector.end(); ++i)
|
||||||
{
|
{
|
||||||
char *fullquery = modutil_get_SQL(queue);
|
RuleList& rules_or = *i;
|
||||||
|
|
||||||
if (fullquery)
|
if (rules_or.size() > 0 && should_match(queue))
|
||||||
{
|
{
|
||||||
for (RuleList::iterator it = rules_or.begin(); it != rules_or.end(); it++)
|
char *fullquery = modutil_get_SQL(queue);
|
||||||
|
|
||||||
|
if (fullquery)
|
||||||
{
|
{
|
||||||
if (rule_is_active(*it))
|
for (RuleList::iterator j = rules_or.begin(); j != rules_or.end(); j++)
|
||||||
{
|
{
|
||||||
if (rule_matches(my_instance, my_session, queue, *it, fullquery))
|
if (rule_is_active(*j))
|
||||||
{
|
{
|
||||||
*rulename = MXS_STRDUP_A((*it)->name().c_str());
|
if (rule_matches(my_instance, my_session, queue, *j, fullquery))
|
||||||
rval = true;
|
{
|
||||||
break;
|
*rulename = MXS_STRDUP_A((*j)->name().c_str());
|
||||||
|
rval = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MXS_FREE(fullquery);
|
MXS_FREE(fullquery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rval)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,44 +127,54 @@ bool User::do_match(Dbfw* my_instance, DbfwSession* my_session,
|
|||||||
bool rval = false;
|
bool rval = false;
|
||||||
bool have_active_rule = false;
|
bool have_active_rule = false;
|
||||||
std::string matching_rules;
|
std::string matching_rules;
|
||||||
RuleList& rules = mode == User::ALL ? rules_and : rules_strict_and;
|
RuleListVector& rules_vector = (mode == User::ALL ? rules_and_vector : rules_strict_and_vector);
|
||||||
|
|
||||||
if (rules.size() > 0 && should_match(queue))
|
for (RuleListVector::iterator i = rules_vector.begin(); i != rules_vector.end(); ++i)
|
||||||
{
|
{
|
||||||
char *fullquery = modutil_get_SQL(queue);
|
RuleList& rules = *i;
|
||||||
|
|
||||||
if (fullquery)
|
if (rules.size() > 0 && should_match(queue))
|
||||||
{
|
{
|
||||||
rval = true;
|
char *fullquery = modutil_get_SQL(queue);
|
||||||
for (RuleList::iterator it = rules.begin(); it != rules.end(); it++)
|
|
||||||
|
if (fullquery)
|
||||||
{
|
{
|
||||||
if (rule_is_active(*it))
|
rval = true;
|
||||||
|
for (RuleList::iterator j = rules.begin(); j != rules.end(); j++)
|
||||||
{
|
{
|
||||||
have_active_rule = true;
|
if (rule_is_active(*j))
|
||||||
|
|
||||||
if (rule_matches(my_instance, my_session, queue, *it, fullquery))
|
|
||||||
{
|
{
|
||||||
matching_rules += (*it)->name();
|
have_active_rule = true;
|
||||||
matching_rules += " ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rval = false;
|
|
||||||
|
|
||||||
if (mode == User::STRICT)
|
if (rule_matches(my_instance, my_session, queue, *j, fullquery))
|
||||||
{
|
{
|
||||||
break;
|
matching_rules += (*j)->name();
|
||||||
|
matching_rules += " ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rval = false;
|
||||||
|
|
||||||
|
if (mode == User::STRICT)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!have_active_rule)
|
if (!have_active_rule)
|
||||||
{
|
{
|
||||||
/** No active rules */
|
/** No active rules */
|
||||||
rval = false;
|
rval = false;
|
||||||
|
}
|
||||||
|
MXS_FREE(fullquery);
|
||||||
}
|
}
|
||||||
MXS_FREE(fullquery);
|
}
|
||||||
|
|
||||||
|
if (rval)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,12 +57,12 @@ public:
|
|||||||
const char* name() const;
|
const char* name() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append new rules to existing rules
|
* Add new rules to existing rules
|
||||||
*
|
*
|
||||||
* @param mode Matching mode for the rule
|
* @param mode Matching mode for the rule
|
||||||
* @param rules Rules to append
|
* @param rules Rules to append
|
||||||
*/
|
*/
|
||||||
void append_rules(match_type mode, const RuleList& rules);
|
void add_rules(match_type mode, const RuleList& rules);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a query matches some rule
|
* Check if a query matches some rule
|
||||||
@ -84,11 +84,13 @@ private:
|
|||||||
STRICT
|
STRICT
|
||||||
};
|
};
|
||||||
|
|
||||||
RuleList rules_or; /*< If any of these rules match the action is triggered */
|
typedef std::vector<RuleList> RuleListVector;
|
||||||
RuleList rules_and; /*< All of these rules must match for the action to trigger */
|
|
||||||
RuleList rules_strict_and; /*< rules that skip the rest of the rules if one of them
|
RuleListVector rules_or_vector; /*< If any of these rules match the action is triggered */
|
||||||
* fails. This is only for rules paired with 'match strict_all'. */
|
RuleListVector rules_and_vector; /*< All of these rules must match for the action to trigger */
|
||||||
std::string m_name; /*< Name of the user */
|
RuleListVector rules_strict_and_vector;/*< rules that skip the rest of the rules if one of them
|
||||||
|
* fails. This is only for rules paired with 'match strict_all'. */
|
||||||
|
std::string m_name; /*< Name of the user */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions for matching rules
|
* Functions for matching rules
|
||||||
|
|||||||
Reference in New Issue
Block a user