diff options
Diffstat (limited to 'src/include/tmpl.h')
-rw-r--r-- | src/include/tmpl.h | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/src/include/tmpl.h b/src/include/tmpl.h new file mode 100644 index 0000000..92884b1 --- /dev/null +++ b/src/include/tmpl.h @@ -0,0 +1,345 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef TMPL_H +#define TMPL_H +/** + * $Id$ + * + * @file tmpl.h + * @brief Structures and prototypes for templates + * + * These functions are used to work with #vp_tmpl_t structs. + * + * #vp_tmpl_t (VPTs) specify either a data source, or a data sink. + * + * Examples of sources are #TMPL_TYPE_XLAT, #TMPL_TYPE_EXEC and #TMPL_TYPE_ATTR. + * Examples of sinks are #TMPL_TYPE_ATTR, #TMPL_TYPE_LIST. + * + * VPTs are used to gather values or attributes for evaluation, or copying, and to specify + * where values or #VALUE_PAIR should be copied to. + * + * To create new #vp_tmpl_t use one of the tmpl_*from_* functions. These parse + * strings into VPTs. The main parsing function is #tmpl_afrom_str, which can produce + * most types of VPTs. It uses the type of quoting (passed as an #FR_TOKEN) to determine + * what type of VPT to parse the string as. For example a #T_DOUBLE_QUOTED_STRING will + * produce either a #TMPL_TYPE_XLAT or a #TMPL_TYPE_LITERAL (depending if the string + * contained a non-literal expansion). + * + * @see tmpl_afrom_str + * @see tmpl_afrom_attr_str + * @see tmpl_from_attr_str + * @see tmpl_from_attr_substr + * + * In the case of #TMPL_TYPE_ATTR and #TMPL_TYPE_LIST, there are special cursor overlay + * functions which can be used to iterate over only the #VALUE_PAIR that match a + * vp_tmpl_t in a given list. + * + * @see tmpl_cursor_init + * @see tmpl_cursor_next + * + * Or for simplicity, there are functions which wrap the cursor functions, to copy or + * return the #VALUE_PAIR that match the VPT. + * + * @see tmpl_copy_vps + * @see tmpl_find_vp + * + * If you just need the string value of whatever the VPT refers to, the tmpl_*expand + * functions may be used. These functions evaluate the VPT, execing, and xlat expanding + * as necessary. In the case of #TMPL_TYPE_ATTR, and #PW_TYPE_STRING or #PW_TYPE_OCTETS + * #tmpl_expand will return a pointer to the raw #VALUE_PAIR buffer. This can be very + * useful when using the #PW_TYPE_TMPL type in #CONF_PARSER structs, as it allows the + * user to determine whether they want the module to sanitise the value using presentation + * format specific #xlat_escape_t function, or to operate on the raw value. + * + * @see tmpl_expand + * @see tmpl_aexpand + * + * @copyright 2014-2015 The FreeRADIUS server project + */ + +RCSIDH(tmpl_h, "$Id$") + +#include <freeradius-devel/xlat.h> + +#ifdef __cplusplus +extern "C" { +#endif +# +typedef enum pair_lists { + PAIR_LIST_UNKNOWN = 0, //!< Unknown list. + PAIR_LIST_REQUEST, //!< Attributes in incoming or internally proxied + ///< request. + PAIR_LIST_REPLY, //!< Attributes to send in the response. + PAIR_LIST_CONTROL, //!< Attributes that change the behaviour of + ///< modules. + PAIR_LIST_STATE, //!< Attributes to store multiple rounds of + ///< challenges/responses. +#ifdef WITH_PROXY + PAIR_LIST_PROXY_REQUEST, //!< A copy of attributes in the request list + ///< that may be modified in pre-proxy before + //!< proxying the request. + PAIR_LIST_PROXY_REPLY, //!< Attributes sent in response to the proxied + ///< request. +#endif +#ifdef WITH_COA + PAIR_LIST_COA, //!< Attributes to send in a forked CoA-Request. + PAIR_LIST_COA_REPLY, //!< Attributes sent in response to the forked + ///< CoA-Request. + PAIR_LIST_DM, //!< Attributes to send in a forked Disconnect-Request. + PAIR_LIST_DM_REPLY //!< Attributes sent in response to the forked + //!< Disconnect-Request. +#endif +} pair_lists_t; + +extern const FR_NAME_NUMBER pair_lists[]; + +typedef enum requests { + REQUEST_UNKNOWN = 0, //!< Unknown request. + REQUEST_OUTER, //!< #REQUEST containing the outer layer of the EAP + //!< conversation. Usually the RADIUS request sent + //!< by the NAS. + REQUEST_CURRENT, //!< The current request. + REQUEST_PARENT //!< Not currently used. +} request_refs_t; + +extern const FR_NAME_NUMBER request_refs[]; + +typedef struct pair_list { + char const *name; + VALUE_PAIR *check; + VALUE_PAIR *reply; + int order; /* for ordering! */ + int lineno; + struct pair_list *next; +} PAIR_LIST; + +/** Types of #vp_tmpl_t + */ +typedef enum tmpl_type { + TMPL_TYPE_UNKNOWN = 0, //!< Uninitialised. + TMPL_TYPE_LITERAL, //!< Literal string. + TMPL_TYPE_XLAT, //!< XLAT expansion. + TMPL_TYPE_ATTR, //!< Dictionary attribute. + TMPL_TYPE_ATTR_UNDEFINED, //!< Attribute not found in the global dictionary. + TMPL_TYPE_LIST, //!< Attribute list. + TMPL_TYPE_REGEX, //!< Regular expression. + TMPL_TYPE_EXEC, //!< Callout to an external script or program. + TMPL_TYPE_DATA, //!< Value in native format. + TMPL_TYPE_XLAT_STRUCT, //!< Pre-parsed XLAT expansion. + TMPL_TYPE_REGEX_STRUCT, //!< Pre-parsed regular expression. + TMPL_TYPE_NULL //!< Has no value. +} tmpl_type_t; + +extern const FR_NAME_NUMBER tmpl_names[]; + +/** Describes a #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNDEFINED or #TMPL_TYPE_LIST + */ +typedef struct { + request_refs_t request; //!< Request to search or insert in. + pair_lists_t list; //!< List to search or insert in. + + DICT_ATTR const *da; //!< Resolved dictionary attribute. + union { + uint8_t da[DICT_ATTR_SIZE]; //!< Unknown dictionary attribute buffer. + char name[DICT_ATTR_SIZE]; //!< Raw unknown dictionary name. + } unknown; + int num; //!< For array references. + int8_t tag; //!< For tag references. +} value_pair_tmpl_attr_t; + +/** A source or sink of value data. + * + * Is used as both the RHS and LHS of a map (both update, and conditional types) + * + * @section update_maps Use in update vp_map_t + * When used on the LHS it describes an attribute to create and should be one of these types: + * - #TMPL_TYPE_ATTR + * - #TMPL_TYPE_LIST + * + * When used on the RHS it describes the value to assign to the attribute being created and + * should be one of these types: + * - #TMPL_TYPE_LITERAL + * - #TMPL_TYPE_XLAT + * - #TMPL_TYPE_ATTR + * - #TMPL_TYPE_LIST + * - #TMPL_TYPE_EXEC + * - #TMPL_TYPE_DATA + * - #TMPL_TYPE_XLAT_STRUCT (pre-parsed xlat) + * + * @section conditional_maps Use in conditional vp_map_t + * When used as part of a condition it may be any of the RHS side types, as well as: + * - #TMPL_TYPE_REGEX_STRUCT (pre-parsed regex) + * + * @see vp_map_t + */ +typedef struct vp_tmpl_t { + tmpl_type_t type; //!< What type of value tmpl refers to. + char const *name; //!< Original attribute ref string, or + //!< where this refers to a none FR + //!< attribute, just the string id for + //!< the attribute. + size_t len; //!< Name length. + char quote; //!< Quotation character for "name" + bool auto_converted; //!< Attr-26.9.1 --> Cisco-AVPair + +#ifdef HAVE_REGEX + bool iflag; //!< regex - case insensitive (if operand is used in regex comparison) + bool mflag; //!< regex - multiline flags (controls $ matching) +#endif + + union { + /* + * Attribute reference. Either an attribute currently in the request + * or an attribute to create. + */ + value_pair_tmpl_attr_t attribute; + + /* + * Attribute value. Typically used as the RHS of an update map. + */ + struct { + PW_TYPE type; //!< Type of data. + size_t length; //!< of the vpd data. + value_data_t data; //!< Value data. + } literal; + + xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t + +#ifdef HAVE_REGEX + regex_t *preg; //!< pre-parsed regex_t +#endif + } data; +} vp_tmpl_t; + +/** @name Field accessors for #TMPL_TYPE_ATTR, #TMPL_TYPE_ATTR_UNDEFINED, #TMPL_TYPE_LIST + * + * @{ + */ +#define tmpl_request data.attribute.request +#define tmpl_list data.attribute.list +#define tmpl_da data.attribute.da +#define tmpl_unknown data.attribute.unknown.da +#define tmpl_unknown_name data.attribute.unknown.name +#define tmpl_num data.attribute.num +#define tmpl_tag data.attribute.tag +/* @} **/ + +/** @name Field accessors for #TMPL_TYPE_XLAT_STRUCT + * + * @{ + */ +#define tmpl_xlat data.xlat +/* @} **/ + +/** @name Field accessors for #TMPL_TYPE_DATA + * + * @{ + */ +#define tmpl_data data.literal +#define tmpl_data_type data.literal.type +#define tmpl_data_length data.literal.length +#define tmpl_data_value data.literal.data +/* @} **/ + +/** @name Field accessors for #TMPL_TYPE_REGEX_STRUCT and #TMPL_TYPE_REGEX + * + * @{ + */ +#ifdef HAVE_REGEX +# define tmpl_preg data.preg //!< #TMPL_TYPE_REGEX_STRUCT only. +# define tmpl_iflag iflag +# define tmpl_mflag mflag +#endif +/* @} **/ + +#ifndef WITH_VERIFY_PTR +# define VERIFY_TMPL(_x) +#else +# define VERIFY_TMPL(_x) tmpl_verify(__FILE__, __LINE__, _x) +void tmpl_verify(char const *file, int line, vp_tmpl_t const *vpt); +#endif + +VALUE_PAIR **radius_list(REQUEST *request, pair_lists_t list); + +RADIUS_PACKET *radius_packet(REQUEST *request, pair_lists_t list_name); + +TALLOC_CTX *radius_list_ctx(REQUEST *request, pair_lists_t list_name); + +size_t radius_list_name(pair_lists_t *out, char const *name, pair_lists_t default_list); + +int radius_request(REQUEST **request, request_refs_t name); + +size_t radius_request_name(request_refs_t *out, char const *name, request_refs_t unknown); + +vp_tmpl_t *tmpl_init(vp_tmpl_t *vpt, tmpl_type_t type, + char const *name, ssize_t len); + +vp_tmpl_t *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, char const *name, + ssize_t len); + +ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name, + request_refs_t request_def, pair_lists_t list_def, + bool allow_unknown, bool allow_undefined); + +ssize_t tmpl_from_attr_str(vp_tmpl_t *vpt, char const *name, + request_refs_t request_def, + pair_lists_t list_def, + bool allow_unknown, bool allow_undefined); + +ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, + request_refs_t request_def, pair_lists_t list_def, + bool allow_unknown, bool allow_undefined); + +ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, + request_refs_t request_def, + pair_lists_t list_def, + bool allow_unknown, bool allow_undefined); + +ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *name, size_t inlen, + FR_TOKEN type, request_refs_t request_def, pair_lists_t list_def, bool do_escape); + +int tmpl_cast_in_place(vp_tmpl_t *vpt, PW_TYPE type, DICT_ATTR const *enumv); + +void tmpl_cast_in_place_str(vp_tmpl_t *vpt); + +int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, + vp_tmpl_t const *vpt, DICT_ATTR const *cast); + +size_t tmpl_prints(char *buffer, size_t bufsize, vp_tmpl_t const *vpt, + DICT_ATTR const *values); + +ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request, + vp_tmpl_t const *vpt, xlat_escape_t escape, void *escape_ctx); + +ssize_t tmpl_aexpand(TALLOC_CTX *ctx, char **out, REQUEST *request, vp_tmpl_t const *vpt, + xlat_escape_t escape, void *escape_ctx); + +VALUE_PAIR *tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, + vp_tmpl_t const *vpt); + +VALUE_PAIR *tmpl_cursor_next(vp_cursor_t *cursor, vp_tmpl_t const *vpt); + +int tmpl_copy_vps(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, + vp_tmpl_t const *vpt); + +int tmpl_find_vp(VALUE_PAIR **out, REQUEST *request, vp_tmpl_t const *vpt); + +int tmpl_define_unknown_attr(vp_tmpl_t *vpt); + +#ifdef __cplusplus +} +#endif +#endif /* TMPL_H */ |