1 /* 2 * This program 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 5 * (at 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 #ifndef TMPL_H 17 #define TMPL_H 18 /** 19 * $Id: 92884b186bddef23432c4ad74bd1dc1d10c6466c $ 20 * 21 * @file tmpl.h 22 * @brief Structures and prototypes for templates 23 * 24 * These functions are used to work with #vp_tmpl_t structs. 25 * 26 * #vp_tmpl_t (VPTs) specify either a data source, or a data sink. 27 * 28 * Examples of sources are #TMPL_TYPE_XLAT, #TMPL_TYPE_EXEC and #TMPL_TYPE_ATTR. 29 * Examples of sinks are #TMPL_TYPE_ATTR, #TMPL_TYPE_LIST. 30 * 31 * VPTs are used to gather values or attributes for evaluation, or copying, and to specify 32 * where values or #VALUE_PAIR should be copied to. 33 * 34 * To create new #vp_tmpl_t use one of the tmpl_*from_* functions. These parse 35 * strings into VPTs. The main parsing function is #tmpl_afrom_str, which can produce 36 * most types of VPTs. It uses the type of quoting (passed as an #FR_TOKEN) to determine 37 * what type of VPT to parse the string as. For example a #T_DOUBLE_QUOTED_STRING will 38 * produce either a #TMPL_TYPE_XLAT or a #TMPL_TYPE_LITERAL (depending if the string 39 * contained a non-literal expansion). 40 * 41 * @see tmpl_afrom_str 42 * @see tmpl_afrom_attr_str 43 * @see tmpl_from_attr_str 44 * @see tmpl_from_attr_substr 45 * 46 * In the case of #TMPL_TYPE_ATTR and #TMPL_TYPE_LIST, there are special cursor overlay 47 * functions which can be used to iterate over only the #VALUE_PAIR that match a 48 * vp_tmpl_t in a given list. 49 * 50 * @see tmpl_cursor_init 51 * @see tmpl_cursor_next 52 * 53 * Or for simplicity, there are functions which wrap the cursor functions, to copy or 54 * return the #VALUE_PAIR that match the VPT. 55 * 56 * @see tmpl_copy_vps 57 * @see tmpl_find_vp 58 * 59 * If you just need the string value of whatever the VPT refers to, the tmpl_*expand 60 * functions may be used. These functions evaluate the VPT, execing, and xlat expanding 61 * as necessary. In the case of #TMPL_TYPE_ATTR, and #PW_TYPE_STRING or #PW_TYPE_OCTETS 62 * #tmpl_expand will return a pointer to the raw #VALUE_PAIR buffer. This can be very 63 * useful when using the #PW_TYPE_TMPL type in #CONF_PARSER structs, as it allows the 64 * user to determine whether they want the module to sanitise the value using presentation 65 * format specific #xlat_escape_t function, or to operate on the raw value. 66 * 67 * @see tmpl_expand 68 * @see tmpl_aexpand 69 * 70 * @copyright 2014-2015 The FreeRADIUS server project 71 */ 72 73 RCSIDH(tmpl_h, "$Id: 92884b186bddef23432c4ad74bd1dc1d10c6466c $") 74 75 #include <freeradius-devel/xlat.h> 76 77 #ifdef __cplusplus 78 extern "C" { 79 #endif 80 # 81 typedef enum pair_lists { 82 PAIR_LIST_UNKNOWN = 0, //!< Unknown list. 83 PAIR_LIST_REQUEST, //!< Attributes in incoming or internally proxied 84 ///< request. 85 PAIR_LIST_REPLY, //!< Attributes to send in the response. 86 PAIR_LIST_CONTROL, //!< Attributes that change the behaviour of 87 ///< modules. 88 PAIR_LIST_STATE, //!< Attributes to store multiple rounds of 89 ///< challenges/responses. 90 #ifdef WITH_PROXY 91 PAIR_LIST_PROXY_REQUEST, //!< A copy of attributes in the request list 92 ///< that may be modified in pre-proxy before 93 //!< proxying the request. 94 PAIR_LIST_PROXY_REPLY, //!< Attributes sent in response to the proxied 95 ///< request. 96 #endif 97 #ifdef WITH_COA 98 PAIR_LIST_COA, //!< Attributes to send in a forked CoA-Request. 99 PAIR_LIST_COA_REPLY, //!< Attributes sent in response to the forked 100 ///< CoA-Request. 101 PAIR_LIST_DM, //!< Attributes to send in a forked Disconnect-Request. 102 PAIR_LIST_DM_REPLY //!< Attributes sent in response to the forked 103 //!< Disconnect-Request. 104 #endif 105 } pair_lists_t; 106 107 extern const FR_NAME_NUMBER pair_lists[]; 108 109 typedef enum requests { 110 REQUEST_UNKNOWN = 0, //!< Unknown request. 111 REQUEST_OUTER, //!< #REQUEST containing the outer layer of the EAP 112 //!< conversation. Usually the RADIUS request sent 113 //!< by the NAS. 114 REQUEST_CURRENT, //!< The current request. 115 REQUEST_PARENT //!< Not currently used. 116 } request_refs_t; 117 118 extern const FR_NAME_NUMBER request_refs[]; 119 120 typedef struct pair_list { 121 char const *name; 122 VALUE_PAIR *check; 123 VALUE_PAIR *reply; 124 int order; /* for ordering! */ 125 int lineno; 126 struct pair_list *next; 127 } PAIR_LIST; 128 129 /** Types of #vp_tmpl_t 130 */ 131 typedef enum tmpl_type { 132 TMPL_TYPE_UNKNOWN = 0, //!< Uninitialised. 133 TMPL_TYPE_LITERAL, //!< Literal string. 134 TMPL_TYPE_XLAT, //!< XLAT expansion. 135 TMPL_TYPE_ATTR, //!< Dictionary attribute. 136 TMPL_TYPE_ATTR_UNDEFINED, //!< Attribute not found in the global dictionary. 137 TMPL_TYPE_LIST, //!< Attribute list. 138 TMPL_TYPE_REGEX, //!< Regular expression. 139 TMPL_TYPE_EXEC, //!< Callout to an external script or program. 140 TMPL_TYPE_DATA, //!< Value in native format. 141 TMPL_TYPE_XLAT_STRUCT, //!< Pre-parsed XLAT expansion. 142 TMPL_TYPE_REGEX_STRUCT, //!< Pre-parsed regular expression. 143 TMPL_TYPE_NULL //!< Has no value. 144 } tmpl_type_t; 145 146 extern const FR_NAME_NUMBER tmpl_names[]; 147 148 /** Describes a #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNDEFINED or #TMPL_TYPE_LIST 149 */ 150 typedef struct { 151 request_refs_t request; //!< Request to search or insert in. 152 pair_lists_t list; //!< List to search or insert in. 153 154 DICT_ATTR const *da; //!< Resolved dictionary attribute. 155 union { 156 uint8_t da[DICT_ATTR_SIZE]; //!< Unknown dictionary attribute buffer. 157 char name[DICT_ATTR_SIZE]; //!< Raw unknown dictionary name. 158 } unknown; 159 int num; //!< For array references. 160 int8_t tag; //!< For tag references. 161 } value_pair_tmpl_attr_t; 162 163 /** A source or sink of value data. 164 * 165 * Is used as both the RHS and LHS of a map (both update, and conditional types) 166 * 167 * @section update_maps Use in update vp_map_t 168 * When used on the LHS it describes an attribute to create and should be one of these types: 169 * - #TMPL_TYPE_ATTR 170 * - #TMPL_TYPE_LIST 171 * 172 * When used on the RHS it describes the value to assign to the attribute being created and 173 * should be one of these types: 174 * - #TMPL_TYPE_LITERAL 175 * - #TMPL_TYPE_XLAT 176 * - #TMPL_TYPE_ATTR 177 * - #TMPL_TYPE_LIST 178 * - #TMPL_TYPE_EXEC 179 * - #TMPL_TYPE_DATA 180 * - #TMPL_TYPE_XLAT_STRUCT (pre-parsed xlat) 181 * 182 * @section conditional_maps Use in conditional vp_map_t 183 * When used as part of a condition it may be any of the RHS side types, as well as: 184 * - #TMPL_TYPE_REGEX_STRUCT (pre-parsed regex) 185 * 186 * @see vp_map_t 187 */ 188 typedef struct vp_tmpl_t { 189 tmpl_type_t type; //!< What type of value tmpl refers to. 190 char const *name; //!< Original attribute ref string, or 191 //!< where this refers to a none FR 192 //!< attribute, just the string id for 193 //!< the attribute. 194 size_t len; //!< Name length. 195 char quote; //!< Quotation character for "name" 196 bool auto_converted; //!< Attr-26.9.1 --> Cisco-AVPair 197 198 #ifdef HAVE_REGEX 199 bool iflag; //!< regex - case insensitive (if operand is used in regex comparison) 200 bool mflag; //!< regex - multiline flags (controls $ matching) 201 #endif 202 203 union { 204 /* 205 * Attribute reference. Either an attribute currently in the request 206 * or an attribute to create. 207 */ 208 value_pair_tmpl_attr_t attribute; 209 210 /* 211 * Attribute value. Typically used as the RHS of an update map. 212 */ 213 struct { 214 PW_TYPE type; //!< Type of data. 215 size_t length; //!< of the vpd data. 216 value_data_t data; //!< Value data. 217 } literal; 218 219 xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t 220 221 #ifdef HAVE_REGEX 222 regex_t *preg; //!< pre-parsed regex_t 223 #endif 224 } data; 225 } vp_tmpl_t; 226 227 /** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNDEFINED, #TMPL_TYPE_LIST 228 * 229 * @{ 230 */ 231 #define tmpl_request data.attribute.request 232 #define tmpl_list data.attribute.list 233 #define tmpl_da data.attribute.da 234 #define tmpl_unknown data.attribute.unknown.da 235 #define tmpl_unknown_name data.attribute.unknown.name 236 #define tmpl_num data.attribute.num 237 #define tmpl_tag data.attribute.tag 238 /* @} **/ 239 240 /** @name Field accessors for #TMPL_TYPE_XLAT_STRUCT 241 * 242 * @{ 243 */ 244 #define tmpl_xlat data.xlat 245 /* @} **/ 246 247 /** @name Field accessors for #TMPL_TYPE_DATA 248 * 249 * @{ 250 */ 251 #define tmpl_data data.literal 252 #define tmpl_data_type data.literal.type 253 #define tmpl_data_length data.literal.length 254 #define tmpl_data_value data.literal.data 255 /* @} **/ 256 257 /** @name Field accessors for #TMPL_TYPE_REGEX_STRUCT and #TMPL_TYPE_REGEX 258 * 259 * @{ 260 */ 261 #ifdef HAVE_REGEX 262 # define tmpl_preg data.preg //!< #TMPL_TYPE_REGEX_STRUCT only. 263 # define tmpl_iflag iflag 264 # define tmpl_mflag mflag 265 #endif 266 /* @} **/ 267 268 #ifndef WITH_VERIFY_PTR 269 # define VERIFY_TMPL(_x) 270 #else 271 # define VERIFY_TMPL(_x) tmpl_verify(__FILE__, __LINE__, _x) 272 void tmpl_verify(char const *file, int line, vp_tmpl_t const *vpt); 273 #endif 274 275 VALUE_PAIR **radius_list(REQUEST *request, pair_lists_t list); 276 277 RADIUS_PACKET *radius_packet(REQUEST *request, pair_lists_t list_name); 278 279 TALLOC_CTX *radius_list_ctx(REQUEST *request, pair_lists_t list_name); 280 281 size_t radius_list_name(pair_lists_t *out, char const *name, pair_lists_t default_list); 282 283 int radius_request(REQUEST **request, request_refs_t name); 284 285 size_t radius_request_name(request_refs_t *out, char const *name, request_refs_t unknown); 286 287 vp_tmpl_t *tmpl_init(vp_tmpl_t *vpt, tmpl_type_t type, 288 char const *name, ssize_t len); 289 290 vp_tmpl_t *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, char const *name, 291 ssize_t len); 292 293 ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name, 294 request_refs_t request_def, pair_lists_t list_def, 295 bool allow_unknown, bool allow_undefined); 296 297 ssize_t tmpl_from_attr_str(vp_tmpl_t *vpt, char const *name, 298 request_refs_t request_def, 299 pair_lists_t list_def, 300 bool allow_unknown, bool allow_undefined); 301 302 ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, 303 request_refs_t request_def, pair_lists_t list_def, 304 bool allow_unknown, bool allow_undefined); 305 306 ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, 307 request_refs_t request_def, 308 pair_lists_t list_def, 309 bool allow_unknown, bool allow_undefined); 310 311 ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, size_t inlen, 312 FR_TOKEN type, request_refs_t request_def, pair_lists_t list_def, bool do_escape); 313 314 int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, DICT_ATTR const *enumv); 315 316 void tmpl_cast_in_place_str(vp_tmpl_t *vpt); 317 318 int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, 319 vp_tmpl_t const *vpt, DICT_ATTR const *cast); 320 321 size_t tmpl_prints(char *buffer, size_t bufsize, vp_tmpl_t const *vpt, 322 DICT_ATTR const *values); 323 324 ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request, 325 vp_tmpl_t const *vpt, xlat_escape_t escape, void *escape_ctx); 326 327 ssize_t tmpl_aexpand(TALLOC_CTX *ctx, char **out, REQUEST *request, vp_tmpl_t const *vpt, 328 xlat_escape_t escape, void *escape_ctx); 329 330 VALUE_PAIR *tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, 331 vp_tmpl_t const *vpt); 332 333 VALUE_PAIR *tmpl_cursor_next(vp_cursor_t *cursor, vp_tmpl_t const *vpt); 334 335 int tmpl_copy_vps(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, 336 vp_tmpl_t const *vpt); 337 338 int tmpl_find_vp(VALUE_PAIR **out, REQUEST *request, vp_tmpl_t const *vpt); 339 340 int tmpl_define_unknown_attr(vp_tmpl_t *vpt); 341 342 #ifdef __cplusplus 343 } 344 #endif 345 #endif /* TMPL_H */ 346