Warning

This is a design page. It was used to design and discuss the initial implementation of the change. However, the state of this document does not necessarily correspond to the current state of the implementation since we do not keep this document up to date with further changes and bug fixes.

Config file validation

Related ticket(s):

Typos in option names are not detected. If conflicting options are used or required options are missing, SSSD should produce easy to understand error/debug message so that administrators can fix the problem easier.

Application developers that use libini from Ding libs will be able to specify constraints that the configuration must respect. These constraints will be written using INI format in form of rules. Each rule will use one validator. The validator can be internal (provided by libini) or external (provided by applications). The rules will be written in a separate file and their usage will be optional. Validators will generate errors in form of strings that should be readable for users. Applications that use libini will then be able to write these strings somewhere appropriate (for example log files or stderr).

[rule/NAME]
validator = validator_name
validator_specific_parameter1 = ...
validator_specific_parameter2 = ...
.
.
.
validator_specific_parameterN = ...

Each rule needs to specify validator that will be used, other parameters depend on the validator. Some validators may not require any additional parameters.

The rules are used from applications in the following way:

  1. rules are loaded from file using the function int ini_read_rules_from_file(const char *filename, struct ini_cfgobj **_rules_obj);

  2. rules and configuration are passed as two fist parameters to the function

    int ini_rules_check(struct ini_cfgobj *rules_obj,
                           struct ini_cfgobj *config_obj,
                           struct ini_validator *extra_validators,
                           int num_extra_validators,
                           struct ini_errobj *errobj);
    

The last parameter is special structure used to hold all errors generated by the validators. libini will provide API to create, destroy, read errors from and write errors into this structure. The extra_validators and num_extra validators are used to specify external validators (see section ‘External validators’ below).

Internal validators will be simple validators that may be used by projects outside SSSD. More complicated and application specific validators will be written as external validators. First two internal validators will be ini_allowed_options and ini_allowed_sections.

Example:

[rule/allowed_options_for_section_foo]
validator = ini_allowed_options
section_re = ^foo$
option = foo
option = bar
option = baz

The rule above uses the ini_allowed_option validator and enumerates all allowed options for sections with names that match regular expression :sup:`foo$. The options allowed here are foo, bar and baz. Config file like this:

[foo]
bar = 1
baz = 1
foo = 1

will generate no errors, because all options in section foo are allowed. Config file

[foo]
baaaar = 1
baz = 1
foo = 1

will result in errors being generated because there is an unknown option baaaar used in section foo.

The ini_allowed_options validator controls only sections that match regular expression specified in section_re. Other sections are ignored by the validator.

This validator is used to enumerate all allowed sections. The format is following.

[rule/enumerate_sections]
validator = ini_allowed_sections
section_re = regex1
section_re = regex2
.
.
.

section_re = regexN

The validator will generate error if the config file contains section that is not matched by any of the regular expressions specified by one of the section_re parameters.

External validators are specified using following structures:

struct ini_validator {
     const char *name;
     ini_validator_func *func;
};

The name attribute is sting that is used inside rules in the validator parameter. The func attribute is pointer to function of type ini_validator_func which is defined using typedef as following:

typedef int (ini_validator_func)(const char *rule_name,
                                 struct ini_cfgobj *rules_obj,
                                 struct ini_cfgobj *config_obj,
                                 struct ini_errobj *errobj);

This function has following parameters:

  • rule_name - this is name of rule that uses this validator (for example “rule/myrule”)

  • rules_obj - this is config object with all the rules

  • config_obj - this is config object with the actual configuration that is being checked by the rules

  • errobj - this ini_errobj structure used to propagate errors

Users of libini can specify array of struct ini_validator structures and pass them to ini_rules_check() function. After this they can be used in the same way as internal validators.

In order to take advantage of this feature in SSSD the constraint file will have to be created.

Unit tests in Ding libs. Integration and unit tests for SSSD.

Michal Židek mzidek@redhat.com