Add path and service module parameter types

The path type is validated if the module requested path
validation. Service checks can be done both on startup and at
runtime. This allows dynamic changes to module parameters to be validated
without a configuration context.
This commit is contained in:
Markus Mäkelä 2017-01-05 09:29:21 +02:00
parent e0ad6188ad
commit 257cb5c209
3 changed files with 83 additions and 10 deletions

View File

@ -223,10 +223,12 @@ SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *er
* @param type Module type
* @param key Parameter key
* @param value Parameter value
* @param context Configuration context or NULL for no context (uses runtime checks)
*
* @return True if the configuration parameter is valid
*/
bool config_param_is_valid(const char *module, const char *type, const char *key, const char *value);
bool config_param_is_valid(const char *module, const char *type, const char *key,
const char *value, const CONFIG_CONTEXT *context);
/**
* @brief Get a boolean value
@ -256,7 +258,8 @@ int config_get_integer(const CONFIG_PARAMETER *params, const char *key);
* @param params List of configuration parameters
* @param key Parameter name
*
* @return The raw string value */
* @return The raw string value
*/
const char* config_get_string(const CONFIG_PARAMETER *params, const char *key);
/**

View File

@ -82,16 +82,23 @@ enum mxs_module_param_type
MXS_MODULE_PARAM_INT, /**< Integer number */
MXS_MODULE_PARAM_BOOL, /**< Boolean value */
MXS_MODULE_PARAM_STRING, /**< String value */
MXS_MODULE_PARAM_ENUM /**< Enumeration of string values */
MXS_MODULE_PARAM_ENUM, /**< Enumeration of string values */
MXS_MODULE_PARAM_PATH, /**< Path to a file or a directory */
MXS_MODULE_PARAM_SERVICE, /**< Service name */
};
/** Parameter options
*
* If no type is specified, the option can be used with all parameter types
*/
enum mxs_module_param_options
{
MXS_MODULE_OPT_NONE = 0,
MXS_MODULE_OPT_REQUIRED = (1 << 0), /**< A required parameter */
MXS_MODULE_OPT_PATH_X_OK = (1 << 1), /**< PATH: Execute permission to path required */
MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */
MXS_MODULE_OPT_PATH_W_OK = (1 << 3) /**< PATH: Write permission to path required */
MXS_MODULE_OPT_NONE = 0,
MXS_MODULE_OPT_REQUIRED = (1 << 0), /**< A required parameter */
MXS_MODULE_OPT_PATH_X_OK = (1 << 1), /**< PATH: Execute permission to path required */
MXS_MODULE_OPT_PATH_R_OK = (1 << 2), /**< PATH: Read permission to path required */
MXS_MODULE_OPT_PATH_W_OK = (1 << 3), /**< PATH: Write permission to path required */
MXS_MODULE_OPT_PATH_F_OK = (1 << 4) /**< PATH: Path must exist */
};
/** Module parameter declaration */

View File

@ -2008,7 +2008,7 @@ check_config_objects(CONFIG_CONTEXT *context)
if (found == 0)
{
if (module == NULL ||
!config_param_is_valid(module, module_type, params->name, params->value))
!config_param_is_valid(module, module_type, params->name, params->value, context))
{
MXS_ERROR("Unexpected parameter '%s' for object '%s' of type '%s'.",
params->name, obj->object, type);
@ -3385,7 +3385,24 @@ bool config_is_ssl_parameter(const char *key)
return false;
}
bool config_param_is_valid(const char *module, const char *type, const char *key, const char *value)
static bool config_contains_type(const CONFIG_CONTEXT *ctx, const char *name, const char *type)
{
while (ctx)
{
if (strcmp(ctx->object, name) == 0 &&
strcmp(type, config_get_value_string(ctx->parameters, "type")) == 0)
{
return true;
}
ctx = ctx->next;
}
return false;
}
bool config_param_is_valid(const char *module, const char *type, const char *key,
const char *value, const CONFIG_CONTEXT *context)
{
bool valid = false;
const MXS_MODULE *mod = get_module(module, type);
@ -3443,6 +3460,52 @@ bool config_param_is_valid(const char *module, const char *type, const char *key
}
break;
case MXS_MODULE_PARAM_SERVICE:
if ((context && config_contains_type(context, "service", value)) ||
service_find(value))
{
valid = true;
}
break;
case MXS_MODULE_PARAM_PATH:
if (mod->parameters[i].options & (MXS_MODULE_OPT_PATH_W_OK |
MXS_MODULE_OPT_PATH_R_OK |
MXS_MODULE_OPT_PATH_X_OK |
MXS_MODULE_OPT_PATH_F_OK))
{
int mode = F_OK;
if (mod->parameters[i].options & MXS_MODULE_OPT_PATH_W_OK)
{
mode |= W_OK;
}
if (mod->parameters[i].options & MXS_MODULE_OPT_PATH_R_OK)
{
mode |= R_OK;
}
if (mod->parameters[i].options & MXS_MODULE_OPT_PATH_X_OK)
{
mode |= X_OK;
}
if (access(value, mode) == 0)
{
valid = true;
}
else
{
char err[MXS_STRERROR_BUFLEN];
MXS_ERROR("Bad path parameter '%s': %d, %s", value,
errno, strerror_r(errno, err, sizeof(err)));
}
}
else
{
/** No checks for the path are required */
valid = true;
}
break;
default:
MXS_ERROR("Unexpected module parameter type: %d", mod->parameters[i].type);
ss_dassert(false);