All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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: a86e91dd477cd5d55dde20e4551b37e5dd3fa34b $
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  */
26 RCSID("$Id: a86e91dd477cd5d55dde20e4551b37e5dd3fa34b $")
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  */
41 int 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  vp_map_t *map;
46 
47  char *to_store = NULL;
48 
49  to_store = talloc_asprintf(ctx, "&Cache-Expires = %" PRIu64 "\n&Cache-Created = %" PRIu64 "\n",
50  (uint64_t)c->expires, (uint64_t)c->created);
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 (!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  for (map = c->maps; map; map = map->next) {
67  char *value;
68  size_t len;
69 
70  len = tmpl_snprint(attr, sizeof(attr), map->lhs, map->lhs->tmpl_da);
71  if (is_truncated(len, sizeof(attr))) {
72  fr_strerror_printf("Serialized attribute too long. Must be < " STRINGIFY(sizeof(attr)) " "
73  "bytes, got %zu bytes", len);
74  goto error;
75  }
76 
77  value = value_data_asprint(value_pool, map->rhs->tmpl_data_type,
78  map->lhs->tmpl_da, &map->rhs->tmpl_data_value, '\'');
79  if (!value) goto error;
80 
81  to_store = talloc_asprintf_append_buffer(to_store, "%s %s %s\n", attr,
82  fr_int2str(fr_tokens_table, map->op, "<INVALID>"),
83  value);
84  if (!to_store) goto error;
85  }
86 finish:
87  talloc_free(value_pool);
88  *out = to_store;
89 
90  return 0;
91 }
92 
93 /** Converts a serialized cache entry back into a structure
94  *
95  * @param c Cache entry to populate (should already be allocated)
96  * @param in String representation of cache entry.
97  * @param inlen Length of string. May be < 0 in which case strlen will be
98  * used to calculate the length of the string.
99  * @return
100  * - 0 on success.
101  * - -1 on failure.
102  */
103 int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
104 {
105  vp_map_t **last = &c->maps;
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  vp_map_t *map = NULL;
114 
115  q = strchr(p, '\n');
116  if (!q) break; /* List should also be terminated with a \n */
117  *q = '\0';
118 
119  if (map_afrom_attr_str(c, &map, p,
122  fr_strerror_printf("Failed parsing pair: %s", p);
123  error:
124  talloc_free(map);
125  return -1;
126  }
127 
128  if (map->lhs->type != TMPL_TYPE_ATTR) {
129  fr_strerror_printf("Pair left hand side \"%s\" parsed as %s, needed attribute. "
130  "Check local dictionaries", map->lhs->name,
131  fr_int2str(tmpl_names, map->lhs->type, "<INVALID>"));
132  goto error;
133  }
134 
135  if (map->rhs->type != TMPL_TYPE_UNPARSED) {
136  fr_strerror_printf("Pair right hand side \"%s\" parsed as %s, needed literal. "
137  "Check serialized data quoting", map->rhs->name,
138  fr_int2str(tmpl_names, map->rhs->type, "<INVALID>"));
139  goto error;
140  }
141 
142  /*
143  * Convert literal to a type appropriate for the VP.
144  */
145  if (tmpl_cast_in_place(map->rhs, map->lhs->tmpl_da->type, map->lhs->tmpl_da) < 0) goto error;
146 
147  /*
148  * Pull out the special attributes, and set the
149  * relevant cache entry fields.
150  */
151  if (map->lhs->tmpl_da->vendor == 0) switch (map->lhs->tmpl_da->attr) {
152  case PW_CACHE_CREATED:
153  c->created = map->rhs->tmpl_data_value.date;
154  talloc_free(map);
155  goto next;
156 
157  case PW_CACHE_EXPIRES:
158  c->expires = map->rhs->tmpl_data_value.date;
159  talloc_free(map);
160  goto next;
161 
162  default:
163  break;
164  }
165 
166  /* It's not a special attribute, add it to the map list */
167  *last = map;
168  last = &(*last)->next;
169 
170  next:
171  p = q + 1;
172  }
173 
174  return 0;
175 }
Definition: rlm_cache.h:76
char const * name
Raw string used to create the template.
Definition: tmpl.h:190
vp_tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
Definition: map.h:47
Dictionary attribute.
Definition: tmpl.h:133
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
vp_tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
Definition: map.h:48
Unparsed literal string.
Definition: tmpl.h:131
const FR_NAME_NUMBER fr_tokens_table[]
Definition: token.c:30
static expr_map_t map[]
Definition: rlm_expr.c:169
struct vp_map * next
The next valuepair map.
Definition: map.h:55
#define is_truncated(_ret, _max)
Definition: libradius.h:204
time_t expires
When the entry expires.
Definition: rlm_cache.h:81
#define STRINGIFY(x)
Definition: build.h:34
Attributes in incoming or internally proxied request.
Definition: tmpl.h:82
The current request.
Definition: tmpl.h:113
tmpl_type_t type
What type of value tmpl refers to.
Definition: tmpl.h:188
time_t created
When the entry was created.
Definition: rlm_cache.h:80
int int map_afrom_attr_str(TALLOC_CTX *ctx, vp_map_t **out, char const *raw, request_refs_t dst_request_def, pair_lists_t dst_list_def, request_refs_t src_request_def, pair_lists_t src_list_def)
Convert a value pair string to valuepair map.
Definition: map.c:487
FR_TOKEN op
The operator that controls insertion of the dst attribute.
Definition: map.h:50
size_t tmpl_snprint(char *buffer, size_t bufsize, vp_tmpl_t const *vpt, fr_dict_attr_t const *values)
Print a vp_tmpl_t to a string.
Definition: tmpl.c:1822
void fr_strerror_printf(char const *,...) CC_HINT(format(printf
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
Definition: token.c:506
vp_map_t * maps
Head of the maps list.
Definition: rlm_cache.h:83
#define RCSID(id)
Definition: build.h:135
int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, fr_dict_attr_t const *enumv)
Convert vp_tmpl_t of type TMPL_TYPE_UNPARSED or TMPL_TYPE_DATA to TMPL_TYPE_DATA of type specified...
Definition: tmpl.c:1212
Value pair map.
Definition: map.h:46
char * value_data_asprint(TALLOC_CTX *ctx, PW_TYPE type, fr_dict_attr_t const *enumv, value_data_t const *data, char quote)
Print one attribute value to a string.
Definition: value.c:1543
int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
Converts a serialized cache entry back into a structure.
Definition: serialize.c:103
const FR_NAME_NUMBER tmpl_names[]
Map tmpl_type_t values to descriptive strings.
Definition: tmpl.c:36