From 6a5bc20fb4b9b34912c3dc77a815225347e74ebc Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Thu, 26 Jun 2014 08:17:30 -0400 Subject: [PATCH] Pass2 for attributes in existence checks if (&foo-LDAP-Group) { ... } --- src/main/modcall.c | 16 +++++++++++++++- src/main/parser.c | 44 +++++++++++++++++++++++++++++++++++++++++--- src/tests/unit/condition.txt | 8 ++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/main/modcall.c b/src/main/modcall.c index d106e09..e0e6536 100644 --- a/src/main/modcall.c +++ b/src/main/modcall.c @@ -2880,6 +2880,7 @@ static bool pass2_callback(UNUSED void *ctx, fr_cond_t *c) value_pair_map_t *map; if (c->type == COND_TYPE_EXISTS) { + if (c->data.vpt->type == VPT_TYPE_XLAT) { return pass2_xlat_compile(c->ci, &c->data.vpt, true); } @@ -2887,8 +2888,21 @@ static bool pass2_callback(UNUSED void *ctx, fr_cond_t *c) rad_assert(c->data.vpt->type != VPT_TYPE_REGEX); /* - * FIXME: fix up attribute references, too! + * The existence check might have been &Foo-Bar, + * where Foo-Bar is defined by a module. */ + if (c->pass2_fixup == PASS2_FIXUP_ATTR) { + value_pair_tmpl_t *vpt; + vpt = radius_str2tmpl(c, c->data.vpt->name, T_BARE_WORD, REQUEST_CURRENT, PAIR_LIST_REQUEST); + if (!vpt) { + cf_log_err(c->ci, "Unknown attribute '%s'", c->data.vpt->name + 1); + return false; + } + + talloc_free(c->data.vpt); + c->data.vpt = vpt; + c->pass2_fixup = PASS2_FIXUP_NONE; + } return true; } diff --git a/src/main/parser.c b/src/main/parser.c index 5ceaeed..e1e5581 100644 --- a/src/main/parser.c +++ b/src/main/parser.c @@ -472,7 +472,23 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st c->data.vpt = radius_str2tmpl(c, lhs, lhs_type, REQUEST_CURRENT, PAIR_LIST_REQUEST); if (!c->data.vpt) { - return_P("Failed creating exists"); + /* + * If strings are T_BARE_WORD and they start with '&', + * then they refer to attributes which have not yet been + * defined. Create the template(s) as literals, and + * fix them up in pass2. + */ + if ((*lhs != '&') || + (lhs_type != T_BARE_WORD)) { + return_P("Failed creating exists"); + } + c->data.vpt = radius_str2tmpl(c, lhs + 1, lhs_type, REQUEST_CURRENT, PAIR_LIST_REQUEST); + if (!c->data.vpt) { + return_P("Failed creating exists"); + } + rad_const_free(c->data.vpt->name); + c->data.vpt->name = talloc_strdup(c->data.vpt, lhs); + c->pass2_fixup = PASS2_FIXUP_ATTR; } rad_assert(c->data.vpt->type != VPT_TYPE_REGEX); @@ -628,7 +644,7 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st REQUEST_CURRENT, PAIR_LIST_REQUEST); if (!c->data.map) { /* - * FIXME: if strings are T_BARE_WORD and they start with '&', + * If strings are T_BARE_WORD and they start with '&', * then they refer to attributes which have not yet been * defined. Create the template(s) as literals, and * fix them up in pass2. @@ -1052,6 +1068,9 @@ done: /* * FOO =* BAR --> FOO * FOO !* BAR --> !FOO + * + * FOO may be a string, or a delayed attribute + * reference. */ if ((c->data.map->op == T_OP_CMP_TRUE) || (c->data.map->op == T_OP_CMP_FALSE)) { @@ -1182,6 +1201,11 @@ done: /* * Existence checks. We short-circuit static strings, * too. + * + * FIXME: the data types should be in the template, too. + * So that we know where a literal came from. + * + * "foo" is NOT the same as 'foo' or a bare foo. */ if (c->type == COND_TYPE_EXISTS) { switch (c->data.vpt->type) { @@ -1233,6 +1257,7 @@ done: } else if (lhs_type == T_BARE_WORD) { int rcode; + bool zeros = true; char const *q; for (q = c->data.vpt->name; @@ -1241,6 +1266,7 @@ done: if (!isdigit((int) *q)) { break; } + if (*q != '0') zeros = false; } /* @@ -1248,11 +1274,23 @@ done: * 'true'. */ if (!*q) { - c->type = COND_TYPE_TRUE; + if (zeros) { + c->type = COND_TYPE_TRUE; + } else { + c->type = COND_TYPE_TRUE; + } TALLOC_FREE(c->data.vpt); break; } + /* + * Allow &Foo-Bar where Foo-Bar is an attribute + * defined by a module. + */ + if (c->pass2_fixup == PASS2_FIXUP_ATTR) { + break; + } + rcode = fr_str2int(allowed_return_codes, c->data.vpt->name, 0); if (!rcode) { diff --git a/src/tests/unit/condition.txt b/src/tests/unit/condition.txt index b2f1aaf..90520ec 100644 --- a/src/tests/unit/condition.txt +++ b/src/tests/unit/condition.txt @@ -473,3 +473,11 @@ data &Tunnel-Password:1[0] == "Hello" condition &Tunnel-Password:1[3] == "Hello" data &Tunnel-Password:1[3] == "Hello" + +# +# This is allowed for pass2-fixups. Foo-Bar MAY be an attribute. +# If so allow it so that pass2 can fix it up. Until then, +# it's a literal. +# +condition &Foo-Bar +data '&Foo-Bar' -- 2.1.4