]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
parse precision for attributes of type 'date'
authorAlan T. DeKok <aland@freeradius.org>
Tue, 21 May 2019 14:58:05 +0000 (10:58 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 21 May 2019 14:58:05 +0000 (10:58 -0400)
src/lib/util/dict.c
src/lib/util/dict.h

index 37f1f4f273c996c5e0e4203335c63c6256f9cb3d..7a20d5bb9bd0410d48625a96fe19e98d069f18b8 100644 (file)
@@ -177,6 +177,15 @@ bool const fr_dict_non_data_types[FR_TYPE_MAX + 1] = {
        [FR_TYPE_VENDOR] = true
 };
 
+static FR_NAME_NUMBER const date_precision_table[] = {
+       { "seconds",            DATE_SECONDS },
+       { "milliseconds",       DATE_MILLISECONDS },
+       { "microseconds",       DATE_MICROSECONDS },
+       { "nanoseconds",        DATE_NANOSECONDS },
+
+       { NULL,                 0 }
+};
+
 /*
  *     Create the hash of the name.
  *
@@ -844,6 +853,15 @@ static bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent
                                   fr_int2str(fr_value_box_type_table, type, "?Unknown?"));
                return false;
 
+       case FR_TYPE_DATE:
+               if (flags->type_size > DATE_NANOSECONDS) {
+                       fr_strerror_printf("Invalid precision '%d' for attribute of type 'date'",
+                                          flags->type_size);
+                       return false;
+               }
+               break;
+
+
        default:
                break;
        }
@@ -3908,7 +3926,7 @@ static int dict_process_type_field(char const *name, fr_type_t *type_p, fr_dict_
 }
 
 
-static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_dict_attr_t const **ref_p, fr_dict_attr_flags_t *flags)
+static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_type_t type, fr_dict_attr_t const **ref_p, fr_dict_attr_flags_t *flags)
 {
        char *p, *q, *v;
        fr_dict_attr_t const *ref = NULL;
@@ -3988,6 +4006,16 @@ static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_dic
 
                        *ref_p = ref;
 
+               } else if (type == FR_TYPE_DATE) {
+                       int precision;
+
+                       precision = fr_str2int(date_precision_table, key, -1);
+                       if (precision < 0) {
+                               fr_strerror_printf("Unknown date precision '%s'", key);
+                               return -1;
+                       }
+                       flags->type_size = precision;
+
                } else {
                        fr_strerror_printf("Unknown option '%s'", key);
                        return -1;
@@ -4083,7 +4111,7 @@ get_by_oid:
        /*
         *      Parse options.
         */
-       if ((argc >= 4) && (dict_process_flag_field(ctx, argv[3], &ref, &flags) < 0)) return -1;
+       if ((argc >= 4) && (dict_process_flag_field(ctx, argv[3], type, &ref, &flags) < 0)) return -1;
 
 #ifdef WITH_DICTIONARY_WARNINGS
        /*
@@ -4164,7 +4192,7 @@ static int dict_read_process_member(dict_from_file_ctx_t *ctx, char **argv, int
        /*
         *      Parse options.
         */
-       if ((argc >= 3) && (dict_process_flag_field(ctx, argv[2], NULL, &flags) < 0)) return -1;
+       if ((argc >= 3) && (dict_process_flag_field(ctx, argv[2], type, NULL, &flags) < 0)) return -1;
 
 #ifdef __clang_analyzer__
        if (!ctx->dict) return -1;
index 78b701229433b3f0b03721d33fb58a0b33dc00d9..ded81b694a9bc8e7a5cb19c0a78884fb22337019 100644 (file)
@@ -85,6 +85,11 @@ typedef struct {
 extern const size_t dict_attr_sizes[FR_TYPE_MAX + 1][2];
 extern fr_dict_t *fr_dict_internal;
 
+#define DATE_SECONDS           (0)
+#define DATE_MILLISECONDS      (1)
+#define DATE_MICROSECONDS      (2)
+#define DATE_NANOSECONDS       (3)
+
 /** Dictionary attribute
  */
 struct dict_attr {