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: 809c26d3763dfe3663acef7a8349accc4b1cb7c8 $
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 
38 static int transport_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule);
39 
41  { FR_CONF_OFFSET("base_dn", sync_config_t, base_dn), .dflt = "", .quote = T_SINGLE_QUOTED_STRING },
42 
43  { FR_CONF_OFFSET("filter", sync_config_t, filter) },
44 
45  { FR_CONF_OFFSET("scope", sync_config_t, scope_str), .dflt = "sub" },
46  /* For persistent search directories, setting this to "no" will load the whole directory. */
47  { FR_CONF_OFFSET("changes_only", sync_config_t, changes_only), .dflt = "yes" },
48 
50 };
51 
53  { FR_CONF_OFFSET_TYPE_FLAGS("transport", FR_TYPE_VOID, 0, proto_ldap_sync_t, io_submodule),
54  .func = transport_parse },
55 
56  { FR_CONF_OFFSET("max_packet_size", proto_ldap_sync_t, max_packet_size) },
57  { FR_CONF_OFFSET("num_messages", proto_ldap_sync_t, num_messages) },
58  { FR_CONF_OFFSET("cookie_interval", proto_ldap_sync_t, cookie_interval), .dflt = "10" },
59  { FR_CONF_OFFSET("cookie_changes", proto_ldap_sync_t, cookie_changes), .dflt = "100" },
60  { FR_CONF_OFFSET("retry_interval", proto_ldap_sync_t, retry_interval), .dflt = "1" },
61 
62  /*
63  * Areas of the DIT to listen on
64  */
66 
68 };
69 
70 static fr_dict_t const *dict_ldap_sync;
71 
74  { .out = &dict_ldap_sync, .proto = "ldap" },
75  { NULL }
76 };
77 
85 
88  { .out = &attr_ldap_sync_packet_id, .name = "Sync-Packet-ID", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
89  { .out = &attr_ldap_sync, .name = "LDAP-Sync", .type = FR_TYPE_TLV, .dict = &dict_ldap_sync },
90  { .out = &attr_ldap_sync_cookie, .name = "LDAP-Sync.Cookie", .type = FR_TYPE_OCTETS, .dict = &dict_ldap_sync },
91  { .out = &attr_ldap_sync_dn, .name = "LDAP-Sync.DN", .type = FR_TYPE_STRING, .dict = &dict_ldap_sync },
92  { .out = &attr_ldap_sync_scope, .name = "LDAP-Sync.Scope", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
93  { .out = &attr_ldap_sync_filter, .name = "LDAP-Sync.Filter", .type = FR_TYPE_STRING, .dict = &dict_ldap_sync },
94  { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_ldap_sync },
95  { NULL }
96 };
97 
98 /** Wrapper around dl_instance
99  *
100  * @param[in] ctx to allocate data in (instance of proto_dns).
101  * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance.
102  * @param[in] parent Base structure address.
103  * @param[in] ci #CONF_PAIR specifying the name of the type module.
104  * @param[in] rule unused.
105  * @return
106  * - 0 on success.
107  * - -1 on failure.
108  */
109 static int transport_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
110  CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
111 {
112  char const *name = cf_pair_value(cf_item_to_pair(ci));
113  dl_module_inst_t *parent_inst;
114  CONF_SECTION *listen_cs = cf_item_to_section(cf_parent(ci));
115  CONF_SECTION *transport_cs;
116  dl_module_inst_t *dl_mod_inst;
117 
118  transport_cs = cf_section_find(listen_cs, name, NULL);
119 
120  /*
121  * Allocate an empty section if one doesn't exist
122  * this is so defaults get parsed.
123  */
124  if (!transport_cs) transport_cs = cf_section_alloc(listen_cs, listen_cs, name, NULL);
125 
126  parent_inst = cf_data_value(cf_data_find(listen_cs, dl_module_inst_t, "proto_ldap_sync"));
127  fr_assert(parent_inst);
128 
129  if (dl_module_instance(ctx, &dl_mod_inst, parent_inst, DL_MODULE_TYPE_SUBMODULE, name,
130  dl_module_inst_name_from_conf(transport_cs)) < 0) return -1;
131  if (dl_module_conf_parse(dl_mod_inst, transport_cs) < 0) {
132  talloc_free(dl_mod_inst);
133  return -1;
134  }
135  *((dl_module_inst_t **)out) = dl_mod_inst;
136  return 0;
137 }
138 
139 /** Check if an attribute is in the config list and add if not present
140  *
141  * @param[in,out] config to check for attribute.
142  * @param[in] attr to look for.
143  * @return
144  * - 1 if attr is added
145  * - 0 if attr was already present
146  */
148 {
149  char **tmp;
150  size_t len;
151 
152  if (fr_ldap_attrs_check(config->attrs, attr)) return 0;
153 
154  len = talloc_array_length(config->attrs);
155 
156  config->attrs[len - 1] = talloc_strdup(config, attr);
157  tmp = (char **)talloc_array_null_terminate(UNCONST(void **, config->attrs));
158  memcpy(&config->attrs, &tmp, sizeof(config->attrs));
159 
160  return 1;
161 }
162 
163 /** Decode an internal LDAP sync packet
164  *
165  */
166 static int mod_decode(UNUSED void const *instance, request_t *request, uint8_t *const data, size_t data_len)
167 {
168  fr_dbuff_t dbuff;
169  ssize_t ret;
170  fr_pair_t *vp = NULL;
171 
172  request->dict = dict_ldap_sync;
173 
174  fr_dbuff_init(&dbuff, data, data_len);
175 
176  /*
177  * Extract attributes from the passed data
178  */
179  ret = fr_internal_decode_list_dbuff(request->pair_list.request, &request->request_pairs,
180  fr_dict_root(request->dict), &dbuff, NULL);
181  if (ret < 0) return ret;
182 
183  vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_packet_type);
184  fr_assert(vp);
185  request->packet->code = vp->vp_uint32;
186 
187  vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_ldap_sync_packet_id);
188  fr_assert(vp);
189  request->packet->id = vp->vp_uint32;
190  request->reply->id = vp->vp_uint32;
191 
192  return 0;
193 }
194 
195 /** Encode responses to processing LDAP sync sections
196  *
197  */
198 static ssize_t mod_encode(UNUSED void const *instance, request_t *request, uint8_t *buffer, size_t buffer_len)
199 {
200  fr_dbuff_t dbuff;
201  fr_pair_t *sync_vp = NULL, *vp = NULL;
202  fr_pair_list_t pairs;
203  TALLOC_CTX *local = NULL;
204 
205  fr_dbuff_init(&dbuff, buffer, buffer_len);
206  local = talloc_new(NULL);
207  fr_pair_list_init(&pairs);
208 
209  fr_pair_list_append_by_da(local, vp, &pairs, attr_packet_type, request->reply->code, false);
210  if (!vp) {
211  error:
212  talloc_free(local);
213  return -1;
214  }
215  fr_pair_list_append_by_da(local, vp, &pairs, attr_ldap_sync_packet_id, (uint32_t)request->reply->id, false);
216  if (!vp) goto error;
217 
218  /*
219  * Only Cookie Load Response has extra data sent - the cookie (if defined)
220  */
221  if (request->reply->code != FR_LDAP_SYNC_CODE_COOKIE_LOAD_RESPONSE) goto send;
222 
223  sync_vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_ldap_sync);
224  if (!sync_vp) goto send;
225  vp = fr_pair_find_by_da(&sync_vp->vp_group, NULL, attr_ldap_sync_cookie);
226  if ((vp) && (vp->data.vb_length > 0)) {
227  fr_pair_remove(&request->reply_pairs, sync_vp);
228  fr_pair_steal_append(local, &pairs, sync_vp);
229  }
230 
231 send:
232  if (fr_internal_encode_list(&dbuff, &pairs, &encode_ctx) < 0) goto error;
233  talloc_free(local);
234 
235  return fr_dbuff_used(&dbuff);
236 }
237 
238 static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf)
239 {
240  proto_ldap_sync_t *inst = talloc_get_type_abort(instance, proto_ldap_sync_t);
241  fr_listen_t *li;
242 
243  /*
244  * Build the #fr_listen_t.
245  */
246  MEM(li = talloc_zero(inst, fr_listen_t));
247  talloc_set_destructor(li, fr_io_listen_free);
248 
249  li->app_io = inst->app_io;
250  li->thread_instance = talloc_zero_array(NULL, uint8_t, li->app_io->common.thread_inst_size);
251  talloc_set_name(li->thread_instance, "proto_%s_thread_t", inst->app_io->common.name);
252  li->app_io_instance = inst->app_io_instance;
253  li->name = "ldap_sync main listener";
254 
255  li->app = &proto_ldap_sync;
256  li->app_instance = instance;
257  li->server_cs = inst->server_cs;
258  li->non_socket_listener = true;
259 
260  /*
261  * Set configurable parameters for message ring buffer.
262  */
263  li->default_message_size = inst->max_packet_size;
264  li->num_messages = inst->num_messages;
265 
266  if (!fr_schedule_listen_add(sc, li)) {
267  talloc_free(li);
268  return -1;
269  }
270 
271  inst->listen = li;
272  inst->sc = sc;
273 
274  return 0;
275 }
276 
277 static int mod_instantiate(module_inst_ctx_t const *mctx)
278 {
279  proto_ldap_sync_t *inst = talloc_get_type_abort(mctx->inst->data, proto_ldap_sync_t);
280  CONF_SECTION *conf = mctx->inst->conf;
281  CONF_SECTION *sync_cs;
282  sync_config_t *sync_conf;
283  size_t i;
284  fr_pair_t *vp;
285  CONF_SECTION *map_cs;
286  map_t *map;
287  tmpl_rules_t parse_rules = {
288  /* Strict rules for the update map as it's processed with limited functionality */
289  .attr = {
291  .list_def = request_attr_request,
292  .allow_foreign = false,
293  .allow_unknown = false,
294  .allow_unresolved = false,
295  .list_presence = TMPL_ATTR_LIST_FORBID,
296  }
297  };
298 
299  /*
300  * Instantiate the I/O module.
301  */
302  if (inst->app_io->common.instantiate &&
303  (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule)) < 0)) {
304  cf_log_err(conf, "Instantiation failed for \"%s\"", inst->app_io->common.name);
305  return -1;
306  }
307 
308  /*
309  * These configuration items are not printed by default,
310  * because normal people shouldn't be touching them.
311  */
312  if (!inst->max_packet_size) inst->max_packet_size = inst->app_io->default_message_size;
313  if (!inst->num_messages) inst->num_messages = 2;
314 
315  FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, >=, 2);
316  FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, <=, 65535);
317 
318  FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, 1024);
319  FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, 65536);
320 
321  if (!inst->priority) inst->priority = PRIORITY_NORMAL;
322 
323  /*
324  * Parse each of the sync sections
325  */
326  for (sync_cs = cf_section_find(conf, "sync", NULL), i = 0;
327  sync_cs;
328  sync_cs = cf_section_find_next(conf, sync_cs, "sync", NULL), i++) {
329  sync_conf = inst->sync_config[i];
330  sync_conf->cs = sync_cs;
331 
332  /*
333  * Convert scope string to enumerated constant
334  */
335  sync_conf->scope = fr_table_value_by_str(fr_ldap_scope, sync_conf->scope_str, -1);
336  if (sync_conf->scope < 0) {
337  cf_log_err(conf, "Invalid 'search.scope' value \"%s\", expected 'sub', 'one', 'base' or 'children'",
338  sync_conf->scope_str);
339  return -1;
340  }
341 
342  map_cs = cf_section_find(sync_cs, "update", NULL);
343  map_list_init(&sync_conf->entry_map);
344  if (map_cs && map_afrom_cs(inst, &sync_conf->entry_map, map_cs,
345  &parse_rules, &parse_rules, fr_ldap_map_verify, NULL,
346  LDAP_MAX_ATTRMAP) < 0) {
347  return -1;
348  }
349 
350  /*
351  * Initialise a NULL terminated list of attributes
352  */
353  sync_conf->attrs = talloc_array(sync_conf, char const *, 1);
354  sync_conf->attrs[0] = NULL;
355 
356  if (map_list_empty(&sync_conf->entry_map)) {
357  cf_log_warn(conf, "LDAP sync specified without update map");
358  continue;
359  }
360 
361  /*
362  * Build the required list of attributes from the update map,
363  * checking validity as we go.
364  */
365  map = NULL;
366  while ((map = map_list_next(&sync_conf->entry_map, map))) {
367  if (fr_type_is_structural(tmpl_attr_tail_da(map->lhs)->type)) {
368  cf_log_err(map->ci, "Structural attribute \"%s\" invalid for LDAP sync update",
369  tmpl_attr_tail_da(map->lhs)->name);
370  return -1;
371  }
372 
373  switch(map->op) {
374  case T_OP_EQ:
375  case T_OP_ADD_EQ:
376  break;
377 
378  default:
379  cf_log_err(map->ci, "Operator \"%s\" invalid for LDAP sync update",
380  fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));
381  return -1;
382  }
383 
384  DEBUG3("Adding %s to attribute list", map->rhs->name);
385  ldap_sync_conf_attr_add(sync_conf, map->rhs->name);
386  }
387 
388  /*
389  * Build the list of pairs representing the sync config
390  */
391  fr_pair_list_init(&sync_conf->sync_pairs);
392 
394  sync_conf->base_dn, strlen(sync_conf->base_dn), false);
395  if (!vp) return -1;
396 
398  (uint32_t)sync_conf->scope, false);
399  if (!vp) return -1;
400 
401  if (sync_conf->filter) {
403  sync_conf->filter, strlen(sync_conf->filter), false);
404  if (!vp) return -1;
405  }
406  }
407 
408  return 0;
409 }
410 
411 static int mod_bootstrap(module_inst_ctx_t const *mctx)
412 {
413  proto_ldap_sync_t *inst = talloc_get_type_abort(mctx->inst->data, proto_ldap_sync_t);
414  CONF_SECTION *conf = mctx->inst->conf;
415 
416  inst->server_cs = cf_item_to_section(cf_parent(conf));
417  inst->cs = conf;
418  inst->self = &proto_ldap_sync;
419 
420  if (!inst->io_submodule) {
421  cf_log_err(conf, "Virtual server for LDAP sync requires a 'transport' configuration");
422  return -1;
423  }
424 
425  /*
426  * Bootstrap the I/O module
427  */
428  inst->app_io = (fr_app_io_t const *) inst->io_submodule->module->common;
429  inst->app_io_instance = inst->io_submodule->data;
430  inst->app_io_conf = inst->io_submodule->conf;
431 
432  if (inst->app_io->common.bootstrap &&
433  (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule)) < 0)) {
434  cf_log_err(inst->app_io_conf, "Bootstrap failed for \"%s\"", inst->app_io->common.name);
435  return -1;
436  }
437 
438  return 0;
439 }
440 
442  .common = {
443  .magic = MODULE_MAGIC_INIT,
444  .name = "ldap_sync",
445  .config = proto_ldap_sync_config,
446  .inst_size = sizeof(proto_ldap_sync_t),
447 
448  .bootstrap = mod_bootstrap,
450  },
451 
452  .dict = &dict_ldap_sync,
453 
454  .open = mod_open,
455  .decode = mod_decode,
456  .encode = mod_encode,
457 };
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:626
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:486
#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:406
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:420
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:400
#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:563
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:629
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:970
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1511
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1680
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:649
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:991
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:220
#define cf_parent(_cf)
Definition: cf_util.h:98
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
Definition: cf_util.h:137
#define cf_log_warn(_cf, _fmt,...)
Definition: cf_util.h:266
#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:762
#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:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
int dl_module_instance(TALLOC_CTX *ctx, dl_module_inst_t **out, dl_module_inst_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name)
Load a module and parse its CONF_SECTION in one operation.
Definition: dl_module.c:552
char const * dl_module_inst_name_from_conf(CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: dl_module.c:584
int dl_module_conf_parse(dl_module_inst_t *dl_inst, CONF_SECTION *conf)
Definition: dl_module.c:594
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition: dl_module.h:71
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
CONF_SECTION *_CONST conf
Module's instance configuration.
Definition: dl_module.h:166
A module/inst tuple.
Definition: dl_module.h:162
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:2915
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:1015
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
#define MODULE_INST_CTX(_dl_inst)
Wrapper to create a module_inst_ctx_t as a compound literal.
Definition: module_ctx.h:153
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:52
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:51
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:688
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:541
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:188
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 int mod_bootstrap(module_inst_ctx_t const *mctx)
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)
static int transport_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
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:41
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1312
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:823
The scheduler.
Definition: schedule.c:125
size_t thread_inst_size
Definition: module.h:151
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Definition: tmpl.h:796
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
if(!subtype_vp) goto fail
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:134
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition: talloc.c:740
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:285
#define fr_pair_list_append_by_da_parent_len(_ctx, _vp, _list, _attr, _val, _len, _tainted)
Definition: pair.h:330
#define fr_pair_list_append_by_da_parent(_ctx, _vp, _list, _attr, _val, _tainted)
Definition: pair.h:319
static fr_slen_t parent
Definition: pair.h:844
#define fr_type_is_structural(_x)
Definition: types.h:371
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984