Blame apache2/re.h

Packit Service 384592
/*
Packit Service 384592
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
Packit Service 384592
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
Packit Service 384592
*
Packit Service 384592
* You may not use this file except in compliance with
Packit Service 384592
* the License.  You may obtain a copy of the License at
Packit Service 384592
*
Packit Service 384592
*     http://www.apache.org/licenses/LICENSE-2.0
Packit Service 384592
*
Packit Service 384592
* If any of the files related to licensing are missing or if you have any
Packit Service 384592
* other questions related to licensing please contact Trustwave Holdings, Inc.
Packit Service 384592
* directly using the email address security@modsecurity.org.
Packit Service 384592
*/
Packit Service 384592
Packit Service 384592
#ifndef _MSC_RE_H_
Packit Service 384592
#define _MSC_RE_H_
Packit Service 384592
Packit Service 384592
#define ABSOLUTE_VALUE 0
Packit Service 384592
#define POSITIVE_VALUE 1
Packit Service 384592
#define NEGATIVE_VALUE 2
Packit Service 384592
Packit Service 384592
typedef struct msre_engine msre_engine;
Packit Service 384592
typedef struct msre_ruleset msre_ruleset;
Packit Service 384592
typedef struct msre_ruleset_internal msre_ruleset_internal;
Packit Service 384592
typedef struct msre_rule msre_rule;
Packit Service 384592
typedef struct msre_var_metadata msre_var_metadata;
Packit Service 384592
typedef struct msre_var msre_var;
Packit Service 384592
typedef struct msre_op_metadata msre_op_metadata;
Packit Service 384592
typedef struct msre_tfn_metadata msre_tfn_metadata;
Packit Service 384592
typedef struct msre_actionset msre_actionset;
Packit Service 384592
typedef struct msre_action_metadata msre_action_metadata;
Packit Service 384592
typedef struct msre_action msre_action;
Packit Service 384592
typedef struct msre_reqbody_processor_metadata msre_reqbody_processor_metadata;
Packit Service 384592
typedef struct msre_cache_rec msre_cache_rec;
Packit Service 384592
Packit Service 384592
#include "apr_general.h"
Packit Service 384592
#include "apr_tables.h"
Packit Service 384592
#include "modsecurity.h"
Packit Service 384592
#include "msc_pcre.h"
Packit Service 384592
#include "msc_tree.h"
Packit Service 384592
#include "persist_dbm.h"
Packit Service 384592
#include "apache2.h"
Packit Service 384592
#include "http_config.h"
Packit Service 384592
Packit Service 384592
#if defined(WITH_LUA)
Packit Service 384592
#include "msc_lua.h"
Packit Service 384592
#endif
Packit Service 384592
Packit Service 384592
/* Actions, variables, functions and operator functions */
Packit Service 384592
char DSOLOCAL *update_rule_target_ex(modsec_rec *msr, msre_ruleset *ruleset, msre_rule *rule, const char *p2,
Packit Service 384592
        const char *p3);
Packit Service 384592
Packit Service 384592
int DSOLOCAL msre_ruleset_rule_matches_exception(msre_rule *rule, rule_exception *re);
Packit Service 384592
Packit Service 384592
char DSOLOCAL *msre_ruleset_rule_update_target_matching_exception(modsec_rec *msr, msre_ruleset *ruleset, rule_exception *re,
Packit Service 384592
    const char *p2, const char *p3);
Packit Service 384592
Packit Service 384592
char DSOLOCAL *msre_ruleset_phase_rule_update_target_matching_exception(modsec_rec *msr, msre_ruleset *ruleset, rule_exception *re,
Packit Service 384592
     apr_array_header_t *phase_arr, const char *p2, const char *p3);
Packit Service 384592
Packit Service 384592
apr_status_t DSOLOCAL collection_original_setvar(modsec_rec *msr, const char *col_name, const msc_string *orig_var);
Packit Service 384592
Packit Service 384592
int DSOLOCAL expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t *mptmp);
Packit Service 384592
Packit Service 384592
msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
Packit Service 384592
Packit Service 384592
msre_var DSOLOCAL *msre_create_var_ex(apr_pool_t *pool, msre_engine *engine, const char *name, const char *param,
Packit Service 384592
    modsec_rec *msr, char **error_msg);
Packit Service 384592
Packit Service 384592
int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
Packit Service 384592
    char **error_msg);
Packit Service 384592
Packit Service 384592
int DSOLOCAL rule_id_in_range(int ruleid, const char *range);
Packit Service 384592
Packit Service 384592
msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
Packit Service 384592
    msre_rule *rule, apr_pool_t *mptmp);
Packit Service 384592
Packit Service 384592
#if defined(WITH_LUA)
Packit Service 384592
apr_table_t DSOLOCAL *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
Packit Service 384592
    msre_rule *rule, apr_pool_t *mptmp);
Packit Service 384592
#endif
Packit Service 384592
Packit Service 384592
/* Structures with the corresponding functions */
Packit Service 384592
Packit Service 384592
struct msre_engine {
Packit Service 384592
    apr_pool_t              *mp;
Packit Service 384592
    apr_table_t             *variables;
Packit Service 384592
    apr_table_t             *operators;
Packit Service 384592
    apr_table_t             *actions;
Packit Service 384592
    apr_table_t             *tfns;
Packit Service 384592
    apr_table_t             *reqbody_processors;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
msre_engine DSOLOCAL *msre_engine_create(apr_pool_t *parent_pool);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_destroy(msre_engine *engine);
Packit Service 384592
Packit Service 384592
msre_op_metadata DSOLOCAL *msre_engine_op_resolve(msre_engine *engine, const char *name);
Packit Service 384592
Packit Service 384592
struct msre_ruleset {
Packit Service 384592
    apr_pool_t              *mp;
Packit Service 384592
    msre_engine             *engine;
Packit Service 384592
Packit Service 384592
    apr_array_header_t      *phase_request_headers;
Packit Service 384592
    apr_array_header_t      *phase_request_body;
Packit Service 384592
    apr_array_header_t      *phase_response_headers;
Packit Service 384592
    apr_array_header_t      *phase_response_body;
Packit Service 384592
    apr_array_header_t      *phase_logging;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
apr_status_t DSOLOCAL msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr);
Packit Service 384592
Packit Service 384592
apr_status_t DSOLOCAL msre_ruleset_process_phase_internal(msre_ruleset *ruleset, modsec_rec *msr);
Packit Service 384592
Packit Service 384592
msre_ruleset DSOLOCAL *msre_ruleset_create(msre_engine *engine, apr_pool_t *mp);
Packit Service 384592
Packit Service 384592
int DSOLOCAL msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase);
Packit Service 384592
Packit Service 384592
msre_rule DSOLOCAL *msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id, int offset);
Packit Service 384592
Packit Service 384592
int DSOLOCAL msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re);
Packit Service 384592
Packit Service 384592
/*
Packit Service 384592
int DSOLOCAL msre_ruleset_phase_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re,
Packit Service 384592
    apr_array_header_t *phase_arr);
Packit Service 384592
*/
Packit Service 384592
Packit Service 384592
#define RULE_NO_MATCH           0
Packit Service 384592
#define RULE_MATCH              1
Packit Service 384592
Packit Service 384592
#define RULE_PH_NONE            0  /* Not a placeholder */
Packit Service 384592
#define RULE_PH_SKIPAFTER       1  /* Implicit placeholder for skipAfter */
Packit Service 384592
#define RULE_PH_MARKER          2  /* Explicit placeholder for SecMarker */
Packit Service 384592
Packit Service 384592
#define RULE_TYPE_NORMAL        0  /* SecRule */
Packit Service 384592
#define RULE_TYPE_ACTION        1  /* SecAction */
Packit Service 384592
#define RULE_TYPE_MARKER        2  /* SecMarker */
Packit Service 384592
#if defined(WITH_LUA)
Packit Service 384592
#define RULE_TYPE_LUA           3  /* SecRuleScript */
Packit Service 384592
#endif
Packit Service 384592
Packit Service 384592
struct msre_rule {
Packit Service 384592
    apr_array_header_t      *targets;
Packit Service 384592
    const char              *op_name;
Packit Service 384592
    const char              *op_param;
Packit Service 384592
    void                    *op_param_data;
Packit Service 384592
    msre_op_metadata        *op_metadata;
Packit Service 384592
    unsigned int             op_negated;
Packit Service 384592
    msre_actionset          *actionset;
Packit Service 384592
    const char              *p1;
Packit Service 384592
    const char              *unparsed;
Packit Service 384592
    const char              *filename;
Packit Service 384592
    int                      line_num;
Packit Service 384592
    int                      placeholder;
Packit Service 384592
    int                      type;
Packit Service 384592
Packit Service 384592
    msre_ruleset            *ruleset;
Packit Service 384592
    msre_rule               *chain_starter;
Packit Service 384592
    #if defined(PERFORMANCE_MEASUREMENT)
Packit Service 384592
    unsigned int             execution_time;
Packit Service 384592
    unsigned int             trans_time;
Packit Service 384592
    unsigned int             op_time;
Packit Service 384592
    #endif
Packit Service 384592
Packit Service 384592
    #if defined(WITH_LUA)
Packit Service 384592
    /* Compiled Lua script. */
Packit Service 384592
    msc_script              *script;
Packit Service 384592
    #endif
Packit Service 384592
Packit Service 384592
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 0
Packit Service 384592
    ap_regex_t              *sub_regex;
Packit Service 384592
#else
Packit Service 384592
    regex_t                 *sub_regex;
Packit Service 384592
#endif
Packit Service 384592
    char                    *sub_str;
Packit Service 384592
    char                    *re_str;
Packit Service 384592
    int                     re_precomp;
Packit Service 384592
    int                     escape_re;
Packit Service 384592
Packit Service 384592
    TreeRoot                *ip_op;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
char DSOLOCAL *msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, const char *targets, const char *args, const char *actions);
Packit Service 384592
Packit Service 384592
msre_rule DSOLOCAL *msre_rule_create(msre_ruleset *ruleset, int type,
Packit Service 384592
    const char *fn, int line, const char *targets,
Packit Service 384592
    const char *args, const char *actions, char **error_msg);
Packit Service 384592
Packit Service 384592
#if defined(WITH_LUA)
Packit Service 384592
msre_rule DSOLOCAL *msre_rule_lua_create(msre_ruleset *ruleset,
Packit Service 384592
    const char *fn, int line, const char *script_filename,
Packit Service 384592
    const char *actions, char **error_msg);
Packit Service 384592
#endif
Packit Service 384592
Packit Service 384592
#define VAR_SIMPLE              0    /* REQUEST_URI */
Packit Service 384592
#define VAR_LIST                1
Packit Service 384592
Packit Service 384592
#define PHASE_REQUEST_HEADERS   1
Packit Service 384592
#define PHASE_REQUEST_BODY      2
Packit Service 384592
#define PHASE_RESPONSE_HEADERS  3
Packit Service 384592
#define PHASE_RESPONSE_BODY     4
Packit Service 384592
#define PHASE_LOGGING           5
Packit Service 384592
Packit Service 384592
typedef int (*fn_op_param_init_t)(msre_rule *rule, char **error_msg);
Packit Service 384592
typedef int (*fn_op_execute_t)(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg);
Packit Service 384592
Packit Service 384592
struct msre_op_metadata {
Packit Service 384592
    const char              *name;
Packit Service 384592
    fn_op_param_init_t       param_init;
Packit Service 384592
    fn_op_execute_t          execute;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
typedef int (*fn_tfn_execute_t)(apr_pool_t *pool, unsigned char *input, long int input_length, char **rval, long int *rval_length);
Packit Service 384592
Packit Service 384592
struct msre_tfn_metadata {
Packit Service 384592
    const char              *name;
Packit Service 384592
Packit Service 384592
    /* Functions should populate *rval and return 1 on
Packit Service 384592
     * success, or return -1 on failure (in which case *rval
Packit Service 384592
     * should contain the error message. Strict functions
Packit Service 384592
     * (those that validate in
Packit Service 384592
     * addition to transforming) can return 0 when input
Packit Service 384592
     * fails validation. Functions are free to perform
Packit Service 384592
     * in-place transformation, or to allocate a new buffer
Packit Service 384592
     * from the provideded temporary (per-rule) memory pool.
Packit Service 384592
     *
Packit Service 384592
     * NOTE Strict transformation functions not supported yet.
Packit Service 384592
     */
Packit Service 384592
    fn_tfn_execute_t execute;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_tfn_register(msre_engine *engine, const char *name,
Packit Service 384592
    fn_tfn_execute_t execute);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_op_register(msre_engine *engine, const char *name,
Packit Service 384592
    fn_op_param_init_t fn1, fn_op_execute_t fn2);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_register_default_tfns(msre_engine *engine);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_register_default_variables(msre_engine *engine);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_register_default_operators(msre_engine *engine);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_register_default_actions(msre_engine *engine);
Packit Service 384592
Packit Service 384592
msre_tfn_metadata DSOLOCAL *msre_engine_tfn_resolve(msre_engine *engine, const char *name);
Packit Service 384592
Packit Service 384592
#define VAR_DONT_CACHE  0
Packit Service 384592
#define VAR_CACHE       1
Packit Service 384592
Packit Service 384592
typedef char *(*fn_var_validate_t)(msre_ruleset *ruleset, msre_var *var);
Packit Service 384592
typedef int (*fn_var_generate_t)(modsec_rec *msr, msre_var *var, msre_rule *rule, apr_table_t *table, apr_pool_t *mptmp);
Packit Service 384592
Packit Service 384592
struct msre_var_metadata {
Packit Service 384592
    const char              *name;
Packit Service 384592
    unsigned int             type;          /* VAR_TYPE_ constants */
Packit Service 384592
    unsigned int             argc_min;
Packit Service 384592
    unsigned int             argc_max;
Packit Service 384592
    fn_var_validate_t        validate;
Packit Service 384592
    fn_var_generate_t        generate;
Packit Service 384592
    unsigned int             is_cacheable;  /* 0 - no, 1 - yes */
Packit Service 384592
    unsigned int             availability;  /* when does this variable become available? */
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct msre_var {
Packit Service 384592
    char                    *name;
Packit Service 384592
    const char              *value;
Packit Service 384592
    unsigned int             value_len;
Packit Service 384592
    char                    *param;
Packit Service 384592
    const void              *param_data;
Packit Service 384592
    msre_var_metadata       *metadata;
Packit Service 384592
    msc_regex_t             *param_regex;
Packit Service 384592
    unsigned int             is_negated;
Packit Service 384592
    unsigned int             is_counting;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
Packit Service 384592
struct msre_actionset {
Packit Service 384592
    apr_table_t             *actions;
Packit Service 384592
Packit Service 384592
    /* Metadata */
Packit Service 384592
    const char              *id;
Packit Service 384592
    const char              *rev;
Packit Service 384592
    const char              *msg;
Packit Service 384592
    const char              *logdata;
Packit Service 384592
    const char              *version;
Packit Service 384592
    int                      maturity;
Packit Service 384592
    int                      accuracy;
Packit Service 384592
    int                      severity;
Packit Service 384592
    int                      phase;
Packit Service 384592
    msre_rule               *rule;
Packit Service 384592
    int                     arg_min;
Packit Service 384592
    int                     arg_max;
Packit Service 384592
Packit Service 384592
    /* Flow */
Packit Service 384592
    int                      is_chained;
Packit Service 384592
    int                      skip_count;
Packit Service 384592
    const char              *skip_after;
Packit Service 384592
Packit Service 384592
    /* Disruptive */
Packit Service 384592
    int                      intercept_action;
Packit Service 384592
    const char              *intercept_uri;
Packit Service 384592
    int                      intercept_status;
Packit Service 384592
    const char              *intercept_pause;
Packit Service 384592
Packit Service 384592
    /* "block" needs parent action to reset it */
Packit Service 384592
    msre_action             *parent_intercept_action_rec;
Packit Service 384592
    msre_action             *intercept_action_rec;
Packit Service 384592
    int                      parent_intercept_action;
Packit Service 384592
Packit Service 384592
    /* Other */
Packit Service 384592
    int                      log;
Packit Service 384592
    int                      auditlog;
Packit Service 384592
    int                      block;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_variable_register(msre_engine *engine, const char *name,
Packit Service 384592
    unsigned int type, unsigned int argc_min, unsigned int argc_max,
Packit Service 384592
    fn_var_validate_t validate, fn_var_generate_t generate,
Packit Service 384592
    unsigned int is_cacheable, unsigned int availability);
Packit Service 384592
Packit Service 384592
msre_actionset DSOLOCAL *msre_actionset_create(msre_engine *engine, apr_pool_t *mp, const char *text,
Packit Service 384592
    char **error_msg);
Packit Service 384592
Packit Service 384592
msre_actionset DSOLOCAL *msre_actionset_merge(msre_engine *engine, apr_pool_t *mp, msre_actionset *parent,
Packit Service 384592
    msre_actionset *child, int inherit_by_default);
Packit Service 384592
Packit Service 384592
msre_actionset DSOLOCAL *msre_actionset_create_default(msre_engine *engine);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_actionset_set_defaults(msre_actionset *actionset);
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_actionset_init(msre_actionset *actionset, msre_rule *rule);
Packit Service 384592
Packit Service 384592
typedef char *(*fn_action_validate_t)(msre_engine *engine, apr_pool_t *mp, msre_action *action);
Packit Service 384592
typedef apr_status_t (*fn_action_init_t)(msre_engine *engine, apr_pool_t *mp, msre_actionset *actionset, msre_action *action);
Packit Service 384592
typedef apr_status_t (*fn_action_execute_t)(modsec_rec *msr, apr_pool_t *mptmp, msre_rule *rule, msre_action *action);
Packit Service 384592
Packit Service 384592
#define ACTION_DISRUPTIVE       1
Packit Service 384592
#define ACTION_NON_DISRUPTIVE   2
Packit Service 384592
#define ACTION_METADATA         3
Packit Service 384592
#define ACTION_FLOW             4
Packit Service 384592
Packit Service 384592
#define NO_PLUS_MINUS           0
Packit Service 384592
#define ALLOW_PLUS_MINUS        1
Packit Service 384592
Packit Service 384592
#define ACTION_CARDINALITY_ONE  1
Packit Service 384592
#define ACTION_CARDINALITY_MANY 2
Packit Service 384592
Packit Service 384592
#define ACTION_CGROUP_NONE       0
Packit Service 384592
#define ACTION_CGROUP_DISRUPTIVE 1
Packit Service 384592
#define ACTION_CGROUP_LOG        2
Packit Service 384592
#define ACTION_CGROUP_AUDITLOG   3
Packit Service 384592
Packit Service 384592
struct msre_action_metadata {
Packit Service 384592
    const char              *name;
Packit Service 384592
    unsigned int             type;
Packit Service 384592
    unsigned int             argc_min;
Packit Service 384592
    unsigned int             argc_max;
Packit Service 384592
    unsigned int             allow_param_plusminus;
Packit Service 384592
    unsigned int             cardinality;
Packit Service 384592
    unsigned int             cardinality_group;
Packit Service 384592
    fn_action_validate_t     validate;
Packit Service 384592
    fn_action_init_t         init;
Packit Service 384592
    fn_action_execute_t      execute;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct msre_action {
Packit Service 384592
    msre_action_metadata    *metadata;
Packit Service 384592
    const char              *param;
Packit Service 384592
    const void              *param_data;
Packit Service 384592
    unsigned int             param_plusminus; /* ABSOLUTE_VALUE, POSITIVE_VALUE, NEGATIVE_VALUE */
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
void DSOLOCAL msre_engine_reqbody_processor_register(msre_engine *engine,
Packit Service 384592
    const char *name, void *fn_init, void *fn_process, void *fn_complete);
Packit Service 384592
Packit Service 384592
typedef int (*fn_reqbody_processor_init_t)(modsec_rec *msr, char **error_msg);
Packit Service 384592
typedef int (*fn_reqbody_processor_process_t)(modsec_rec *msr, const char *buf,
Packit Service 384592
            unsigned int size, char **error_msg);
Packit Service 384592
typedef int (*fn_reqbody_processor_complete_t)(modsec_rec *msr, char **error_msg);
Packit Service 384592
Packit Service 384592
struct msre_reqbody_processor_metadata {
Packit Service 384592
    const char                       *name;
Packit Service 384592
    fn_reqbody_processor_init_t       init;
Packit Service 384592
    fn_reqbody_processor_process_t    process;
Packit Service 384592
    fn_reqbody_processor_complete_t   complete;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
/* -- MSRE Function Prototypes ---------------------------------------------- */
Packit Service 384592
Packit Service 384592
msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
Packit Service 384592
Packit Service 384592
int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
Packit Service 384592
    char **error_msg);
Packit Service 384592
Packit Service 384592
apr_status_t DSOLOCAL msre_parse_vars(msre_ruleset *ruleset, const char *text,
Packit Service 384592
    apr_array_header_t *arr, char **error_msg);
Packit Service 384592
Packit Service 384592
char DSOLOCAL *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset);
Packit Service 384592
Packit Service 384592
/* -- Data Cache -- */
Packit Service 384592
Packit Service 384592
struct msre_cache_rec {
Packit Service 384592
    int                      hits;
Packit Service 384592
    int                      changed;
Packit Service 384592
    int                      num;
Packit Service 384592
    const char              *path;
Packit Service 384592
    const char              *val;
Packit Service 384592
    apr_size_t               val_len;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct fuzzy_hash_chunk {
Packit Service 384592
    const char *data;
Packit Service 384592
    struct fuzzy_hash_chunk *next;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
struct fuzzy_hash_param_data {
Packit Service 384592
    const char *file;
Packit Service 384592
    struct fuzzy_hash_chunk *head;
Packit Service 384592
    int threshold;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
#endif