Skip to content

Commit

Permalink
Complete documentation for templates
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed Mar 5, 2015
1 parent 841444d commit 7fc9b7a
Show file tree
Hide file tree
Showing 2 changed files with 1,533 additions and 1,271 deletions.
185 changes: 127 additions & 58 deletions src/include/tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,53 @@
* @file tmpl.h
* @brief Structures and prototypes for templates
*
* @copyright 2014 The FreeRADIUS server project
* These functions are used to work with #value_pair_tmpl_t structs.
*
* #value_pair_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 #value_pair_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
* value_pair_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 #RADIUS_ESCAPE_STRING 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$")
Expand All @@ -31,32 +77,42 @@ RCSIDH(tmpl_h, "$Id$")
#ifdef __cplusplus
extern "C" {
#endif

#
typedef enum pair_lists {
PAIR_LIST_UNKNOWN = 0,
PAIR_LIST_REQUEST,
PAIR_LIST_REPLY,
PAIR_LIST_CONTROL,
PAIR_LIST_STATE,
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,
PAIR_LIST_PROXY_REPLY,
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,
PAIR_LIST_COA_REPLY,
PAIR_LIST_DM,
PAIR_LIST_DM_REPLY
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,
REQUEST_OUTER,
REQUEST_CURRENT,
REQUEST_PARENT /* For future use */
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[];
Expand All @@ -71,23 +127,27 @@ typedef struct pair_list {
struct pair_list *lastdefault;
} PAIR_LIST;

/** Types of #value_pair_tmpl_t
*/
typedef enum tmpl_type {
TMPL_TYPE_UNKNOWN = 0,
TMPL_TYPE_LITERAL, //!< Is a literal string.
TMPL_TYPE_XLAT, //!< Needs to be expanded.
TMPL_TYPE_ATTR, //!< Is a dictionary attribute.
TMPL_TYPE_ATTR_UNDEFINED, //!< Is an attribute not found in the global dictionary.
TMPL_TYPE_LIST, //!< Is a list.
TMPL_TYPE_REGEX, //!< Is a regex.
TMPL_TYPE_EXEC, //!< Needs to be executed.
TMPL_TYPE_DATA, //!< Is a value_data_t
TMPL_TYPE_XLAT_STRUCT, //!< pre-parsed xlat_exp_t
TMPL_TYPE_REGEX_STRUCT, //!< pre-parsed regex_t
TMPL_TYPE_NULL //!< VPT has no value
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.
Expand All @@ -101,26 +161,28 @@ typedef struct {
int8_t tag; //!< For tag references.
} value_pair_tmpl_attr_t;

/** A pre-parsed template attribute
/** 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 value_pair_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
* - #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)
* - #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 value_pair_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)
* - #TMPL_TYPE_REGEX_STRUCT (pre-parsed regex)
*
* @see value_pair_map_t
*/
Expand Down Expand Up @@ -157,31 +219,51 @@ typedef struct value_pair_tmpl_t {
xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t

#ifdef HAVE_REGEX
regex_t *preg; //!< pre-parsed regex_t
regex_t *preg; //!< pre-parsed regex_t
#endif
} data;
} value_pair_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
# 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)
Expand All @@ -190,7 +272,6 @@ typedef struct value_pair_tmpl_t {
void tmpl_verify(char const *file, int line, value_pair_tmpl_t const *vpt);
#endif

/* Attribute qualifier parsing */
VALUE_PAIR **radius_list(REQUEST *request, pair_lists_t list);

RADIUS_PACKET *radius_packet(REQUEST *request, pair_lists_t list_name);
Expand All @@ -203,21 +284,12 @@ 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);


/* Template manipulation and execution */
value_pair_tmpl_t *tmpl_init(value_pair_tmpl_t *vpt, tmpl_type_t type,
char const *name, ssize_t len);

value_pair_tmpl_t *tmpl_alloc(TALLOC_CTX *ctx, tmpl_type_t type, char const *name,
ssize_t len);

/*
* The following three functions parse attribute name strings into templates
*
* The 'str' variants will error out if the entire string isn't parsed.
* The 'afrom' variant will alloc a new tmpl structure.
*
*/
ssize_t tmpl_from_attr_substr(value_pair_tmpl_t *vpt, char const *name,
request_refs_t request_def, pair_lists_t list_def,
bool allow_unknown, bool allow_undefined);
Expand All @@ -232,22 +304,19 @@ ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, value_pair_tmpl_t **out, char con
pair_lists_t list_def,
bool allow_unknown, bool allow_undefined);

/*
* Parses any type of string into a template
*/
ssize_t tmpl_afrom_str(TALLOC_CTX *ctx, value_pair_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);

bool tmpl_cast_in_place(value_pair_tmpl_t *vpt, PW_TYPE type, DICT_ATTR const *enumv);

void tmpl_cast_in_place_str(value_pair_tmpl_t *vpt);

size_t tmpl_prints(char *buffer, size_t bufsize, value_pair_tmpl_t const *vpt,
DICT_ATTR const *values);

int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
value_pair_tmpl_t const *vpt, DICT_ATTR const *cast);

size_t tmpl_prints(char *buffer, size_t bufsize, value_pair_tmpl_t const *vpt,
DICT_ATTR const *values);

ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request,
value_pair_tmpl_t const *vpt, RADIUS_ESCAPE_STRING escape, void *escape_ctx);

Expand Down
Loading

0 comments on commit 7fc9b7a

Please sign in to comment.