21 #define AFW_IMPLEMENTATION_ID "ldap"
33 self->pub.inf = &impl_afw_adaptor_session_inf;
35 self->pub.p = xctx->p;
36 self->adaptor = adaptor;
39 afw_ldap_internal_session_begin(
self, xctx);
58 afw_ldap_internal_session_end(
self);
96 if (afw_ldap_metadata_handles(object_type_id))
99 self, object_type_id, criteria, context, callback, xctx);
105 if (adaptor_type_specific) {
107 &afw_ldap_s_base, xctx);
114 if (object_type_id) {
128 if (criteria && criteria->filter) {
129 filter = afw_ldap_internal_expression_from_query_criteria(
130 self, criteria->filter, xctx);
135 filter = filter_class;
140 msgid = ldap_search(self->ld, base_z, LDAP_SCOPE_SUBTREE,
141 (
char *)filter_z, afw_ldap_internal_allattrs, 0);
143 ldap_get_option(self->ld, LDAP_OPT_ERROR_NUMBER, &err);
145 "ldap_search() failed.", xctx);
153 rv = ldap_result(self->ld, msgid, 0, &adaptor->timeout, &res);
155 ldap_get_option(self->ld, LDAP_OPT_ERROR_NUMBER, &err);
157 "ldap_result() failed", xctx);
161 "ldap_result() timeout.", xctx);
163 if (rv == LDAP_RES_SEARCH_RESULT) {
166 if (rv != LDAP_RES_SEARCH_ENTRY) {
168 "ldap_result() unexpected return value", xctx);
172 e = ldap_first_entry(self->ld, res);
174 object_id = afw_ldap_internal_get_object_id(
self, e,
true, xctx);
175 o = afw_ldap_internal_create_object_from_entry(
self, object_type_id,
176 object_id, e, xctx->p, xctx);
178 abandon = callback(o, context, xctx);
180 ldap_abandon(self->ld, msgid);
183 e = ldap_next_entry(self->ld, e);
206 callback(NULL, context, xctx);
239 if (afw_ldap_metadata_handles(object_type_id))
242 self, object_type_id, object_id, context, callback, xctx);
251 ldap_scope = LDAP_SCOPE_BASE;
255 rv = ldap_search_s(self->ld, (
char *)dn_z, ldap_scope, (
char *)filter_z,
256 afw_ldap_internal_allattrs, 0, &res);
259 afw_ldap_internal_cleanup_ldap_msgfree, xctx);
261 if (rv != LDAP_SUCCESS) {
267 count = ldap_count_entries(self->ld, res);
273 "Expecting ldap_search_s() to return exactly 1 entry but "
279 e = ldap_first_entry(self->ld, res);
282 "ldap_first_entry() failed.", xctx);
286 obj = afw_ldap_internal_create_object_from_entry(
self, object_type_id,
287 object_id, e, xctx->p, xctx);
288 callback(obj, context, xctx);
312 apr_array_header_t *mods;
316 struct berval **bvals;
322 if (afw_ldap_metadata_handles(object_type_id))
328 if (suggested_object_id == NULL) {
330 "An objectId is required for LDAP operations.",
335 first_attribute = apr_hash_get(metadata->object_type_attributes,
336 object_type_id->s, object_type_id->len);
337 if (!first_attribute) {
349 mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
350 mod->mod_type =
"objectClass";
353 (*bvals)->bv_len = (ber_len_t)object_type_id->len;
354 (*bvals)->bv_val = (
char *)object_type_id->s;
355 mod->mod_vals.modv_bvals = bvals;
356 APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
361 &iterator, &property_name, xctx)))
364 first_attribute, property_name);
365 if (!attribute || attribute->attribute_type->never_allow_write) {
369 bvals = afw_ldap_metadata_value_to_bv(
self, property_name, value,
373 mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
375 property_name->s, property_name->len);
376 mod->mod_vals.modv_bvals = bvals;
377 APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
382 APR_ARRAY_PUSH(mods, LDAPMod *) = NULL;
388 rv = ldap_add_s(self->ld, dn_z, (LDAPMod * *)mods->elts);
389 if (rv != LDAP_SUCCESS) {
398 return suggested_object_id;
422 apr_array_header_t *mods;
430 if (afw_ldap_metadata_handles(object_type_id))
436 first_attribute = apr_hash_get(metadata->object_type_attributes,
437 object_type_id->s, object_type_id->len);
438 if (!first_attribute) {
448 for (e = entry; *e; e++) {
451 if (!(*e)->first_property_name_entry ||
452 (*e)->first_property_name_entry->next)
455 "LDAP adaptor only allows entity properties to be modified",
458 property_name = &(*e)->first_property_name_entry->property_name;
462 first_attribute, property_name);
463 if (!attribute || attribute->attribute_type->never_allow_write)
474 property_name->s, property_name->len);
476 (*e)->first_property_name_entry->property_name.s,
477 (*e)->first_property_name_entry->property_name.len);
479 switch ((*e)->type) {
481 case afw_adaptor_modify_entry_type_add_value:
482 mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
483 mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(
self,
484 property_name, (*e)->value, xctx);
487 case afw_adaptor_modify_entry_type_remove_property:
488 mod->mod_op = LDAP_MOD_DELETE;
491 case afw_adaptor_modify_entry_type_remove_value:
492 mod->mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
493 mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(
self,
494 property_name, (*e)->value, xctx);
497 case afw_adaptor_modify_entry_type_set_property:
498 mod->mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
499 mod->mod_vals.modv_bvals = afw_ldap_metadata_value_to_bv(
self,
500 property_name, (*e)->value, xctx);
505 "Unsupported entry type %d", (*e)->type);
508 APR_ARRAY_PUSH(mods, LDAPMod *) = mod;
512 APR_ARRAY_PUSH(mods, LDAPMod *) = NULL;
518 rv = ldap_modify_s(self->ld, dn_z, (LDAPMod * *)mods->elts);
519 if (rv != LDAP_SUCCESS) {
548 "LDAP adaptor does not support replace_object()",
572 if (afw_ldap_metadata_handles(object_type_id))
581 rv = ldap_delete_s(self->ld, dn_z);
582 if (rv != LDAP_SUCCESS) {
608 impl_afw_adaptor_session_get_journal_interface(
649 impl_afw_adaptor_session_get_object_type_cache_interface(
657 &self->object_type_cache,
659 instance,
true, xctx);
661 return &
self->object_type_cache;
Adaptive Framework Core API.
Helpers for adaptor implementation development.
Interface afw_interface implementation declares.
afw_ldap_internal_adaptor_session_t * afw_ldap_internal_adaptor_session_create(afw_ldap_internal_adaptor_t *adaptor, afw_xctx_t *xctx)
Internal create an LDAP adaptor session.
Adaptive Framework LDAP Internal Header
afw_adaptor_impl_object_type_cache_initialize(afw_adaptor_object_type_cache_t *object_type_cache, const afw_adaptor_object_type_cache_inf_t *inf, const afw_adaptor_session_t *session, afw_boolean_t all_object_types_immutable, afw_xctx_t *xctx)
Initialize object type cache instance.
afw_adaptor_impl_object_type_cache_inf
inf for an implementation of afw_adaptor_object_type_cache.
void impl_afw_adaptor_session_modify_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_adaptor_modify_entry_t *const *entry, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_replace_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *replacement_object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_delete_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_retrieve_objects(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_query_criteria_t *criteria, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_transaction_t * impl_afw_adaptor_session_begin_transaction(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
void impl_afw_adaptor_session_destroy(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_adaptor_impl_index_t * impl_afw_adaptor_session_get_index_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
const afw_utf8_t * impl_afw_adaptor_session_add_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *suggested_object_id, const afw_object_t *object, const afw_object_t *adaptor_type_specific, afw_xctx_t *xctx)
void impl_afw_adaptor_session_get_object(const afw_adaptor_session_t *instance, const afw_adaptor_impl_request_t *impl_request, const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, void *context, afw_object_cb_t callback, const afw_object_t *adaptor_type_specific, const afw_pool_t *p, afw_xctx_t *xctx)
const afw_adaptor_key_value_t * impl_afw_adaptor_session_get_key_value_interface(const afw_adaptor_session_t *instance, afw_xctx_t *xctx)
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
afw_boolean_t(* afw_object_cb_t)(const afw_object_t *object, void *context, afw_xctx_t *xctx)
Typedef for afw_adaptor_session_object callback.
struct afw_iterator_s afw_iterator_t
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
#define AFW_FINALLY
Always executed regardless of error.
#define AFW_THROW_ERROR_RV_Z(code, rv_source_id, rv, message_z, xctx)
Macro used to set error and rv in xctx and throw it.
#define AFW_ENDTRY
Ends an AFW try block.
#define AFW_TRY
Begin an AFW TRY block.
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
#define AFW_OBJECT_OPTION_IS(_options, _option)
Test mask.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_register_cleanup_before(instance, data, data2, cleanup, xctx)
Call method register_cleanup_before of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_utf8_z_create(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Create a NFC Normalized zero terminated UTF-8 string in specified pool.
const afw_utf8_z_t * afw_utf8_to_utf8_z(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Convert utf8 to utf8_z in specified pool.
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Interface afw_adaptor_impl_index public struct.
Internal request info used by afw_adaptor_impl*() functions.
const afw_object_options_t * options
Object options.
Interface afw_adaptor_journal public struct.
Interface afw_adaptor_key_value public struct.
Interface afw_adaptor_object_type_cache public struct.
Interface afw_adaptor public struct.
Interface afw_adaptor_session public struct.
Interface afw_adaptor_transaction public struct.
Interface afw_object public struct.
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Interface afw_value public struct.
Interface afw_xctx public struct.