]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
added ON_READ for parsing callback functions when reading files
authorAlan T. DeKok <aland@freeradius.org>
Mon, 7 May 2018 12:17:54 +0000 (08:17 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 7 May 2018 12:17:54 +0000 (08:17 -0400)
src/include/cf_parse.h
src/main/cf_parse.c
src/main/cf_priv.h
src/main/cf_util.c

index c6cad06cc7c89247ef7cf3d7a1d0d0ef4567e3a7..2e2e36ba97ce3b5557a31285a9dfc1ae73fcfdfa 100644 (file)
@@ -311,6 +311,7 @@ _Generic((_ct), \
                                                                        //!< left as the default to is_set_offset
                                                                        //!< or is_set_ptr.
 #define FR_TYPE_OK_MISSING                     (1 << 22)                       //!< OK if it's missing
+#define FR_TYPE_ON_READ                (1 << 23)                       //!< run the parse callback during the file read phase
 
 #define FR_BASE_TYPE(_t)               (0xff & (_t))
 /* @} **/
index eba5fbab85a1291de7b987b38091616a780808be..8cdf29432bd53df46015fc74acca30149c882b4b 100644 (file)
@@ -130,6 +130,7 @@ static int CC_HINT(nonnull(2, 3, 4)) cf_pair_parse_value(TALLOC_CTX *ctx, void *
 
        rad_assert(cp);
        rad_assert(!(type & FR_TYPE_ATTRIBUTE) || tmpl);         /* Attribute flag only valid for templates */
+       rad_assert((type & FR_TYPE_ON_READ) == 0);
 
        if (required) cant_be_empty = true;             /* May want to review this in the future... */
 
@@ -1104,6 +1105,11 @@ int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
 
                rule = cf_data_value(rule_cd);
 
+               /*
+                *      Ignore ON_READ parse rules
+                */
+               if ((rule->type & FR_TYPE_ON_READ) != 0) continue;
+
                /*
                 *      Pre-allocate the config structure to hold default values
                 */
@@ -1428,7 +1434,7 @@ int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const
         */
        if (!_cf_data_add_static(CF_TO_ITEM(cs), rule, "CONF_PARSER", rule->name, filename, lineno)) {
                CONF_DATA const *cd;
-               CONF_PARSER const *old;
+               CONF_PARSER *old;
 
                cd = cf_data_find(CF_TO_ITEM(cs), CONF_PARSER, rule->name);
                old = cf_data_value(cd);
@@ -1441,6 +1447,22 @@ int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const
                        return 0;
                }
 
+               /*
+                *      Remove any ON_READ callbacks, and add the new
+                *      rule in its place.
+                */
+               if ((old->type & FR_TYPE_ON_READ) != 0) {
+                       (void) cf_remove(CF_TO_ITEM(cs), CF_TO_ITEM(cd));
+                       talloc_const_free(cd);
+
+                       if (!_cf_data_add_static(CF_TO_ITEM(cs), rule, "CONF_PARSER", rule->name, filename, lineno)) {
+                               cf_log_err(cs, "Failed adding rule '%s'", rule->name);
+                               cf_debug(cs);
+                               return -1;
+                       }
+                       return 0;
+               }
+
                /*
                 *      If we have a duplicate sub-section, just
                 *      recurse and add the new sub-rules to the
index d0194a3f66d22aa11d558fb780c4e2c2fd28a781..c6956e5a1147d8ef94fa0057b5b5a1cbff6d8acd 100644 (file)
@@ -144,6 +144,8 @@ typedef struct cf_file_t {
        struct stat             buf;
 } cf_file_t;
 
+CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child);
+
 #ifdef __cplusplus
 }
 #endif
index e228e3561981bca064b9fc680941b24a450ed6d4..b7e4f74168b4086bf701d6a49bbbb119c415c5eb 100644 (file)
@@ -395,7 +395,7 @@ void _cf_item_add(CONF_ITEM *parent, CONF_ITEM *child)
  *     - The item removed.
  *     - NULL if the item wasn't set.
  */
-static CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child)
+CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child)
 {
        CONF_ITEM       *found;
        bool            in_ident1, in_ident2;