The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
serialize.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 80fed2ccc6acedda7039f89a6c2e86ad745bdd43 $
19 * @file serialize.c
20 * @brief Serialize and deserialise cache entries.
21 *
22 * @author Arran Cudbard-Bell
23 * @copyright 2014 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @copyright 2014 The FreeRADIUS server project
25 */
26RCSID("$Id: 80fed2ccc6acedda7039f89a6c2e86ad745bdd43 $")
27
28#include "rlm_cache.h"
29#include "serialize.h"
30
31/** Serialize a cache entry as a humanly readable string
32 *
33 * @param ctx to alloc new string in. Should be a talloc pool a little bigger
34 * than the maximum serialized size of the entry.
35 * @param out Where to write pointer to serialized cache entry.
36 * @param c Cache entry to serialize.
37 * @return
38 * - 0 on success.
39 * - -1 on failure.
40 */
41int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t const *c)
42{
43 TALLOC_CTX *value_pool = NULL;
44 char attr[256]; /* Attr name buffer */
45 map_t *map = NULL;
46
47 char *to_store = NULL;
48
49 to_store = fr_asprintf(ctx, "Cache-Expires = '%pV'\nCache-Created = '%pV'\n",
51 if (!to_store) return -1;
52
53 /*
54 * It's valid to have an empty cache entry (save allocing the pairs pool)
55 */
56 if (map_list_empty(&c->maps)) goto finish;
57
58 value_pool = talloc_pool(ctx, 512);
59 if (!value_pool) {
60 error:
61 talloc_free(to_store);
62 talloc_free(value_pool);
63 return -1;
64 }
65
66 while ((map = map_list_next(&c->maps, map))) {
67 char *value;
68 ssize_t slen;
69
70 slen = tmpl_print(&FR_SBUFF_OUT(attr, sizeof(attr)), map->lhs, TMPL_ATTR_REF_PREFIX_NO, NULL);
71 if (slen < 0) {
72 fr_strerror_printf("Serialized attribute too long. Must be < " STRINGIFY(sizeof(attr)) " "
73 "bytes, needed %zu additional bytes", (size_t)(slen * -1));
74 goto error;
75 }
76
78 if (!value) goto error;
79
80 to_store = talloc_asprintf_append_buffer(to_store, "%s %s %s\n", attr,
81 fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"),
82 value);
83 if (!to_store) goto error;
84 }
85finish:
86 talloc_free(value_pool);
87 *out = to_store;
88
89 return 0;
90}
91
92/** Converts a serialized cache entry back into a structure
93 *
94 * @param[in] request Current request
95 * @param[in] c Cache entry to populate (should already be allocated)
96 * @param[in] dict to use for unqualified attributes.
97 * @param[in] in String representation of cache entry.
98 * @param[in] inlen Length of string. May be < 0 in which case strlen will be
99 * used to calculate the length of the string.
100 * @return
101 * - 0 on success.
102 * - -1 on failure.
103 */
105{
106 char *p, *q;
107
108 if (inlen < 0) inlen = strlen(in);
109
110 p = in;
111
112 while (((size_t)(p - in)) < (size_t)inlen) {
113 map_t *map = NULL;
114 tmpl_rules_t parse_rules = {
115 .attr = {
116 .dict_def = dict,
117 .list_def = request_attr_request,
119 },
120 .xlat = {
121 .runtime_el = unlang_interpret_event_list(request),
122 },
123 .at_runtime = true,
124 };
125
126 q = strchr(p, '\n');
127 if (!q) break; /* List should also be terminated with a \n */
128 *q = '\0';
129
130 if (map_afrom_attr_str(c, &map, p, &parse_rules, &parse_rules) < 0) {
131 fr_strerror_printf("Failed parsing pair: %s", p);
132 error:
133 talloc_free(map);
134 return -1;
135 }
136
137 if (!tmpl_is_attr(map->lhs)) {
138 fr_strerror_printf("Pair left hand side \"%s\" parsed as %s, needed attribute. "
139 "Check local dictionaries", map->lhs->name,
140 tmpl_type_to_str(map->lhs->type));
141 goto error;
142 }
143
144 if (!tmpl_is_data(map->rhs)) {
145 fr_strerror_printf("Pair right hand side \"%s\" parsed as %s, needed literal. "
146 "Check serialized data quoting", map->rhs->name,
147 tmpl_type_to_str(map->rhs->type));
148 goto error;
149 }
150
151 /*
152 * Convert literal to a type appropriate for the VP.
153 */
154 if (tmpl_cast_in_place(map->rhs, tmpl_attr_tail_da(map->lhs)->type, tmpl_attr_tail_da(map->lhs)) < 0) goto error;
155
156 /*
157 * Pull out the special attributes, and set the
158 * relevant cache entry fields.
159 */
160 if (fr_dict_attr_is_top_level(tmpl_attr_tail_da(map->lhs))) switch (tmpl_attr_tail_da(map->lhs)->attr) {
161 case FR_CACHE_CREATED:
162 c->created = tmpl_value(map->rhs)->vb_date;
163 talloc_free(map);
164 goto next;
165
166 case FR_CACHE_EXPIRES:
167 c->expires = tmpl_value(map->rhs)->vb_date;
168 talloc_free(map);
169 goto next;
170
171 default:
172 break;
173 }
174
175 MAP_VERIFY(map);
176
177 /* It's not a special attribute, add it to the map list */
178 map_list_insert_tail(&c->maps, map);
179
180 next:
181 p = q + 1;
182 }
183
184 return 0;
185}
#define RCSID(id)
Definition build.h:483
#define STRINGIFY(x)
Definition build.h:197
static bool fr_dict_attr_is_top_level(fr_dict_attr_t const *da)
Return true if this attribute is parented directly off the dictionary root.
Definition dict.h:757
static fr_slen_t in
Definition dict.h:824
Test enumeration values.
Definition dict_test.h:92
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:1764
int map_afrom_attr_str(TALLOC_CTX *ctx, map_t **out, char const *vp_str, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules)
Convert a value pair string to valuepair map.
Definition map.c:1319
talloc_free(reap)
#define MAP_VERIFY(_x)
Definition map.h:108
@ TMPL_ATTR_REF_PREFIX_NO
Attribute refs have no '&' prefix.
fr_slen_t tmpl_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t ar_prefix, fr_sbuff_escape_rules_t const *e_rules)
long int ssize_t
char * fr_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Special version of asprintf which implements custom format specifiers.
Definition print.c:874
fr_dict_attr_t const * request_attr_request
Definition request.c:45
map_list_t maps
Head of the maps list.
Definition rlm_cache.h:78
fr_unix_time_t created
When the entry was created.
Definition rlm_cache.h:75
fr_unix_time_t expires
When the entry expires.
Definition rlm_cache.h:76
Definition rlm_cache.h:72
#define FR_SBUFF_OUT(_start, _len_or_end)
int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t const *c)
Serialize a cache entry as a humanly readable string.
Definition serialize.c:41
int cache_deserialize(request_t *request, rlm_cache_entry_t *c, fr_dict_t const *dict, char *in, ssize_t inlen)
Converts a serialized cache entry back into a structure.
Definition serialize.c:104
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
Definition tmpl.h:645
#define tmpl_value(_tmpl)
Definition tmpl.h:948
#define tmpl_is_attr(vpt)
Definition tmpl.h:213
int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv))
Convert tmpl_t of type TMPL_TYPE_DATA_UNRESOLVED or TMPL_TYPE_DATA to TMPL_TYPE_DATA of type specifie...
#define tmpl_is_data(vpt)
Definition tmpl.h:211
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:344
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition tmpl.h:812
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:341
Value pair map.
Definition map.h:77
fr_token_t op
The operator that controls insertion of the dst attribute.
Definition map.h:82
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
Definition map.h:78
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
Definition map.h:79
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:285
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
fr_table_num_ordered_t const fr_tokens_table[]
Definition token.c:33
@ T_DOUBLE_QUOTED_STRING
Definition token.h:121
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
static size_t char fr_sbuff_t size_t inlen
Definition value.h:997
static fr_slen_t static e_rules fr_slen_t fr_value_box_aprint_quoted(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_token_t quote) 1(fr_value_box_print_quoted
static size_t char ** out
Definition value.h:997
#define fr_box_date(_val)
Definition value.h:324