MXS-1461 Introduce 'not_function' rule
Using 'not_function' it is possible to match functions other than a specific set of ones. That will make it significantly easier to allow certain functions to be used with certain columns. The special handling of no arguments to `function` in conjunction with an allowing filter has been removed. The same effect can now be achieved, without special handling, using `not_function`, no arguments and a blocking filter. Implementation will follow in a subsequent commit.
This commit is contained in:
@ -161,24 +161,36 @@ matched. The symbolic comparison operators (`<`, `>`, `>=` etc.) are also
|
||||
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
|
||||
not considered functions.
|
||||
|
||||
If the rule is given no values then the rule will match any query which does not
|
||||
use functions. By combining this with the `action=allow` parameter, it is
|
||||
possible to enable whitelisting of all queries which do not use functions. One
|
||||
such use case is preventing functions from being used to circumvent masking done
|
||||
by the masking filter.
|
||||
|
||||
When the filter is in whitelist mode (`action=allow`) the function rule
|
||||
will match any query that does not use a function. This means that queries
|
||||
that do not use functions will be allowed through a function type rule.
|
||||
|
||||
##### Example
|
||||
|
||||
Deny SUM and COUNT functions:
|
||||
Match queries using the _sum_ and _count_ functions:
|
||||
|
||||
```
|
||||
rule examplerule match function sum count
|
||||
```
|
||||
|
||||
#### `not_function`
|
||||
|
||||
This rule expects a list of values after the `not_function` keyword. These values
|
||||
are interpreted as function names and if a query uses any function other than these,
|
||||
it is matched. The symbolic comparison operators (`<`, `>`, `>=` etc.) are also
|
||||
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
|
||||
not considered functions.
|
||||
|
||||
If the rule is given no values, then the rule will match a query using any function.
|
||||
|
||||
#### Example
|
||||
|
||||
Match queries using other functions but the _length_ function:
|
||||
```
|
||||
rule examplerule match not_function length
|
||||
```
|
||||
|
||||
Match queries using functions:
|
||||
```
|
||||
rule examplerule match not_function
|
||||
```
|
||||
|
||||
#### `uses_function`
|
||||
|
||||
This rule expects a list of column names after the keyword. If any of the
|
||||
@ -207,6 +219,31 @@ Deny use of the _sum_ function with _name_ or _address_ columns:
|
||||
rule examplerule match function sum columns name address
|
||||
```
|
||||
|
||||
#### `not_function` and `columns`
|
||||
|
||||
This rule combines the `not_function` and `columns` type rules to match if
|
||||
one of the listed columns is used in conjunction with functions other than
|
||||
the listed ones. The rule expects the `not_function` and `columns` keywords
|
||||
both followed by a list of values.
|
||||
|
||||
If `not_function` is not provided with a list of values, then the rule
|
||||
matches if any of the columns is used with any function.
|
||||
|
||||
##### Example
|
||||
|
||||
Match if any other function but _length_ is used with the _name_ or _address_
|
||||
columns:
|
||||
|
||||
```
|
||||
rule examplerule match not_function length columns name address
|
||||
```
|
||||
|
||||
Match if any function is used with the _ssn_column:
|
||||
|
||||
```
|
||||
rule examplerule match not_function columns ssn
|
||||
```
|
||||
|
||||
#### `regex`
|
||||
|
||||
This rule blocks all queries matching a regex enclosed in single or double
|
||||
|
@ -870,11 +870,11 @@ void define_columns_rule(void* scanner)
|
||||
*
|
||||
* @param scanner Current scanner
|
||||
*/
|
||||
void define_function_rule(void* scanner)
|
||||
void define_function_rule(void* scanner, bool inverted)
|
||||
{
|
||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||
ss_dassert(rstack);
|
||||
rstack->add(new FunctionRule(rstack->name, rstack->values));
|
||||
rstack->add(new FunctionRule(rstack->name, rstack->values, inverted));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -894,11 +894,11 @@ void define_function_usage_rule(void* scanner)
|
||||
*
|
||||
* @param scanner Current scanner
|
||||
*/
|
||||
void define_column_function_rule(void* scanner)
|
||||
void define_column_function_rule(void* scanner, bool inverted)
|
||||
{
|
||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||
ss_dassert(rstack);
|
||||
rstack->add(new ColumnFunctionRule(rstack->name, rstack->values, rstack->auxiliary_values));
|
||||
rstack->add(new ColumnFunctionRule(rstack->name, rstack->values, rstack->auxiliary_values, inverted));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,9 +43,9 @@ void define_wildcard_rule(void* scanner);
|
||||
void define_where_clause_rule(void* scanner);
|
||||
bool define_regex_rule(void* scanner, char* pattern);
|
||||
void define_columns_rule(void* scanner);
|
||||
void define_function_rule(void* scanner);
|
||||
void define_function_rule(void* scanner, bool inverted);
|
||||
void define_function_usage_rule(void* scanner);
|
||||
void define_column_function_rule(void* scanner);
|
||||
void define_column_function_rule(void* scanner, bool inverted);
|
||||
void define_limit_queries_rule(void* scanner, int max, int timeperiod, int holdoff);
|
||||
bool add_at_times_rule(void* scanner, const char* range);
|
||||
void add_on_queries_rule(void* scanner, const char* sql);
|
||||
|
@ -37,7 +37,7 @@
|
||||
%token FWTOK_RULE FWTOK_USERS FWTOK_RULES FWTOK_ANY FWTOK_ALL
|
||||
%token FWTOK_STRICT_ALL FWTOK_MATCH FWTOK_WILDCARD FWTOK_COLUMNS FWTOK_REGEX
|
||||
%token FWTOK_LIMIT_QUERIES FWTOK_WHERE_CLAUSE FWTOK_AT_TIMES FWTOK_ON_QUERIES
|
||||
%token FWTOK_FUNCTION FWTOK_USES_FUNCTION FWTOK_COMMENT FWTOK_PIPE
|
||||
%token FWTOK_FUNCTION FWTOK_USES_FUNCTION FWTOK_COMMENT FWTOK_PIPE FWTOK_NOT_FUNCTION
|
||||
|
||||
/** Terminal typed symbols */
|
||||
%token <floatval>FWTOK_FLOAT <strval>FWTOK_TIME <strval>FWTOK_BTSTR
|
||||
@ -124,9 +124,15 @@ mandatory
|
||||
{define_limit_queries_rule(scanner, $2, $3, $4);}
|
||||
| FWTOK_REGEX FWTOK_QUOTEDSTR {define_regex_rule(scanner, $2);}
|
||||
| FWTOK_COLUMNS valuelist {define_columns_rule(scanner);}
|
||||
| FWTOK_FUNCTION valuelist {define_function_rule(scanner);}
|
||||
| FWTOK_FUNCTION {define_function_rule(scanner);}
|
||||
| FWTOK_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist {define_column_function_rule(scanner);}
|
||||
| FWTOK_FUNCTION valuelist {define_function_rule(scanner, false);}
|
||||
| FWTOK_NOT_FUNCTION valuelist {define_function_rule(scanner, true);}
|
||||
| FWTOK_NOT_FUNCTION {define_function_rule(scanner, true);}
|
||||
| FWTOK_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist
|
||||
{define_column_function_rule(scanner, false);}
|
||||
| FWTOK_NOT_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist
|
||||
{define_column_function_rule(scanner, true);}
|
||||
| FWTOK_NOT_FUNCTION FWTOK_COLUMNS auxiliaryvaluelist
|
||||
{define_column_function_rule(scanner, true);}
|
||||
| FWTOK_USES_FUNCTION valuelist {define_function_usage_rule(scanner);}
|
||||
;
|
||||
|
||||
|
@ -180,12 +180,16 @@ class FunctionRule: public ValueListRule
|
||||
FunctionRule& operator=(const FunctionRule&);
|
||||
|
||||
public:
|
||||
FunctionRule(std::string name, const ValueList& values):
|
||||
ValueListRule(name, "FUNCTION", values)
|
||||
FunctionRule(std::string name, const ValueList& values, bool inverted):
|
||||
ValueListRule(name, inverted ? "NOT_FUNCTION" : "FUNCTION", values),
|
||||
m_inverted(inverted)
|
||||
{
|
||||
}
|
||||
|
||||
bool matches_query(DbfwSession* session, GWBUF* buffer, char** msg) const;
|
||||
|
||||
private:
|
||||
bool m_inverted; /*< Should the match be inverted. */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -214,9 +218,10 @@ class ColumnFunctionRule: public ValueListRule
|
||||
ColumnFunctionRule& operator=(const ColumnFunctionRule&);
|
||||
|
||||
public:
|
||||
ColumnFunctionRule(std::string name, const ValueList& values, const ValueList& columns):
|
||||
ValueListRule(name, "COLUMN_FUNCTION", values),
|
||||
m_columns(columns)
|
||||
ColumnFunctionRule(std::string name, const ValueList& values, const ValueList& columns, bool inverted):
|
||||
ValueListRule(name, inverted ? "NOT_COLUMN_FUNCTION" : "COLUMN_FUNCTION", values),
|
||||
m_columns(columns),
|
||||
m_inverted(inverted)
|
||||
{
|
||||
}
|
||||
|
||||
@ -224,6 +229,7 @@ public:
|
||||
|
||||
private:
|
||||
ValueList m_columns; /*< List of columns to match */
|
||||
bool m_inverted; /*< Should the match be inverted. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,6 +40,7 @@ CMP [=<>!]+
|
||||
deny|allow MXS_WARNING("Use of '%s' is deprecated, use 'match' instead", yytext);return FWTOK_MATCH;
|
||||
rule return FWTOK_RULE;
|
||||
function return FWTOK_FUNCTION;
|
||||
not_function return FWTOK_NOT_FUNCTION;
|
||||
uses_function return FWTOK_USES_FUNCTION;
|
||||
no_where_clause return FWTOK_WHERE_CLAUSE;
|
||||
wildcard return FWTOK_WILDCARD;
|
||||
|
Reference in New Issue
Block a user