The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 952724463061bd315d33976238c260510935fa38 $
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 
68 static fr_dict_t const *dict_ldap_sync;
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  */
123 static 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 ret;
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  */
155 static 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 
188 send:
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 
195 static 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 
234 static 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))) {
331  if (fr_type_is_structural(tmpl_attr_tail_da(map->lhs)->type)) {
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",
379  .config = proto_ldap_sync_config,
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:574
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:165
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:487
#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:345
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:405
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:419
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:399
#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:564
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
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:267
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:280
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
Specifies an attribute which must be present for the module to function.
Definition: dict.h:266
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:279
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
if(rcode > 0)
Definition: fd_read.h:9
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:2923
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.
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.
Definition: merged_model.c:118
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
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
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:1302
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
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_rules_t attr
Rules/data for parsing attribute references.
Definition: tmpl.h:344
@ 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
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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.