The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
proto_ldap_sync.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: dfe9ae5938e3ec75f89dc1e4ebe56e4335cb89dc $
19 * @file proto_ldap_sync.c
20 * @brief LDAP sync protocol handler.
21 *
22 * @copyright 2022 Network RADIUS SAS (legal@networkradius.com)
23 */
24#define LOG_PREFIX "proto_ldap_sync"
25
26#include <freeradius-devel/internal/internal.h>
27#include <freeradius-devel/io/listen.h>
28#include <freeradius-devel/server/module.h>
29
30#include "proto_ldap_sync.h"
31
32#include <fcntl.h>
33
35
37
39 { FR_CONF_OFFSET("base_dn", sync_config_t, base_dn), .dflt = "", .quote = T_SINGLE_QUOTED_STRING },
40
41 { FR_CONF_OFFSET("filter", sync_config_t, filter) },
42
43 { FR_CONF_OFFSET("scope", sync_config_t, scope_str), .dflt = "sub" },
44 /* For persistent search directories, setting this to "no" will load the whole directory. */
45 { FR_CONF_OFFSET("changes_only", sync_config_t, changes_only), .dflt = "yes" },
46
48};
49
51 { FR_CONF_OFFSET_TYPE_FLAGS("transport", FR_TYPE_VOID, 0, proto_ldap_sync_t, io_submodule),
53
54 { FR_CONF_OFFSET("max_packet_size", proto_ldap_sync_t, max_packet_size) },
55 { FR_CONF_OFFSET("num_messages", proto_ldap_sync_t, num_messages) },
56 { FR_CONF_OFFSET("cookie_interval", proto_ldap_sync_t, cookie_interval), .dflt = "10" },
57 { FR_CONF_OFFSET("cookie_changes", proto_ldap_sync_t, cookie_changes), .dflt = "100" },
58 { FR_CONF_OFFSET("retry_interval", proto_ldap_sync_t, retry_interval), .dflt = "1" },
59
60 /*
61 * Areas of the DIT to listen on
62 */
64
66};
67
69
72 { .out = &dict_ldap_sync, .proto = "ldap" },
73 { NULL }
74};
75
83
86 { .out = &attr_ldap_sync_packet_id, .name = "Sync-Packet-ID", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
87 { .out = &attr_ldap_sync, .name = "LDAP-Sync", .type = FR_TYPE_TLV, .dict = &dict_ldap_sync },
88 { .out = &attr_ldap_sync_cookie, .name = "LDAP-Sync.Cookie", .type = FR_TYPE_OCTETS, .dict = &dict_ldap_sync },
89 { .out = &attr_ldap_sync_dn, .name = "LDAP-Sync.DN", .type = FR_TYPE_STRING, .dict = &dict_ldap_sync },
90 { .out = &attr_ldap_sync_scope, .name = "LDAP-Sync.Scope", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
91 { .out = &attr_ldap_sync_filter, .name = "LDAP-Sync.Filter", .type = FR_TYPE_STRING, .dict = &dict_ldap_sync },
92 { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
93 { NULL }
94};
95
96/** Check if an attribute is in the config list and add if not present
97 *
98 * @param[in,out] config to check for attribute.
99 * @param[in] attr to look for.
100 * @return
101 * - 1 if attr is added
102 * - 0 if attr was already present
103 */
105{
106 char **tmp;
107 size_t len;
108
109 if (fr_ldap_attrs_check(config->attrs, attr)) return 0;
110
111 len = talloc_array_length(config->attrs);
112
113 config->attrs[len - 1] = talloc_strdup(config, attr);
114 tmp = (char **)talloc_array_null_terminate(UNCONST(void **, config->attrs));
115 memcpy(&config->attrs, &tmp, sizeof(config->attrs));
116
117 return 1;
118}
119
120/** Decode an internal LDAP sync packet
121 *
122 */
123static int mod_decode(UNUSED void const *instance, request_t *request, uint8_t *const data, size_t data_len)
124{
125 fr_dbuff_t dbuff;
126 ssize_t ret;
127 fr_pair_t *vp = NULL;
128
129 request->dict = dict_ldap_sync;
130
131 fr_dbuff_init(&dbuff, data, data_len);
132
133 /*
134 * Extract attributes from the passed data
135 */
136 ret = fr_internal_decode_list_dbuff(request->pair_list.request, &request->request_pairs,
137 fr_dict_root(request->dict), &dbuff, NULL);
138 if (ret < 0) return -1;
139
140 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_packet_type);
141 fr_assert(vp);
142 request->packet->code = vp->vp_uint32;
143
144 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_ldap_sync_packet_id);
145 fr_assert(vp);
146 request->packet->id = vp->vp_uint32;
147 request->reply->id = vp->vp_uint32;
148
149 return 0;
150}
151
152/** Encode responses to processing LDAP sync sections
153 *
154 */
155static ssize_t mod_encode(UNUSED void const *instance, request_t *request, uint8_t *buffer, size_t buffer_len)
156{
157 fr_dbuff_t dbuff;
158 fr_pair_t *sync_vp = NULL, *vp = NULL;
159 fr_pair_list_t pairs;
160 TALLOC_CTX *local = NULL;
161
162 fr_dbuff_init(&dbuff, buffer, buffer_len);
163 local = talloc_new(NULL);
164 fr_pair_list_init(&pairs);
165
166 fr_pair_list_append_by_da(local, vp, &pairs, attr_packet_type, request->reply->code, false);
167 if (!vp) {
168 error:
169 talloc_free(local);
170 return -1;
171 }
172 fr_pair_list_append_by_da(local, vp, &pairs, attr_ldap_sync_packet_id, (uint32_t)request->reply->id, false);
173 if (!vp) goto error;
174
175 /*
176 * Only Cookie Load Response has extra data sent - the cookie (if defined)
177 */
178 if (request->reply->code != FR_LDAP_SYNC_CODE_COOKIE_LOAD_RESPONSE) goto send;
179
180 sync_vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_ldap_sync);
181 if (!sync_vp) goto send;
182 vp = fr_pair_find_by_da(&sync_vp->vp_group, NULL, attr_ldap_sync_cookie);
183 if ((vp) && (vp->data.vb_length > 0)) {
184 fr_pair_remove(&request->reply_pairs, sync_vp);
185 fr_pair_steal_append(local, &pairs, sync_vp);
186 }
187
188send:
189 if (fr_internal_encode_list(&dbuff, &pairs, &encode_ctx) < 0) goto error;
190 talloc_free(local);
191
192 return fr_dbuff_used(&dbuff);
193}
194
195static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf)
196{
197 proto_ldap_sync_t *inst = talloc_get_type_abort(instance, proto_ldap_sync_t);
198 fr_listen_t *li;
199
200 /*
201 * Build the #fr_listen_t.
202 */
203 MEM(li = talloc_zero(inst, fr_listen_t));
204 talloc_set_destructor(li, fr_io_listen_free);
205
206 li->app_io = inst->app_io;
207 li->thread_instance = talloc_zero_array(NULL, uint8_t, li->app_io->common.thread_inst_size);
208 talloc_set_name(li->thread_instance, "proto_%s_thread_t", inst->app_io->common.name);
209 li->app_io_instance = inst->app_io_instance;
210 li->name = "ldap_sync main listener";
211
212 li->app = &proto_ldap_sync;
213 li->app_instance = instance;
214 li->server_cs = inst->server_cs;
215 li->non_socket_listener = true;
216
217 /*
218 * Set configurable parameters for message ring buffer.
219 */
220 li->default_message_size = inst->max_packet_size;
221 li->num_messages = inst->num_messages;
222
223 if (!fr_schedule_listen_add(sc, li)) {
224 talloc_free(li);
225 return -1;
226 }
227
228 inst->listen = li;
229 inst->sc = sc;
230
231 return 0;
232}
233
234static int mod_instantiate(module_inst_ctx_t const *mctx)
235{
236 proto_ldap_sync_t *inst = talloc_get_type_abort(mctx->mi->data, proto_ldap_sync_t);
237 CONF_SECTION *conf = mctx->mi->conf;
238 CONF_SECTION *sync_cs;
239 sync_config_t *sync_conf;
240 size_t i;
241 fr_pair_t *vp;
242 CONF_SECTION *map_cs;
243 map_t *map;
244 tmpl_rules_t parse_rules = {
245 /* Strict rules for the update map as it's processed with limited functionality */
246 .attr = {
248 .list_def = request_attr_request,
249 .allow_foreign = false,
250 .allow_unknown = false,
251 .allow_unresolved = false,
252 .list_presence = TMPL_ATTR_LIST_FORBID,
253 }
254 };
255
256 inst->server_cs = cf_item_to_section(cf_parent(conf));
257 inst->cs = conf;
258 inst->self = &proto_ldap_sync;
259
260 if (!inst->io_submodule) {
261 cf_log_err(conf, "Virtual server for LDAP sync requires a 'transport' configuration");
262 return -1;
263 }
264
265 /*
266 * Bootstrap the I/O module
267 */
268 inst->app_io = (fr_app_io_t const *) inst->io_submodule->exported;
269 inst->app_io_instance = inst->io_submodule->data;
270 inst->app_io_conf = inst->io_submodule->conf;
271
272 /*
273 * These configuration items are not printed by default,
274 * because normal people shouldn't be touching them.
275 */
276 if (!inst->max_packet_size) inst->max_packet_size = inst->app_io->default_message_size;
277 if (!inst->num_messages) inst->num_messages = 2;
278
279 FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, >=, 2);
280 FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, <=, 65535);
281
282 FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, 1024);
283 FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, 65536);
284
285 if (!inst->priority) inst->priority = PRIORITY_NORMAL;
286
287 /*
288 * Parse each of the sync sections
289 */
290 for (sync_cs = cf_section_find(conf, "sync", NULL), i = 0;
291 sync_cs;
292 sync_cs = cf_section_find_next(conf, sync_cs, "sync", NULL), i++) {
293 sync_conf = inst->sync_config[i];
294 sync_conf->cs = sync_cs;
295
296 /*
297 * Convert scope string to enumerated constant
298 */
299 sync_conf->scope = fr_table_value_by_str(fr_ldap_scope, sync_conf->scope_str, -1);
300 if (sync_conf->scope < 0) {
301 cf_log_err(conf, "Invalid 'search.scope' value \"%s\", expected 'sub', 'one', 'base' or 'children'",
302 sync_conf->scope_str);
303 return -1;
304 }
305
306 map_cs = cf_section_find(sync_cs, "update", NULL);
307 map_list_init(&sync_conf->entry_map);
308 if (map_cs && map_afrom_cs(inst, &sync_conf->entry_map, map_cs,
309 &parse_rules, &parse_rules, fr_ldap_map_verify, NULL,
310 LDAP_MAX_ATTRMAP) < 0) {
311 return -1;
312 }
313
314 /*
315 * Initialise a NULL terminated list of attributes
316 */
317 sync_conf->attrs = talloc_array(sync_conf, char const *, 1);
318 sync_conf->attrs[0] = NULL;
319
320 if (map_list_empty(&sync_conf->entry_map)) {
321 cf_log_warn(conf, "LDAP sync specified without update map");
322 continue;
323 }
324
325 /*
326 * Build the required list of attributes from the update map,
327 * checking validity as we go.
328 */
329 map = NULL;
330 while ((map = map_list_next(&sync_conf->entry_map, map))) {
332 cf_log_err(map->ci, "Structural attribute \"%s\" invalid for LDAP sync update",
333 tmpl_attr_tail_da(map->lhs)->name);
334 return -1;
335 }
336
337 switch(map->op) {
338 case T_OP_EQ:
339 case T_OP_ADD_EQ:
340 break;
341
342 default:
343 cf_log_err(map->ci, "Operator \"%s\" invalid for LDAP sync update",
344 fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));
345 return -1;
346 }
347
348 DEBUG3("Adding %s to attribute list", map->rhs->name);
349 ldap_sync_conf_attr_add(sync_conf, map->rhs->name);
350 }
351
352 /*
353 * Build the list of pairs representing the sync config
354 */
355 fr_pair_list_init(&sync_conf->sync_pairs);
356
358 sync_conf->base_dn, strlen(sync_conf->base_dn), false);
359 if (!vp) return -1;
360
362 (uint32_t)sync_conf->scope, false);
363 if (!vp) return -1;
364
365 if (sync_conf->filter) {
367 sync_conf->filter, strlen(sync_conf->filter), false);
368 if (!vp) return -1;
369 }
370 }
371
372 return 0;
373}
374
376 .common = {
377 .magic = MODULE_MAGIC_INIT,
378 .name = "ldap_sync",
380 .inst_size = sizeof(proto_ldap_sync_t),
382 },
383
384 .dict = &dict_ldap_sync,
385
386 .open = mod_open,
387 .decode = mod_decode,
388 .encode = mod_encode,
389};
static int const char char buffer[256]
Definition acutest.h:576
module_t common
Common fields to all loadable modules.
Definition app_io.h:34
Public structure describing an I/O path for a protocol.
Definition app_io.h:33
module_t common
Common fields provided by all modules.
Definition application.h:72
Describes a new application (protocol)
Definition application.h:71
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
#define UNUSED
Definition build.h:315
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:596
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition cf_parse.h:502
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
#define FR_CONF_SUBSECTION_ALLOC(_name, _type, _flags, _struct, _field, _subcs)
A conf_parser_t multi-subsection.
Definition cf_parse.h:358
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:634
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:418
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition cf_parse.h:432
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:412
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:241
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition cf_util.c:1028
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:684
CONF_SECTION * cf_section_find_next(CONF_SECTION const *cs, CONF_SECTION const *prev, char const *name1, char const *name2)
Return the next matching section.
Definition cf_util.c:1049
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define cf_parent(_cf)
Definition cf_util.h:101
#define cf_log_warn(_cf, _fmt,...)
Definition cf_util.h:290
#define PRIORITY_NORMAL
Definition channel.h:151
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
Definition dbuff.h:767
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:354
#define MEM(x)
Definition debug.h:36
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2400
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
bool allow_name_only
Allow name only pairs.
Definition internal.h:36
size_t num_messages
for the message ring buffer
Definition listen.h:52
bool non_socket_listener
special internal listener that does not use sockets.
Definition listen.h:45
char const * name
printable name for this socket - set by open
Definition listen.h:29
void const * app_instance
Definition listen.h:38
size_t default_message_size
copied from app_io, but may be changed
Definition listen.h:51
fr_app_t const * app
Definition listen.h:37
void const * app_io_instance
I/O path configuration context.
Definition listen.h:32
int fr_io_listen_free(fr_listen_t *li)
Definition master.c:2917
CONF_SECTION * server_cs
CONF_SECTION of the server.
Definition listen.h:40
void * thread_instance
thread / socket context
Definition listen.h:33
fr_app_io_t const * app_io
I/O path functions.
Definition listen.h:31
int fr_ldap_map_verify(map_t *map, void *instance)
int fr_ldap_attrs_check(char const **attrs, char const *attr)
Check that a particular attribute is included in an attribute list.
Definition util.c:579
#define LDAP_MAX_ATTRMAP
Maximum number of mappings between LDAP and FreeRADIUS attributes.
Definition base.h:96
fr_table_num_sorted_t const fr_ldap_scope[]
Definition base.c:69
#define DEBUG3(_fmt,...)
Definition log.h:266
int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, unsigned int max)
Convert a config section into an attribute map.
Definition map.c:1014
talloc_free(reap)
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:693
int fr_pair_steal_append(TALLOC_CTX *list_ctx, fr_pair_list_t *list, fr_pair_t *vp)
Change a vp's talloc ctx and insert it into a new list.
Definition pair.c:546
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
static const conf_parser_t config[]
Definition base.c:183
static conf_parser_t const ldap_sync_search_config[]
static fr_dict_attr_t const * attr_ldap_sync_filter
static fr_dict_attr_t const * attr_packet_type
static ssize_t mod_encode(UNUSED void const *instance, request_t *request, uint8_t *buffer, size_t buffer_len)
Encode responses to processing LDAP sync sections.
static fr_dict_attr_t const * attr_ldap_sync_packet_id
static fr_dict_t const * dict_ldap_sync
fr_dict_attr_autoload_t proto_ldap_sync_dict_attr[]
int ldap_sync_conf_attr_add(sync_config_t *config, char const *attr)
Check if an attribute is in the config list and add if not present.
static conf_parser_t const proto_ldap_sync_config[]
static fr_dict_attr_t const * attr_ldap_sync_dn
static fr_dict_attr_t const * attr_ldap_sync
fr_app_t proto_ldap_sync
static fr_internal_encode_ctx_t encode_ctx
static int mod_decode(UNUSED void const *instance, request_t *request, uint8_t *const data, size_t data_len)
Decode an internal LDAP sync packet.
static fr_dict_attr_t const * attr_ldap_sync_scope
fr_dict_autoload_t proto_ldap_sync_dict[]
static fr_dict_attr_t const * attr_ldap_sync_cookie
static int mod_instantiate(module_inst_ctx_t const *mctx)
static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf)
char const * filter
Filter to retrieve only user objects.
char const * scope_str
Scope (sub, one, base).
char const * base_dn
DN to search for users under.
int scope
Scope as its libldap value.
CONF_SECTION * cs
Config section where this sync was defined.
char const ** attrs
Zero terminated attribute array.
map_list_t entry_map
How to convert attributes in entries to FreeRADIUS attributes.
fr_pair_list_t sync_pairs
Pairs representing the sync config sent to the worker with each request.
An instance of a proto_ldap_sync listen section.
Areas of the directory to receive notifications for.
ssize_t fr_internal_decode_list_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *dbuff, void *decode_ctx)
Retrieve all pairs from the dbuff.
Definition decode.c:310
ssize_t fr_internal_encode_list(fr_dbuff_t *dbuff, fr_pair_list_t const *list, void *encode_ctx)
Encode a list of pairs using the internal encoder.
Definition encode.c:303
#define fr_assert(_expr)
Definition rad_assert.h:38
static rs_t * conf
Definition radsniff.c:53
fr_dict_attr_t const * request_attr_request
Definition request.c:45
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1310
fr_network_t * fr_schedule_listen_add(fr_schedule_t *sc, fr_listen_t *li)
Add a fr_listen_t to a scheduler.
Definition schedule.c:881
The scheduler.
Definition schedule.c:125
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:329
void * data
Module's instance data.
Definition module.h:271
size_t thread_inst_size
Size of the module's thread-specific instance data.
Definition module.h:235
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:198
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
Definition tmpl.h:344
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition tmpl.h:812
@ TMPL_ATTR_LIST_FORBID
Attribute refs are forbidden from having a list.
Definition tmpl.h:275
Optional arguments passed to vp_tmpl functions.
Definition tmpl.h:341
static const uchar sc[16]
Definition smbdes.c:115
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Value pair map.
Definition map.h:77
fr_token_t op
The operator that controls insertion of the dst attribute.
Definition map.h:82
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
Definition map.h:78
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
Definition map.h:79
CONF_ITEM * ci
Config item that the map was created from.
Definition map.h:85
fr_dict_t const * dict_def
Default dictionary to use with unqualified attribute references.
Definition tmpl.h:285
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
@ FR_LDAP_SYNC_CODE_COOKIE_LOAD_RESPONSE
Response with the returned cookie.
Definition sync.h:46
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition talloc.c:852
fr_table_num_ordered_t const fr_tokens_table[]
Definition token.c:33
@ T_SINGLE_QUOTED_STRING
Definition token.h:122
@ T_OP_EQ
Definition token.h:83
@ T_OP_ADD_EQ
Definition token.h:69
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
Definition pair_inline.c:94
#define fr_pair_list_append_by_da(_ctx, _vp, _list, _attr, _val, _tainted)
Append a pair to a list, assigning its value.
Definition pair.h:286
#define fr_pair_list_append_by_da_parent_len(_ctx, _vp, _list, _attr, _val, _len, _tainted)
Definition pair.h:331
#define fr_pair_list_append_by_da_parent(_ctx, _vp, _list, _attr, _val, _tainted)
Definition pair.h:320
#define fr_type_is_structural(_x)
Definition types.h:371
static fr_slen_t data
Definition value.h:1265
int virtual_server_listen_transport_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic conf_parser_t func for loading drivers.