}
-#include <freeradius-devel/server/modpriv.h>
-
-/*
- * %{poke:sql.foo=bar}
- */
-static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen,
- UNUSED void const *inst, UNUSED void const *xlat_inst,
- REQUEST *request, char const *fmt)
-{
- int i;
- void *data, *base;
- char *p, *q;
- module_instance_t *mod_inst;
- char *buffer;
- CONF_SECTION *modules;
- CONF_PAIR *cp;
- CONF_PARSER const *variables;
- size_t len;
-
- rad_assert(outlen > 1);
- rad_assert(request != NULL);
- rad_assert(fmt != NULL);
- rad_assert(out != NULL);
- rad_assert(*out);
-
- modules = cf_section_find(request->config->root_cs, "modules", NULL);
- if (!modules) return 0;
-
- buffer = talloc_strdup(request, fmt);
- if (!buffer) return 0;
-
- p = strchr(buffer, '.');
- if (!p) return 0;
-
- *(p++) = '\0';
-
- mod_inst = module_find(modules, buffer);
- if (!mod_inst) {
- RDEBUG("Failed finding module '%s'", buffer);
- fail:
- talloc_free(buffer);
- return 0;
- }
-
- q = strchr(p, '=');
- if (!q) {
- RDEBUG("Failed finding '=' in string '%s'", fmt);
- goto fail;
- }
-
- *(q++) = '\0';
-
- if (strchr(p, '.') != NULL) {
- RDEBUG("Can't do sub-sections right now");
- goto fail;
- }
-
- cp = cf_pair_find(mod_inst->dl_inst->conf, p);
- if (!cp) {
- RDEBUG("No such item '%s'", p);
- goto fail;
- }
-
- /*
- * Copy the old value to the output buffer, that way
- * tests can restore it later, if they need to.
- */
- len = strlcpy(*out, cf_pair_value(cp), outlen);
-
- if (cf_pair_replace(mod_inst->dl_inst->conf, cp, q) < 0) {
- RDEBUG("Failed replacing pair");
- goto fail;
- }
-
- base = mod_inst->dl_inst->data;
- variables = mod_inst->dl_inst->module->common->config;
-
- /*
- * Handle the known configuration parameters.
- */
- for (i = 0; variables[i].name != NULL; i++) {
- int ret;
- char const *quote;
-
- if (FR_BASE_TYPE(variables[i].type) == FR_TYPE_SUBSECTION) continue;
- /* else it's a CONF_PAIR */
-
- /*
- * Not the pair we want. Skip it.
- */
- if (strcmp(variables[i].name, p) != 0) continue;
-
- if (variables[i].data) {
- data = variables[i].data; /* prefer this. */
- } else if (base) {
- data = ((char *)base) + variables[i].offset;
- } else {
- DEBUG2("Internal sanity check 2 failed in cf_section_parse");
- goto fail;
- }
-
- /*
- * Parse the pair we found, or a default value.
- */
- ret = cf_pair_parse(ctx, mod_inst->dl_inst->conf, variables[i].name, variables[i].type,
- data, variables[i].dflt, variables[i].quote);
- if (ret < 0) {
- DEBUG2("Failed inserting new value into module instance data");
- goto fail;
- }
-
- quote = fr_int2str(fr_token_quotes_table, variables[i].quote, "<INVALID>");
-
- DEBUG2("Setting config item to %s = %s%s%s", variables[i].name, quote, q, quote);
-
- break; /* we found it, don't do any more */
- }
-
- talloc_free(buffer);
-
- return len;
-}
-
-
/*
* Read a file compose of xlat's and expected results
*/
}
#endif
- if (xlat_register(NULL, "poke", xlat_poke, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true) < 0) {
- rcode = EXIT_FAILURE;
- goto finish;
- }
-
if (map_proc_register(NULL, "test-fail", mod_map_proc, map_proc_verify, 0) < 0) {
rcode = EXIT_FAILURE;
goto finish;
typedef struct rlm_always_t {
char const *name; //!< Name of this instance of the always module.
char const *rcode_str; //!< The base value.
- char const *rcode_old; //!< Make changing the rcode work with %{poke:} and radmin.
rlm_rcode_t rcode; //!< The integer constant representing rcode_str.
uint32_t simulcount;
cf_log_err(conf, "rcode value \"%s\" is invalid", inst->rcode_str);
return -1;
}
- inst->rcode_old = NULL; /* Hack - forces the compiler not to optimise away rcode_old */
return 0;
}
-/** Reparse the rcode if it changed
- *
- * @note Look ma, no locks...
- *
- * @param inst Module instance.
- */
-static void reparse_rcode(rlm_always_t *inst)
-{
- rlm_rcode_t rcode;
-
- rcode = fr_str2int(mod_rcode_table, inst->rcode_str, RLM_MODULE_UNKNOWN);
- if (rcode == RLM_MODULE_UNKNOWN) {
- WARN("Ignoring rcode change. rcode value \"%s\" is invalid ", inst->rcode_str);
- return;
- }
-
- inst->rcode = rcode;
- inst->rcode_old = inst->rcode_str;
-}
-
/*
* Just return the rcode ... this function is autz, auth, acct, and
* preacct!
{
rlm_always_t *inst = instance;
- if (inst->rcode_old != inst->rcode_str) reparse_rcode(inst);
-
return inst->rcode;
}