The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
caller.c
Go to the documentation of this file.
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
17/**
18 * $Id: b6a38d7b55ccc47152414747a9aed935a7c767db $
19 *
20 * @file unlang/caller.c
21 * @brief Unlang "caller" keyword evaluation. Used for setting allowed parent protocols
22 *
23 * @copyright 2020 The FreeRADIUS server project
24 * @copyright 2021 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
25 */
26RCSID("$Id: b6a38d7b55ccc47152414747a9aed935a7c767db $")
27
28#include <freeradius-devel/server/state.h>
29
30#include "caller_priv.h"
31#include "group_priv.h"
32
34{
37
38 fr_assert(!unlang_list_empty(&g->children)); /* otherwise the compilation is broken */
39
40 /*
41 * No parent, or the dictionaries don't match. Ignore it.
42 */
43 if (!request->parent || (request->parent->proto_dict != gext->dict)) {
44 RDEBUG2("...");
46 }
47
48 /*
49 * The dictionary matches. Go recurse into its' children.
50 */
51 return unlang_group(p_result, request, frame);
52}
53
54
56{
58 unlang_t *c;
59
61 unlang_caller_t *gext;
62
64 char const *name;
65 fr_dict_t const *dict;
66 unlang_compile_ctx_t unlang_ctx2;
67 tmpl_rules_t parent_rules, t_rules;
68
69 fr_dict_autoload_talloc_t *dict_ref = NULL;
70
72 if (!name) {
73 cf_log_err(cs, "You MUST specify a protocol name for 'caller <protocol> { ... }'");
74 print_url:
75 cf_log_err(ci, DOC_KEYWORD_REF(caller));
76 return NULL;
77 }
78
80 if (type != T_BARE_WORD) {
81 cf_log_err(cs, "The argument to 'caller' cannot be a quoted string or a dynamic value");
82 goto print_url;
83 }
84
86 if (!dict) {
87 dict_ref = fr_dict_autoload_talloc(NULL, &dict, name);
88 if (!dict_ref) {
89 cf_log_perr(cs, "Unknown protocol '%s'", name);
90 goto print_url;
91 }
92 }
93
94 /*
95 * Create a new parent context with the new dictionary.
96 */
97 memcpy(&parent_rules, unlang_ctx->rules, sizeof(parent_rules));
98 memcpy(&t_rules, unlang_ctx->rules, sizeof(t_rules));
99 parent_rules.attr.dict_def = dict;
100 t_rules.parent = &parent_rules;
101
102 /*
103 * We don't want to modify the context we were passed, so
104 * we just clone it
105 */
106 memcpy(&unlang_ctx2, unlang_ctx, sizeof(unlang_ctx2));
107 unlang_ctx2.rules = &t_rules;
108 unlang_ctx2.section_name1 = "caller";
109 unlang_ctx2.section_name2 = name;
110
111 c = unlang_compile_section(parent, &unlang_ctx2, cs, UNLANG_TYPE_CALLER);
112 if (!c) {
113 talloc_free(dict_ref);
114 return NULL;
115 }
116
117 /*
118 * Set the virtual server name, which tells unlang_call()
119 * which virtual server to call.
120 */
122 gext = unlang_group_to_caller(g);
123 gext->dict = dict;
124
125 if (dict_ref) {
126 /*
127 * Parent the dictionary reference correctly now that we
128 * have the section with the dependency. This should
129 * be fast as dict_ref has no siblings.
130 */
131 talloc_steal(gext, dict_ref);
132 }
133
134 if (unlang_list_empty(&g->children)) {
135 talloc_free(c);
136 return UNLANG_IGNORE;
137 }
138
139 return c;
140}
141
143{
145 .name = "caller",
146 .type = UNLANG_TYPE_CALLER,
148
149 .compile = unlang_compile_caller,
150 .interpret = unlang_caller,
151
152 .unlang_size = sizeof(unlang_caller_t),
153 .unlang_name = "unlang_caller_t",
154 });
155}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_EXECUTE_NEXT
Execute the next unlang_t.
Definition action.h:38
#define RCSID(id)
Definition build.h:485
static unlang_t * unlang_compile_caller(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
Definition caller.c:55
static unlang_action_t unlang_caller(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Definition caller.c:33
void unlang_caller_init(void)
Definition caller.c:142
static unlang_caller_t * unlang_group_to_caller(unlang_group_t *g)
Cast a group structure to the caller keyword extension.
Definition caller_priv.h:40
fr_dict_t const * dict
Definition caller_priv.h:34
Common header for all CONF_* types.
Definition cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1184
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:683
fr_token_t cf_section_name2_quote(CONF_SECTION const *cs)
Return the quoting of the name2 identifier.
Definition cf_util.c:1229
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:296
unlang_t * unlang_compile_section(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_SECTION *cs, unlang_type_t type)
Definition compile.c:1508
#define fr_dict_autoload_talloc(_ctx, _dict_out, _proto)
Definition dict.h:873
fr_dict_t const * fr_dict_by_protocol_name(char const *name)
Lookup a protocol by its name.
Definition dict_util.c:2580
Structure used to managed the lifetime of a dictionary.
Definition dict_util.c:4240
unlang_action_t unlang_group(UNUSED unlang_result_t *p_result, request_t *request, UNUSED unlang_stack_frame_t *frame)
Definition group.c:31
Declarations for the "group" keyword.
static TALLOC_CTX * unlang_ctx
Definition base.c:71
void unlang_register(unlang_op_t *op)
Register an operation with the interpreter.
Definition base.c:56
talloc_free(reap)
#define fr_assert(_expr)
Definition rad_assert.h:38
#define RDEBUG2(fmt,...)
Definition radclient.h:54
static char const * name
tmpl_rules_t const * parent
for parent / child relationships
Definition tmpl.h:333
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:335
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:332
fr_aka_sim_id_type_t type
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:273
enum fr_token fr_token_t
@ T_BARE_WORD
Definition token.h:120
tmpl_rules_t const * rules
#define UNLANG_IGNORE
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
char const * section_name1
unlang_list_t children
@ UNLANG_TYPE_CALLER
conditionally check parent dictionary type
Definition unlang_priv.h:73
unlang_t const * instruction
The unlang node we're evaluating.
@ UNLANG_OP_FLAG_DEBUG_BRACES
Print debug braces.
char const * section_name2
Generic representation of a grouping.
An unlang operation.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
static fr_slen_t parent
Definition pair.h:841
#define DOC_KEYWORD_REF(_x)
Definition version.h:89