25 #define LOG_PREFIX "ldap_sync_persistent"
29 #include <freeradius-devel/ldap/base.h>
30 #include <freeradius-devel/util/debug.h>
55 static char const *notify_oid = LDAP_CONTROL_PERSIST_REQUEST;
56 LDAPControl ctrl = {0}, *ctrls[2] = { &ctrl, NULL };
57 BerElement *ber = NULL;
80 ber = ber_alloc_t(LBER_USE_DER);
82 ERROR(
"Failed allocating sync control");
88 memcpy(&ctrl.ldctl_oid, ¬ify_oid,
sizeof(ctrl.ldctl_oid));
96 ber_printf(ber,
"{ibb}", LDAP_CONTROL_PERSIST_ENTRY_CHANGE_ADD |
97 LDAP_CONTROL_PERSIST_ENTRY_CHANGE_DELETE |
98 LDAP_CONTROL_PERSIST_ENTRY_CHANGE_MODIFY |
99 LDAP_CONTROL_PERSIST_ENTRY_CHANGE_RENAME,
100 config->changes_only,
true );
101 ret = ber_flatten2(ber, &ctrl.ldctl_value, 0);
103 ERROR(
"Failed creating sync control");
109 memcpy(&ctrl.ldctl_oid, ¬ify_oid,
sizeof(ctrl.ldctl_oid));
114 ctrl.ldctl_iscritical = 1;
121 ERROR(
"Failed to start persistent search query");
126 ERROR(
"Duplicate sync (msgid %i)", sync->
msgid);
130 DEBUG3(
"Sync created with base dn \"%s\", filter \"%s\", msgid %i",
182 BerElement *ber = NULL;
184 int change_type, change_no;
185 struct berval orig_dn = { 0, NULL };
201 ERROR(
"searchResEntry missing EntryChangeNotification control");
224 for (i = 0; ctrls[i] != NULL; i++) {
225 if (strcmp(ctrls[i]->ldctl_oid, LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE) == 0)
break;
227 if (!ctrls[i])
goto missing_control;
234 ber = ber_init(&ctrls[i]->ldctl_value);
236 ERROR(
"Failed allocating ber to handle syncStateValue control");
239 if (ber) ber_free(ber, 1);
246 if (ber_scanf(ber,
"{e", &change_type) == LBER_ERROR) {
247 ERROR(
"Maformed EntryChangeNotification control");
254 if ((change_type == LDAP_CONTROL_PERSIST_ENTRY_CHANGE_RENAME) &&
255 (ber_scanf(ber,
"m", &orig_dn) == LBER_ERROR)) {
256 ERROR(
"Maformed EntryChangeNotification for entry modification");
260 if (ber_peek_tag(ber, &len) == 0x02) {
261 if (ber_scanf(ber,
"i", &change_no) == LBER_ERROR) {
262 ERROR(
"Malformed changeNumber control");
269 sync->
cookie = (
uint8_t *)talloc_asprintf(sync,
"%d", change_no);
273 if (ber_scanf(ber,
"}") == LBER_ERROR) {
274 ERROR(
"Malformed syncStatevalue sequence");
281 switch(change_type) {
282 case LDAP_CONTROL_PERSIST_ENTRY_CHANGE_ADD:
285 case LDAP_CONTROL_PERSIST_ENTRY_CHANGE_DELETE:
288 case LDAP_CONTROL_PERSIST_ENTRY_CHANGE_MODIFY:
291 case LDAP_CONTROL_PERSIST_ENTRY_CHANGE_RENAME:
295 ERROR(
"Invalid changeType returned");
303 DEBUG3(
"Processing searchResEntry (%s), dn \"%s\"",
305 entry_dn ? entry_dn :
"<unknown>");
307 ldap_memfree(entry_dn);
#define fr_event_timer_in(...)
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
LDAP * handle
libldap handle.
void * uctx
User data associated with the handle.
connection_t * conn
Connection state handle.
@ LDAP_PROC_SUCCESS
Operation was successful.
Tracks the state of a libldap connection handle.
fr_ldap_rcode_t fr_ldap_search_async(int *msgid, request_t *request, fr_ldap_connection_t *pconn, char const *dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Search for something in the LDAP directory.
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
int persistent_sync_search_entry(sync_state_t *sync, LDAPMessage *msg, LDAPControl **ctrls)
Handle a SearchResultEntry response from Persistent Search LDAP servers.
int persistent_sync_state_init(fr_ldap_connection_t *conn, size_t sync_no, proto_ldap_sync_t const *inst, UNUSED uint8_t const *cookie)
Allocate and initialise sync queries for persistent searches.
static const conf_parser_t config[]
char const * filter
Filter to retrieve only user objects.
sync_op_t
Operations to perform on entries.
@ SYNC_OP_ADD
Entry should be added to our copy.
@ SYNC_OP_MODIFY
Entry should be updated in our copy.
@ SYNC_OP_INVALID
Invalid sync operation.
@ SYNC_OP_DELETE
Entry should be deleted from our copy.
char const * base_dn
DN to search for users under.
An instance of a proto_ldap_sync listen section.
Areas of the directory to receive notifications for.
int ldap_sync_cookie_store(sync_state_t *sync, bool refresh)
Add a new cookie packet ctx to the pending list.
int ldap_sync_entry_send(sync_state_t *sync, uint8_t const uuid[SYNC_UUID_LENGTH], struct berval *orig_dn, LDAPMessage *msg, sync_op_t op)
Enqueue a new entry change packet.
fr_table_num_sorted_t const sync_op_table[]
Operations performed on entries.
sync_state_t * sync_state_alloc(TALLOC_CTX *ctx, fr_ldap_connection_t *conn, proto_ldap_sync_t const *inst, size_t sync_no, sync_config_t const *config)
Allocate a sync state.
void ldap_sync_cookie_event(fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Event to handle storing of cookies on a timed basis.
int8_t sync_state_cmp(void const *one, void const *two)
Compare two sync state structures on msgid.
uint8_t * cookie
Opaque cookie, used to resume synchronisation.
sync_phases_t phase
Phase this sync is in.
int msgid
The unique identifier for this sync session.
sync_config_t const * config
Configuration for this sync.
@ SYNC_PHASE_DONE
Refresh phase is complete.
@ SYNC_PHASE_INIT
We haven't entered any of the refresh phases.
fr_event_timer_t const * cookie_ev
Timer event for sending cookies.
fr_ldap_connection_t * conn
Connection the sync is running on.
fr_pair_list_t trigger_args
Arguments to make available in triggers.
State of an individual sync.
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
The main red black tree structure.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
int trigger_exec(unlang_interpret_t *intp, CONF_SECTION const *cs, char const *name, bool rate_limit, fr_pair_list_t *args)
Execute a trigger - call an executable to process an event.