int get_cfg_block(config_file_t config, const char *name, config_item_t *item, char *msg_out) { bool unique = true; config_item_t block = rh_config_FindItemByName(config, name, &unique); *item = NULL; if (block == NULL) { sprintf(msg_out, "Missing configuration block '%s'", name); return ENOENT; } else if (!unique) { sprintf(msg_out, "Found duplicate of block '%s' line %d.", name, rh_config_GetItemLine(block)); return EEXIST; } if (rh_config_ItemType(block) != CONFIG_ITEM_BLOCK) { sprintf(msg_out, "A block is expected for '%s' item, line %d", name, rh_config_GetItemLine(block)); return EINVAL; } *item = block; return 0; }
/** get param with the given name and check for existence and unicity */ static int get_cfg_param(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, char **pname, char **pvalue, int *pextra, config_item_t *pitem, char *err_msg) { bool unique = true; int rc; *pitem = rh_config_GetItemByName(block, var_name, &unique); if (!*pitem) { if (flags & PFLG_MANDATORY) sprintf(err_msg, "Missing mandatory parameter '%s' in block '%s', line %d", var_name, block_name, rh_config_GetItemLine(block)); /* return ENOENT in any case */ return ENOENT; } else if (!unique) { sprintf(err_msg, "Duplicate definition of parameter '%s' found in block '%s', line %d.", var_name, block_name, rh_config_GetItemLine(*pitem)); return EEXIST; } rc = rh_config_GetKeyValue(*pitem, pname, pvalue, pextra); if (rc) sprintf(err_msg, "Error retrieving parameter value for '%s::%s', line %d:\n%s", block_name, var_name, rh_config_GetItemLine(*pitem), rh_config_GetErrorMsg()); return rc; }
/** * Retrieve a size parameter and check its format * @return 0 on success * ENOENT if the parameter does not exist in the block * EINVAL if the parameter does not satisfy restrictions */ int GetSizeParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, unsigned long long *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc; int extra = 0; unsigned long long sizeval; char *name; char *value; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; sizeval = str2size( value ); if ( sizeval == ( unsigned long long ) -1 ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: size expected. Eg: 10MB", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NOT_NULL) && (sizeval == 0)) { sprintf( err_msg, "'%s::%s' must not be null, line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } *target = sizeval; if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
int GetBoolParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, bool *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg ) { config_item_t curr_item; int rc, extra; char *name; char *value; int tmp_bool; err_msg[0] = '\0'; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; tmp_bool = str2bool(value); if (tmp_bool == -1) { sprintf(err_msg, "Invalid value for '%s::%s', line %d: boolean expected (0, 1, true, false, yes, no, enabled, disabled)", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } *target = (tmp_bool != 0); if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
int ReadLmgrConfig( config_file_t config, void *module_config, char *msg_out, int for_reload ) { int rc; lmgr_config_t *conf = ( lmgr_config_t * ) module_config; char **options = NULL; unsigned int nb_options = 0; char tmpstr[1024]; config_item_t db_block; static const char *lmgr_allowed[] = { "commit_behavior", "connect_retry_interval_min", "connect_retry_interval_max", "user_acct", "group_acct", MYSQL_CONFIG_BLOCK, SQLITE_CONFIG_BLOCK, NULL }; #ifdef _MYSQL static const char *db_allowed[] = { "server", "db", "user", "password", "password_file", "port", "socket", "innodb", NULL }; #elif defined (_SQLITE) static const char *db_allowed[] = { "db_file", "retry_delay_microsec", NULL }; #endif /* get ListManager block */ config_item_t lmgr_block = rh_config_FindItemByName( config, LMGR_CONFIG_BLOCK ); if ( lmgr_block == NULL ) { strcpy( msg_out, "Missing configuration block '" LMGR_CONFIG_BLOCK "'" ); return ENOENT; } if ( rh_config_ItemType( lmgr_block ) != CONFIG_ITEM_BLOCK ) { strcpy( msg_out, "A block is expected for '" LMGR_CONFIG_BLOCK "' item" ); return EINVAL; } /* retrieve parameters */ /* 1) commit_behavior */ rc = GetStringParam( lmgr_block, LMGR_CONFIG_BLOCK, "commit_behavior", STR_PARAM_NO_WILDCARDS, tmpstr, 1024, &options, &nb_options, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc != ENOENT ) { if ( !strcasecmp( tmpstr, "autocommit" ) ) conf->commit_behavior = 0; else if ( !strcasecmp( tmpstr, "transaction" ) ) conf->commit_behavior = 1; else if ( !strcasecmp( tmpstr, "periodical" ) /* for backward compatibility */ || !strcasecmp( tmpstr, "periodic" ) ) { if ( ( nb_options != 1 ) || !options || !options[0] ) { strcpy( msg_out, "A single argument is expected for periodic commit behavior. Eg: commit_behavior = periodic(1000)" ); return EINVAL; } conf->commit_behavior = atoi( options[0] ); if ( conf->commit_behavior == 0 ) { strcpy( msg_out, "The argument for \"" LMGR_CONFIG_BLOCK "::commit_behavior = periodical\" must be a positive integer. Eg: commit_behavior = periodic(1000)" ); return EINVAL; } } else { sprintf( msg_out, "Invalid commit behavior '%s' (expected: autocommit, " "transaction, periodic(<count>))", tmpstr ); return EINVAL; } } /* 2) connect_retry_interval_min and connect_retry_interval_max */ rc = GetDurationParam( lmgr_block, LMGR_CONFIG_BLOCK, "connect_retry_interval_min", INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL, ( int * ) &conf->connect_retry_min, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetDurationParam( lmgr_block, LMGR_CONFIG_BLOCK, "connect_retry_interval_max", INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL, ( int * ) &conf->connect_retry_max, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; /* 3) ACCT configuration*/ rc = GetBoolParam( lmgr_block, LMGR_CONFIG_BLOCK, "user_acct", 0, &conf->user_acct, NULL, NULL, msg_out); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetBoolParam( lmgr_block, LMGR_CONFIG_BLOCK, "group_acct", 0, &conf->group_acct, NULL, NULL, msg_out); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; CheckUnknownParameters( lmgr_block, LMGR_CONFIG_BLOCK, lmgr_allowed ); /* Database specific parameters */ #ifdef _MYSQL /* get MySQL block */ db_block = rh_config_GetItemByName( lmgr_block, MYSQL_CONFIG_BLOCK ); if ( db_block == NULL ) { strcpy( msg_out, "Missing configuration block '" LMGR_CONFIG_BLOCK "::" MYSQL_CONFIG_BLOCK "'" ); return ENOENT; } if ( rh_config_ItemType( db_block ) != CONFIG_ITEM_BLOCK ) { sprintf( msg_out, "A block is expected for '" LMGR_CONFIG_BLOCK "::" MYSQL_CONFIG_BLOCK "' item, line %d", rh_config_GetItemLine( db_block ) ); return EINVAL; } rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "server", STR_PARAM_NO_WILDCARDS, conf->db_config.server, 256, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "db", PARAM_MANDATORY | STR_PARAM_NO_WILDCARDS, conf->db_config.db, 256, NULL, NULL, msg_out ); if ( rc ) return rc; rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "user", STR_PARAM_NO_WILDCARDS, conf->db_config.user, 256, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "password", 0, conf->db_config.password, 256, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc == ENOENT ) { FILE *passfile; char errstr[1024]; rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "password_file", STR_PARAM_ABSOLUTE_PATH | STR_PARAM_NO_WILDCARDS, tmpstr, 1024, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc == ENOENT ) { strcpy( msg_out, MYSQL_CONFIG_BLOCK "::password or " MYSQL_CONFIG_BLOCK "::password_file must be provided" ); return ENOENT; } /* read password file and @TODO check its rights */ passfile = fopen( tmpstr, "r" ); if ( !passfile ) { rc = errno; sprintf( msg_out, "Error openning password file %s : %s", tmpstr, strerror(errno) ); return rc; } fscanf( passfile, "%1024s", tmpstr ); if ( ferror( passfile ) ) { rc = errno; strerror_r( rc, errstr, 1024 ); sprintf( msg_out, "Error reading password file %s : %s", tmpstr, errstr ); return rc; } fclose( passfile ); strncpy( conf->db_config.password, tmpstr, 256 ); } rc = GetIntParam( db_block, MYSQL_CONFIG_BLOCK, "port", INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL, (int*)&conf->db_config.port, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "socket", STR_PARAM_NO_WILDCARDS | STR_PARAM_ABSOLUTE_PATH, conf->db_config.socket, RBH_PATH_MAX, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetBoolParam( db_block, MYSQL_CONFIG_BLOCK, "innodb", 0, &conf->db_config.innodb, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; CheckUnknownParameters( db_block, MYSQL_CONFIG_BLOCK, db_allowed ); #elif defined (_SQLITE) /* get SQLite block */ db_block = rh_config_GetItemByName( lmgr_block, SQLITE_CONFIG_BLOCK ); if ( db_block == NULL ) { strcpy( msg_out, "Missing configuration block '" LMGR_CONFIG_BLOCK "::" SQLITE_CONFIG_BLOCK "'" ); return ENOENT; } if ( rh_config_ItemType( db_block ) != CONFIG_ITEM_BLOCK ) { sprintf( msg_out, "A block is expected for '" LMGR_CONFIG_BLOCK "::" SQLITE_CONFIG_BLOCK "' item, line %d", rh_config_GetItemLine( db_block ) ); return EINVAL; } rc = GetStringParam( db_block, SQLITE_CONFIG_BLOCK, "db_file", STR_PARAM_ABSOLUTE_PATH | STR_PARAM_NO_WILDCARDS, conf->db_config.filepath, RBH_PATH_MAX, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetIntParam( db_block, SQLITE_CONFIG_BLOCK, "retry_delay_microsec", INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL, (int*)&conf->db_config.retry_delay_microsec, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; CheckUnknownParameters( db_block, SQLITE_CONFIG_BLOCK, db_allowed ); #endif return 0; }
/** * Check that no unknown parameter or block is found. * @param param_array NULL terminated array of allowed parameters. */ void CheckUnknownParameters(config_item_t block, const char *block_name, const char * const *param_array ) { int i, j; for ( i = 0; i < rh_config_GetNbItems( block ); i++ ) { config_item_t curr_item = rh_config_GetItemByIndex( block, i ); if ( rh_config_ItemType( curr_item ) == CONFIG_ITEM_VAR ) { char *name; char *value; int args_flg; bool found = false; if ( rh_config_GetKeyValue( curr_item, &name, &value, &args_flg ) == 0 ) { for ( j = 0; param_array[j] != NULL; j++ ) { if ( !strcasecmp( param_array[j], name ) ) { found = true; break; } } if ( !found ) DisplayLog( LVL_CRIT, "Config Check", "WARNING: unknown parameter '%s' in block '%s' line %d", name, block_name, rh_config_GetItemLine( curr_item ) ); } } else if ( rh_config_ItemType( curr_item ) == CONFIG_ITEM_BLOCK ) { char *name; bool found = false; name = rh_config_GetBlockName( curr_item ); if ( name != NULL ) { for ( j = 0; param_array[j] != NULL; j++ ) { if ( !strcasecmp( param_array[j], name ) ) { found = true; break; } } if ( !found ) DisplayLog( LVL_CRIT, "Config Check", "WARNING: unknown block '%s' as sub-block of '%s' line %d", name, block_name, rh_config_GetItemLine( curr_item ) ); } } } }
/** * Misc. tools for config parsing */ int GetStringParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, char *target, unsigned int target_size, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc; int extra = 0; char *name; char *value; gsize sz; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; sz = g_strlcpy(target, value, target_size); if (sz >= target_size) { sprintf(err_msg, "Option too long for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } /* checks */ /* empty string? */ if ((flags & PFLG_NOT_EMPTY) && EMPTY_STRING(target)) { sprintf(err_msg, "Unexpected empty parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } /* are stdio names allowed ? */ if ((flags & PFLG_STDIO_ALLOWED) && is_stdname(target)) return 0; if ((flags & PFLG_ABSOLUTE_PATH) && !IS_ABSOLUTE_PATH(target)) { sprintf( err_msg, "Absolute path expected for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NO_WILDCARDS) && WILDCARDS_IN(target)) { sprintf( err_msg, "Wildcards are not allowed in '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if (flags & PFLG_MAIL) { char *arob = strchr( target, '@' ); /* check there is an arobase, and this arobase has text before and after */ if ( ( arob == NULL ) || ( arob == target ) || ( *( arob + 1 ) == '\0' ) ) { sprintf( err_msg, "Invalid mail address in '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } } if ((flags & PFLG_REMOVE_FINAL_SLASH) && FINAL_SLASH(target)) REMOVE_FINAL_SLASH(target); return 0; }
/** * Retrieve a float parameter and check its format * @return 0 on success * ENOENT if the parameter does not exist in the block * EINVAL if the parameter does not satisfy restrictions */ int GetFloatParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, double *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc, extra, nb_read; double val; char *name; char *value; char tmpbuf[256]; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; nb_read = sscanf( value, "%lf%256s", &val, tmpbuf ); if ( nb_read < 1 ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: float expected.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ( nb_read > 1 ) { if ((!(flags & PFLG_ALLOW_PCT_SIGN) && (tmpbuf[0] != '\0')) /* no sign allowed */ || ((flags & PFLG_ALLOW_PCT_SIGN) && (strcmp(tmpbuf, "%") != 0))) /* '%' allowed */ { sprintf( err_msg, "Invalid value for '%s::%s', line %d: extra characters '%s' found after float %.2f.", block_name, var_name, rh_config_GetItemLine( curr_item ), tmpbuf, val ); return EINVAL; } } if ((flags & PFLG_POSITIVE) && (val < 0.0)) { sprintf( err_msg, "Positive value expected for '%s::%s', line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NOT_NULL) && (val == 0.0)) { sprintf( err_msg, "'%s::%s' must not be null, line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } *target = val; if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
/** * Retrieve a long integer parameter and check its format. * (a suffix can be used in config file). * @return 0 on success * ENOENT if the parameter does not exist in the block * EINVAL if the parameter does not satisfy restrictions */ int GetInt64Param(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, uint64_t *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc, extra, nb_read; uint64_t intval; char *name; char *value; char tmpbuf[256]; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; nb_read = sscanf( value, "%"SCNu64"%256s", &intval, tmpbuf ); if ( nb_read < 1 ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: integer expected.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ( ( nb_read > 1 ) && ( tmpbuf[0] != '\0' ) ) { /* check suffix */ if ( !strcasecmp( tmpbuf, "k" ) ) intval *= 1000ULL; /* thousand */ else if ( !strcasecmp( tmpbuf, "M" ) ) intval *= 1000000ULL; /* million */ else if ( !strcasecmp( tmpbuf, "G" ) ) intval *= 1000000000ULL; /* billion */ else if ( !strcasecmp( tmpbuf, "T" ) ) intval *= 1000000000000ULL; /* trillion */ else { sprintf( err_msg, "Invalid suffix for '%s::%s', line %d: '%s'. " "Only 'k', 'M', 'G' or 'T' are allowed.", block_name, var_name, rh_config_GetItemLine( curr_item ), tmpbuf ); return EINVAL; } } if ((flags & PFLG_NOT_NULL) && (intval == 0)) { sprintf( err_msg, "'%s::%s' must not be null, line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } *target = intval; if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
/** * Retrieve an integer parameter and check its format * @return 0 on success * ENOENT if the parameter does not exist in the block * EINVAL if the parameter does not satisfy restrictions */ int GetIntParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, int *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc, extra, intval, nb_read; char *name; char *value; char tmpbuf[256]; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; nb_read = sscanf( value, "%d%256s", &intval, tmpbuf ); if ( nb_read < 1 ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: integer expected.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ( ( nb_read > 1 ) && ( tmpbuf[0] != '\0' ) ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: extra characters '%s' found after integer %d.", block_name, var_name, rh_config_GetItemLine( curr_item ), tmpbuf, intval ); return EINVAL; } if ((flags & PFLG_POSITIVE) && (intval < 0)) { sprintf( err_msg, "Positive value expected for '%s::%s', line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NOT_NULL) && (intval == 0)) { sprintf( err_msg, "'%s::%s' must not be null, line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } *target = intval; if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
/** * Retrieve a duration parameter and check its format * @return 0 on success * ENOENT if the parameter does not exist in the block * EINVAL if the parameter does not satisfy restrictions */ int GetDurationParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, time_t *target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc, extra; time_t timeval; char *name; char *value; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; timeval = str2duration( value ); if ( timeval == -1 ) { sprintf( err_msg, "Invalid value for '%s::%s', line %d: duration expected. Eg: 10s", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_POSITIVE) && (timeval < 0)) { sprintf( err_msg, "Positive value expected for '%s::%s', line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NOT_NULL) && (timeval == 0)) { sprintf( err_msg, "'%s::%s' must not be null, line %d.", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } *target = timeval; if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } return 0; }
int GetCommandParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, char ***target, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc, ac; int extra = 0; char *name; char *value; GError *err_desc; err_msg[0] = '\0'; if (nb_extra_args) *nb_extra_args = 0; if (extra_args_tab) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; /* Early check */ if ((flags & PFLG_NO_WILDCARDS) && WILDCARDS_IN(value)) { sprintf( err_msg, "Wildcards are not allowed in '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } /* free previous array */ if (*target != NULL) { g_strfreev(*target); *target = NULL; } /* Split argv */ if (value[0] != '\0') { rc = g_shell_parse_argv(value, &ac, target, &err_desc); if (!rc) { sprintf(err_msg, "Cannot parse '%s': %s", value, err_desc->message); g_error_free(err_desc); return EINVAL; } if (ac == 0) { g_strfreev(*target); *target = NULL; } } if (extra) { if (!extra_args_tab || !nb_extra_args) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } /* Post checks */ /* empty string? */ if ((flags & PFLG_NOT_EMPTY) && *target == NULL) { sprintf(err_msg, "Unexpected empty parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } return 0; }
int ReadLogConfig( config_file_t config, void *module_config, char *msg_out, int for_reload ) { int rc, tmpval; char tmpstr[1024]; log_config_t *conf = ( log_config_t * ) module_config; static const char *allowed_params[] = { "debug_level", "log_file", "report_file", "alert_file", "alert_mail", "stats_interval", "batch_alert_max", "alert_show_attrs", "syslog_facility", NULL }; /* get Log block */ config_item_t log_block = rh_config_FindItemByName( config, RBH_LOG_CONFIG_BLOCK ); if ( log_block == NULL ) { strcpy( msg_out, "Missing configuration block '" RBH_LOG_CONFIG_BLOCK "'" ); /* no parameter is mandatory => Not an error */ return 0; } if ( rh_config_ItemType( log_block ) != CONFIG_ITEM_BLOCK ) { sprintf( msg_out, "A block is expected for '" RBH_LOG_CONFIG_BLOCK "' item, line %d", rh_config_GetItemLine( log_block ) ); return EINVAL; } /* retrieve parameters */ rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "debug_level", STR_PARAM_NO_WILDCARDS, tmpstr, 1024, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc != ENOENT ) { tmpval = str2debuglevel( tmpstr ); if ( tmpval < 0 ) { sprintf( msg_out, "Invalid value for " RBH_LOG_CONFIG_BLOCK "::debug_level: '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected", tmpstr ); return EINVAL; } else conf->debug_level = tmpval; } rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "log_file", STR_PARAM_ABSOLUTE_PATH | STR_PARAM_NO_WILDCARDS | STDIO_ALLOWED, conf->log_file, RBH_PATH_MAX, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "report_file", STR_PARAM_ABSOLUTE_PATH | STR_PARAM_NO_WILDCARDS | STDIO_ALLOWED, conf->report_file, RBH_PATH_MAX, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "alert_file", STR_PARAM_ABSOLUTE_PATH | STR_PARAM_NO_WILDCARDS | STDIO_ALLOWED, conf->alert_file, 1024, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc == ENOENT ) conf->alert_file[0] = '\0'; rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "syslog_facility", STR_PARAM_NO_WILDCARDS, tmpstr, 1024, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc == 0 ) { rc = check_syslog_facility( tmpstr, &conf->syslog_facility, &conf->syslog_priority ); if (rc) { sprintf( msg_out, "Invalid syslog channel '%s': expected syntax: <facility>[.<priority>]", tmpstr ); return rc; } } rc = GetStringParam( log_block, RBH_LOG_CONFIG_BLOCK, "alert_mail", STR_PARAM_MAIL, conf->alert_mail, 256, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc == ENOENT ) conf->alert_mail[0] = '\0'; rc = GetDurationParam( log_block, RBH_LOG_CONFIG_BLOCK, "stats_interval", INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL, &tmpval, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; else if ( rc != ENOENT ) conf->stats_interval = tmpval; rc = GetIntParam( log_block, RBH_LOG_CONFIG_BLOCK, "batch_alert_max", INT_PARAM_POSITIVE, (int *)&conf->batch_alert_max, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; rc = GetBoolParam( log_block, RBH_LOG_CONFIG_BLOCK, "alert_show_attrs", INT_PARAM_POSITIVE, &conf->alert_show_attrs, NULL, NULL, msg_out ); if ( ( rc != 0 ) && ( rc != ENOENT ) ) return rc; CheckUnknownParameters( log_block, RBH_LOG_CONFIG_BLOCK, allowed_params ); return 0; }
static int polrun_read_config(config_file_t config, const char *policy_name, const struct sm_instance *smi, policy_run_config_t *conf, char *msg_out) { int rc; char block_name[1024]; char tmp[1024]; config_item_t param_block, action_params_block; char **extra = NULL; unsigned int extra_cnt = 0; /* parameter for CheckUnknownParams() */ static const char *allowed[] = { "lru_sort_attr", "max_action_count", "max_action_volume", "nb_threads", "suspend_error_pct", "suspend_error_min", "report_interval", "action_timeout", "check_actions_interval", "check_actions_on_startup", "recheck_ignored_entries", "report_actions", "pre_maintenance_window", "maint_min_apply_delay", "queue_size", "db_result_size_max", "action_params", "action", "recheck_ignored_classes", /* for compat */ NULL }; /* parameter for read_scalar_params() */ const cfg_param_t cfg_params[] = { { "max_action_count", PT_INT, PFLG_POSITIVE, &conf->max_action_nbr, 0 }, { "max_action_volume", PT_SIZE, PFLG_POSITIVE, &conf->max_action_vol, 0 }, { "nb_threads", PT_INT, PFLG_POSITIVE | PFLG_NOT_NULL, &conf->nb_threads, 0 }, { "suspend_error_pct", PT_FLOAT, PFLG_POSITIVE | PFLG_ALLOW_PCT_SIGN, &conf->suspend_error_pct, 0 }, { "suspend_error_min", PT_INT, PFLG_POSITIVE, &conf->suspend_error_min, 0 }, { "report_interval", PT_DURATION, PFLG_POSITIVE | PFLG_NOT_NULL, &conf->report_interval, 0 }, { "action_timeout", PT_DURATION, PFLG_POSITIVE, &conf->action_timeout, 0 }, { "check_actions_interval", PT_DURATION, PFLG_POSITIVE, &conf->check_action_status_delay, 0 }, { "check_actions_on_startup", PT_BOOL, 0, &conf->check_action_status_on_startup, 0 }, { "recheck_ignored_entries", PT_BOOL, 0, &conf->recheck_ignored_entries, 0 }, {"report_actions", PT_BOOL, 0, &conf->report_actions, 0}, { "pre_maintenance_window", PT_DURATION, PFLG_POSITIVE, &conf->pre_maintenance_window, 0 }, { "maint_min_apply_delay", PT_DURATION, PFLG_POSITIVE, &conf->maint_min_apply_delay, 0 }, { "queue_size", PT_INT, PFLG_POSITIVE | PFLG_NOT_NULL, &conf->queue_size, 0 }, { "db_result_size_max", PT_INT, PFLG_POSITIVE, &conf->db_request_limit, 0 }, {NULL, 0, 0, NULL, 0} }; snprintf(block_name, sizeof(block_name), "%s" PARAM_SUFFIX, policy_name); /* get <policy>_parameters block */ rc = get_cfg_block(config, block_name, ¶m_block, msg_out); if (rc) return rc == ENOENT ? 0 : rc; /* not mandatory */ /* check deprecated parameters */ rc = GetBoolParam(param_block, block_name, "recheck_ignored_classes", 0, &conf->recheck_ignored_entries, NULL, NULL, msg_out); if (rc == 0) DisplayLog(LVL_CRIT, TAG, "WARNING: parameter %s::%s' is deprecated. " "Use 'recheck_ignored_entries' instead.", block_name, "recheck_ignored_classes"); /* read all scalar params */ rc = read_scalar_params(param_block, block_name, cfg_params, msg_out); if (rc) return rc; /* read specific parameters */ /* 'lru_sort_attr' overrides 'default_lru_sort_attr' from 'define_policy' */ rc = GetStringParam(param_block, block_name, "lru_sort_attr", PFLG_NO_WILDCARDS, tmp, sizeof(tmp), NULL, NULL, msg_out); if ((rc != 0) && (rc != ENOENT)) return rc; else if (rc != ENOENT) { /* is it a time attribute? */ rc = str2lru_attr(tmp, smi); if (rc == LRU_ATTR_INVAL) { strcpy(msg_out, "time attribute expected for 'lru_sort_attr': " ALLOWED_LRU_ATTRS_STR "..."); return EINVAL; } else conf->lru_sort_attr = rc; } /* 'action' overrides 'default_action' from 'define_policy' */ rc = GetStringParam(param_block, block_name, "action", 0, tmp, sizeof(tmp), &extra, &extra_cnt, msg_out); if ((rc != 0) && (rc != ENOENT)) return rc; else if (rc != ENOENT) { rc = parse_policy_action("action", tmp, extra, extra_cnt, &conf->action, &conf->run_attr_mask, msg_out); if (rc) return rc; } /* get subblock */ bool unique = true; action_params_block = rh_config_GetItemByName(param_block, "action_params", &unique); if (action_params_block != NULL) { if (!unique) { sprintf(msg_out, "Found duplicate block '%s' in '%s' line %d.", "action_params", block_name, rh_config_GetItemLine(action_params_block)); return EEXIST; } if (rh_config_ItemType(action_params_block) != CONFIG_ITEM_BLOCK) { sprintf(msg_out, "A block is expected for configuration item '%s::action_params', line %d.", block_name, rh_config_GetItemLine(action_params_block)); return EINVAL; } #ifdef _DEBUG_POLICIES fprintf(stderr, "processing parameters in '%s'\n", block_name); #endif rc = read_action_params(action_params_block, &conf->action_params, &conf->run_attr_mask, msg_out); if (rc) return rc; } /* warn for unknown parameters */ CheckUnknownParameters(param_block, block_name, allowed); return 0; }
/** parse a trigger block from configuration and fills a trigger item */ static int parse_trigger_block(config_item_t config_blk, const char *block_name, trigger_item_t *p_trigger_item, char *msg_out) { int rc; char tmpstr[1024]; char **arg_tab; unsigned int arg_count; config_item_t params_block; const struct trig_target_def *def; static const char *trigger_expect[] = { "trigger_on", "check_interval", "high_threshold_pct", "low_threshold_pct", "high_threshold_vol", "low_threshold_vol", "high_threshold_cnt", "low_threshold_cnt", "alert_high", "alert_low", "post_trigger_wait", "action_params", "max_action_count", "max_action_volume", NULL }; const cfg_param_t cfg_params[] = { { "max_action_count", PT_INT, PFLG_POSITIVE, &p_trigger_item->max_action_nbr, 0 }, { "max_action_volume", PT_SIZE, PFLG_POSITIVE, &p_trigger_item->max_action_vol, 0 }, { "check_interval", PT_DURATION, PFLG_POSITIVE | PFLG_NOT_NULL | PFLG_MANDATORY, &p_trigger_item->check_interval, 0 }, { "alert_high", PT_BOOL, 0, &p_trigger_item->alert_hw, 0 }, { "alert_low", PT_BOOL, 0, &p_trigger_item->alert_lw, 0 }, { "post_trigger_wait", PT_DURATION, 0, &p_trigger_item->post_trigger_wait, 0 }, END_OF_PARAMS }; memset(p_trigger_item, 0, sizeof(*p_trigger_item)); /* retrieve special parameters */ rc = GetStringParam(config_blk, block_name, "trigger_on", PFLG_MANDATORY | PFLG_NO_WILDCARDS, tmpstr, sizeof(tmpstr), &arg_tab, &arg_count, msg_out); if (rc) /* even ENOENT retruns an error because trigger_on is mandatory */ return rc; /* initialize list of optional args */ p_trigger_item->list = NULL; p_trigger_item->list_size = 0; def = str2trigger_def(tmpstr); if (def == NULL) { sprintf(msg_out, "Unexpected value for 'trigger_on' parameter: %s.", tmpstr); return EINVAL; } rc = set_trigger_target(p_trigger_item, def, arg_tab, arg_count, msg_out); if (rc) return rc; /* retrieve high and low thresholds params and check their compatibility */ rc = read_threshold_params(config_blk, block_name, "high", p_trigger_item, &p_trigger_item->hw_type, &p_trigger_item->hw_u, msg_out); if (rc) return rc; rc = read_threshold_params(config_blk, block_name, "low", p_trigger_item, &p_trigger_item->lw_type, &p_trigger_item->lw_u, msg_out); if (rc) return rc; if ((p_trigger_item->trigger_type != TRIG_ALWAYS) && (p_trigger_item->hw_type != p_trigger_item->lw_type)) { strcpy(msg_out, "Incompatible high/low threshold types"); return EINVAL; } /** FIXME RBHv3 count threshold for HSM systems should only match online * files (not released) */ /* retrieve other scalar parameters */ rc = read_scalar_params(config_blk, block_name, cfg_params, msg_out); if (rc) return rc; /* get action_params subblock */ bool unique = true; params_block = rh_config_GetItemByName(config_blk, "action_params", &unique); if (params_block != NULL) { if (!unique) { sprintf(msg_out, "Found duplicate block '%s' in '%s' line %d.", "action_params", block_name, rh_config_GetItemLine(params_block)); return EEXIST; } if (rh_config_ItemType(params_block) != CONFIG_ITEM_BLOCK) { sprintf(msg_out, "A block is expected for configuration item '%s::action_params', line %d.", block_name, rh_config_GetItemLine(params_block)); return EINVAL; } #ifdef _DEBUG_POLICIES fprintf(stderr, "processing parameters for trigger '%s'\n", block_name); #endif rc = read_action_params(params_block, &p_trigger_item->action_params, &p_trigger_item->params_mask, msg_out); if (rc) return rc; } CheckUnknownParameters(config_blk, block_name, trigger_expect); return 0; }