if (FR_BASE_TYPE(call_env->type) == FR_TYPE_SUBSECTION) {
CONF_SECTION const *subcs;
subcs = cf_section_find(cs, call_env->name, call_env->section.ident2);
- if (!subcs) goto next;
+ if (!subcs) {
+ if (!call_env->section.required) goto next;
+ cf_log_err(cs, "Module %s missing required section %s", name, call_env->name);
+ return -1;
+ }
if (call_env_parse(ctx, parsed, name, dict_def, subcs, call_env->section.subcs) < 0) return -1;
goto next;
struct {
char const *ident2; //!< Second identifier for a section
call_env_t const *subcs; //!< Nested definitions for subsection.
+ bool required; //!< Section is required.
} section;
};
};
.type = CALL_ENV_TYPE_TMPL_ONLY, \
.tmpl_offset = offsetof(_struct, _tmpl_field) }
-#define FR_CALL_ENV_SUBSECTION(_name, _ident2, _subcs ) \
+#define FR_CALL_ENV_SUBSECTION(_name, _ident2, _subcs, _required ) \
.name = _name, \
.type = FR_TYPE_SUBSECTION, \
.section = { .ident2 = _ident2, \
- .subcs = _subcs }
+ .subcs = _subcs, \
+ .required = _required }
int call_env_parse(TALLOC_CTX *ctx, call_env_parsed_head_t *parsed, char const *name, fr_dict_t const *dict_def,
CONF_SECTION const *cs, call_env_t const *call_env) CC_HINT(nonnull);
CALL_ENV_TERMINATOR \
}
-user_call_env(auth, ldap_auth_call_env_t, { FR_CALL_ENV_SUBSECTION("sasl", NULL, sasl_call_env) },
+user_call_env(auth, ldap_auth_call_env_t, { FR_CALL_ENV_SUBSECTION("sasl", NULL, sasl_call_env, false) },
{ FR_CALL_ENV_TMPL_OFFSET("password_attribute", FR_TYPE_STRING | FR_TYPE_ATTRIBUTE, ldap_auth_call_env_t, password,
password_tmpl, "&User-Password", T_BARE_WORD, true, true, true) } );
* Method specific call environments
*/
static const call_env_t authenticate_call_env[] = {
- { FR_CALL_ENV_SUBSECTION("user", NULL, auth_user_call_env) },
+ { FR_CALL_ENV_SUBSECTION("user", NULL, auth_user_call_env, true) },
CALL_ENV_TERMINATOR
};
static const call_env_t authorize_call_env[] = {
- { FR_CALL_ENV_SUBSECTION("user", NULL, autz_user_call_env) },
- { FR_CALL_ENV_SUBSECTION("group", NULL, autz_group_call_env) },
- { FR_CALL_ENV_SUBSECTION("profile", NULL, autz_profile_call_env) },
+ { FR_CALL_ENV_SUBSECTION("user", NULL, autz_user_call_env, true) },
+ { FR_CALL_ENV_SUBSECTION("group", NULL, autz_group_call_env, false) },
+ { FR_CALL_ENV_SUBSECTION("profile", NULL, autz_profile_call_env, false) },
CALL_ENV_TERMINATOR
};
static const call_env_t usermod_call_env[] = {
- { FR_CALL_ENV_SUBSECTION("user", NULL, usermod_user_call_env) },
+ { FR_CALL_ENV_SUBSECTION("user", NULL, usermod_user_call_env, true) },
CALL_ENV_TERMINATOR
};
static const call_env_t memberof_call_env[] = {
- { FR_CALL_ENV_SUBSECTION("user", NULL, memberof_user_call_env) },
- { FR_CALL_ENV_SUBSECTION("group", NULL, memberof_group_call_env) },
+ { FR_CALL_ENV_SUBSECTION("user", NULL, memberof_user_call_env, true) },
+ { FR_CALL_ENV_SUBSECTION("group", NULL, memberof_group_call_env, false) },
CALL_ENV_TERMINATOR
};