Skip to content
Permalink
Browse files

add "len" to tmpl_from_attr_substr()

so that we can call it on pre-parsed data, and so that it
doesn't do strlen()
  • Loading branch information
alandekok committed Aug 25, 2019
1 parent 560ae9e commit ea5c1537bcb6c084ae273647366734f61fb4e64b
@@ -593,6 +593,7 @@ static vp_tmpl_rules_t const default_rules = {
* @param[in] name of attribute including #request_ref_t and #pair_list_t qualifiers.
* If only #request_ref_t #pair_list_t qualifiers are found,
* a #TMPL_TYPE_LIST #vp_tmpl_t will be produced.
* @param[in] name_len Length of name, or -1 to do strlen()
* @param[in] rules Rules which control parsing:
* - dict_def The default dictionary to use if attributes
* are unqualified.
@@ -628,7 +629,7 @@ static vp_tmpl_rules_t const default_rules = {
* - > 0 on success (number of bytes parsed).
*/
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,
vp_tmpl_t **out, char const *name, vp_tmpl_rules_t const *rules)
vp_tmpl_t **out, char const *name, ssize_t name_len, vp_tmpl_rules_t const *rules)
{
char const *p, *q;
long num;
@@ -639,6 +640,8 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,

if (err) *err = ATTR_REF_ERROR_NONE;

if (name_len < 0) name_len = strlen(name);

p = name;

if (!*p) {
@@ -727,6 +730,14 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,
vpt->tmpl_num = NUM_ANY;
vpt->type = TMPL_TYPE_ATTR;

/*
* No more input after parsing the list ref, we're done.
*/
if (p == (name + name_len)) {
vpt->type = TMPL_TYPE_LIST;
goto finish;
}

/*
* This may be just a bare list, but it can still
* have instance selectors and tag selectors.
@@ -800,7 +811,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,
* Copy the name to a field for later resolution
*/
vpt->type = TMPL_TYPE_ATTR_UNDEFINED;
for (q = p; fr_dict_attr_allowed_chars[(uint8_t) *q]; q++);
for (q = p; (q < (name + name_len)) && fr_dict_attr_allowed_chars[(uint8_t) *q]; q++);
if (q == p) {
fr_strerror_printf("Invalid attribute name");
if (err) *err = ATTR_REF_ERROR_INVALID_ATTRIBUTE_NAME;
@@ -1001,16 +1012,17 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, attr_ref_error_t *err,
vp_tmpl_t **out, char const *name, vp_tmpl_rules_t const *rules)
{
ssize_t slen;
ssize_t slen, name_len;

if (!rules) rules = &default_rules; /* Use the defaults */

slen = tmpl_afrom_attr_substr(ctx, err, out, name, rules);
name_len = strlen(name);
slen = tmpl_afrom_attr_substr(ctx, err, out, name, name_len, rules);
if (slen <= 0) return slen;

if (!fr_cond_assert(*out)) return -1;

if (slen != (ssize_t)strlen(name)) {
if (slen != name_len) {
/* This looks wrong, but it produces meaningful errors for unknown attrs with tags */
fr_strerror_printf("Unexpected text after %s", fr_table_str_by_value(tmpl_type_table, (*out)->type, "<INVALID>"));
return -slen;
@@ -1130,7 +1142,7 @@ ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out,
* We can't define a template with garbage after
* the attribute name.
*/
slen = tmpl_afrom_attr_substr(ctx, NULL, &vpt, in, &mrules);
slen = tmpl_afrom_attr_substr(ctx, NULL, &vpt, in, inlen, &mrules);
if (mrules.allow_undefined && (slen <= 0)) return slen;
if (slen > 0) {
if ((size_t) slen < inlen) {
@@ -462,7 +462,7 @@ void tmpl_from_da(vp_tmpl_t *vpt, fr_dict_attr_t const *da, int8_t tag, int nu
int tmpl_afrom_value_box(TALLOC_CTX *ctx, vp_tmpl_t **out, fr_value_box_t *data, bool steal);

ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err,
vp_tmpl_t **out, char const *name,
vp_tmpl_t **out, char const *name, ssize_t name_len,
vp_tmpl_rules_t const *rules);

ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, attr_ref_error_t *err,
@@ -1692,7 +1692,7 @@ static ssize_t xlat_func_explode(TALLOC_CTX *ctx, char **out, size_t outlen,
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(ctx, NULL, &vpt, p, &(vp_tmpl_rules_t){ .dict_def = request->dict });
slen = tmpl_afrom_attr_substr(ctx, NULL, &vpt, p, -1, &(vp_tmpl_rules_t){ .dict_def = request->dict });
if (slen <= 0) {
RPEDEBUG("Invalid input");
return -1;
@@ -1923,7 +1923,7 @@ static ssize_t parse_pad(vp_tmpl_t **vpt_p, size_t *pad_len_p, char *pad_char_p,
return 0;
}

slen = tmpl_afrom_attr_substr(request, NULL, &vpt, p, &(vp_tmpl_rules_t){ .dict_def = request->dict });
slen = tmpl_afrom_attr_substr(request, NULL, &vpt, p, -1, &(vp_tmpl_rules_t){ .dict_def = request->dict });
if (slen <= 0) {
RPEDEBUG("Failed parsing input string");
return slen;
@@ -327,7 +327,7 @@ static inline ssize_t xlat_tokenize_attribute(TALLOC_CTX *ctx, xlat_exp_t **head

our_rules.allow_undefined = true; /* So we can check for virtual attributes later */
our_rules.prefix = VP_ATTR_REF_PREFIX_NO; /* Must be NO to stop %{&User-Name} */
slen = tmpl_afrom_attr_substr(NULL, &err, &vpt, p, &our_rules);
slen = tmpl_afrom_attr_substr(NULL, &err, &vpt, p, -1, &our_rules);
if (slen <= 0) {
/*
* If the parse error occurred before the ':'
@@ -49,7 +49,7 @@ static ssize_t sim_xlat_id_method(TALLOC_CTX *ctx, char **out, UNUSED size_t out
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -103,7 +103,7 @@ static ssize_t sim_xlat_id_type(TALLOC_CTX *ctx, char **out, UNUSED size_t outle
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -156,7 +156,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_key_index(TALLOC_CTX *ctx, char **out, UN
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -204,7 +204,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_decrypt(TALLOC_CTX *ctx, char **out, UNUS
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -223,7 +223,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_decrypt(TALLOC_CTX *ctx, char **out, UNUS
}
p++;

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -316,7 +316,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_encrypt(TALLOC_CTX *ctx, char **out, UNUS
*/
fr_skip_spaces(p);

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -335,7 +335,7 @@ static ssize_t sim_xlat_3gpp_pseudonym_encrypt(TALLOC_CTX *ctx, char **out, UNUS
}
p++;

slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, p,
slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, p, -1,
&(vp_tmpl_rules_t){
.dict_def = request->dict,
.prefix = VP_ATTR_REF_PREFIX_AUTO
@@ -0,0 +1,23 @@
# Modules to fix for namespace

Some modules need an explicit `dict` pointer.

Other modules use xlat's, etc. which need to have a dict / namespace set.

We MAY need to add a `namespace = ...` config to EVERY module. <sigh>
It would be much preferable to just get the namespace from where the
module is being referenced.

The daemon parses the config, and then bootstraps the modules *before*
the virtual servers. So we can't say "hey, this module is used from
virtual server X, let's go figure out it's namespace!"

* attr_filter
* files
* detail
* cache
* get dict into TYPE_TMPL config file parsing
* exec
* passwd
* radutmp
* linelog
@@ -0,0 +1,10 @@
# TO DO

Add `leftover` argument to `mod_write()`. So the caller knows if the
data has been partially written. That way all of the pending / retry
code is handled in `network.c`.

This change will substantially simplify the writers.

* EWOULDBLOCK, network side retries whole packet
* `leftover != 0`, network side localizes message, and retries at a later time.
@@ -0,0 +1,12 @@
# TODO

* add config file items for
recv_type = { accounting, preacct, etc.}
send_type

* code
for packet processing request->packet->code

# DONE

* priority is now set manually

0 comments on commit ea5c153

Please sign in to comment.
You can’t perform that action at this time.