ldap/apr_ldap_stub.c (336 lines of code) (raw):

/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "apr.h" #include "apu.h" #include "apu_config.h" #include "apr_ldap.h" #include "apu_internal.h" #include "apr_atomic.h" #include "apr_dso.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_strings.h" #include "apu_version.h" #if APR_HAS_LDAP #if APU_DSO_BUILD static apr_pool_t *global; static struct apr__ldap_dso_fntable *lfn = NULL; static apr_uint32_t in_init = 0, initialised = 0; static apr_status_t apr_ldap_term(void *ptr) { if (apr_atomic_inc32(&in_init)) { while (apr_atomic_read32(&in_init) > 1); /* wait until we get fully inited */ } /* Reference count - cleanup when last reference is cleaned up */ if (!apr_atomic_dec32(&initialised)) { apr_pool_destroy(global); /* set statics to NULL so init can work again */ global = NULL; lfn = NULL; } apr_atomic_dec32(&in_init); /* Everything else we need is handled by cleanups registered * when we created mutexes and loaded DSOs */ return APR_SUCCESS; } static apr_status_t load_ldap(apr_pool_t *pool, const apr_ldap_driver_t **driver, apu_err_t *err) { char *modname; apr_dso_handle_sym_t symbol; apr_status_t rv; /* deprecate in 2.0 - permit implicit initialization */ apu_dso_init(pool); rv = apu_dso_mutex_lock(); if (rv) { return rv; } #if defined(WIN32) modname = "apr_ldap-" APR_STRINGIFY(APR_MAJOR_VERSION) ".dll"; #else modname = "apr_ldap-" APR_STRINGIFY(APR_MAJOR_VERSION) ".so"; #endif rv = apu_dso_load(NULL, &symbol, modname, "apr__ldap_fns", pool, err); if (rv == APR_SUCCESS || APR_EINIT == rv) { lfn = symbol; rv = APR_SUCCESS; } if (driver) { *driver = (apr_ldap_driver_t *)lfn; } apu_dso_mutex_unlock(); return rv; } #define LOAD_LEGACY_STUB(pool, err, failres) \ if (!lfn && (apr_ldap_get_driver(pool, NULL, err) != APR_SUCCESS)) \ return failres; #define LOAD_LDAP_STUB(pool, err) \ { \ apr_status_t status; \ if (!lfn && ((status = apr_ldap_get_driver(pool, NULL, err)) != APR_SUCCESS)) \ return status; \ } #define CHECK_LDAP_STUB(failres) \ if (!lfn) \ return failres; APU_DECLARE(apr_status_t) apr_ldap_get_driver(apr_pool_t *pool, const apr_ldap_driver_t **driver, apu_err_t *err) { apr_status_t status = APR_EREINIT; if (apr_atomic_inc32(&in_init)) { while (apr_atomic_read32(&in_init) > 1); /* wait until we get fully inited */ } /* Reference count increment... */ if (!apr_atomic_inc32(&initialised)) { apr_pool_create_unmanaged(&global); status = load_ldap(global, driver, err); } apr_pool_cleanup_register(pool, NULL, apr_ldap_term, apr_pool_cleanup_null); apr_atomic_dec32(&in_init); return status; } /* Legacy API */ APU_DECLARE_LDAP(int) apr_ldap_info(apr_pool_t *pool, apr_ldap_err_t **result_err) { LOAD_LEGACY_STUB(pool, NULL, -1); return lfn->info(pool, result_err); } APU_DECLARE_LDAP(int) apr_ldap_init(apr_pool_t *pool, LDAP **ldap, const char *hostname, int portno, int secure, apr_ldap_err_t **result_err) { LOAD_LEGACY_STUB(pool, NULL, -1); return lfn->init(pool, ldap, hostname, portno, secure, result_err); } APU_DECLARE_LDAP(int) apr_ldap_ssl_init(apr_pool_t *pool, const char *cert_auth_file, int cert_file_type, apr_ldap_err_t **result_err) { LOAD_LEGACY_STUB(pool, NULL, -1); return lfn->ssl_init(pool, cert_auth_file, cert_file_type, result_err); } APU_DECLARE_LDAP(int) apr_ldap_ssl_deinit(void) { if (!lfn) return -1; return lfn->ssl_deinit(); } APU_DECLARE_LDAP(int) apr_ldap_get_option(apr_pool_t *pool, LDAP *ldap, int option, void *outvalue, apr_ldap_err_t **result_err) { LOAD_LEGACY_STUB(pool, NULL, -1); return lfn->get_option(pool, ldap, option, outvalue, result_err); } APU_DECLARE_LDAP(int) apr_ldap_set_option(apr_pool_t *pool, LDAP *ldap, int option, const void *invalue, apr_ldap_err_t **result_err) { LOAD_LEGACY_STUB(pool, NULL, -1); return lfn->set_option(pool, ldap, option, invalue, result_err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_init(apr_pool_t *pool) { LOAD_LEGACY_STUB(pool, NULL, APR_EGENERAL); return lfn->rebind_init(pool); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_add(apr_pool_t *pool, LDAP *ld, const char *bindDN, const char *bindPW) { LOAD_LEGACY_STUB(pool, NULL, APR_EGENERAL); return lfn->rebind_add(pool, ld, bindDN, bindPW); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_remove(LDAP *ld) { if (!lfn) return APR_EGENERAL; return lfn->rebind_remove(ld); } /* Current API */ APU_DECLARE_LDAP(apr_status_t) apr_ldap_initialise(apr_pool_t *pool, apr_ldap_t **ldap, apu_err_t *err) { LOAD_LDAP_STUB(pool, err); return lfn->initialise(pool, ldap, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_option_get(apr_pool_t *pool, apr_ldap_t *ldap, int option, apr_ldap_opt_t *outvalue, apu_err_t *err) { LOAD_LDAP_STUB(pool, err); return lfn->option_get(pool, ldap, option, outvalue, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_option_set(apr_pool_t *pool, apr_ldap_t *ldap, int option, const apr_ldap_opt_t *invalue, apu_err_t *err) { LOAD_LDAP_STUB(pool, err); return lfn->option_set(pool, ldap, option, invalue, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_connect(apr_pool_t *pool, apr_ldap_t *ldap, apr_interval_time_t timeout, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->connect(pool, ldap, timeout, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_prepare(apr_pool_t *pool, apr_ldap_t *ldap, apr_ldap_prepare_cb prepare_cb, void *prepare_ctx) { CHECK_LDAP_STUB(APR_EINIT); return lfn->prepare(pool, ldap, prepare_cb, prepare_ctx); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_process(apr_pool_t *pool, apr_ldap_t *ldap, apr_interval_time_t timeout, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->process(pool, ldap, timeout, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_result(apr_pool_t *pool, apr_ldap_t *ldap, apr_interval_time_t timeout, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->result(pool, ldap, timeout, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_poll(apr_pool_t *pool, apr_ldap_t *ldap, apr_pollcb_t *poll, apr_interval_time_t timeout, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->poll(pool, ldap, poll, timeout, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_bind(apr_pool_t *pool, apr_ldap_t *ldap, const char *mech, apr_ldap_bind_interact_cb *interact_cb, void *interact_ctx, apr_interval_time_t timeout, apr_ldap_bind_cb bind_cb, void *bind_ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->bind(pool, ldap, mech, interact_cb, interact_ctx, timeout, bind_cb, bind_ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_compare(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, const char *attr, const apr_buffer_t *bval, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_compare_cb compare_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->compare(pool, ldap, dn, attr, bval, serverctrls, clientctrls, timeout, compare_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_search(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, apr_ldap_search_scope_e scope, const char *filter, const char **attrs, apr_ldap_switch_e attrsonly, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ssize_t sizelimit, apr_ldap_search_result_cb search_result_cb, apr_ldap_search_entry_cb search_entry_cb, void *search_ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->search(pool, ldap, dn, scope, filter, attrs, attrsonly, serverctrls, clientctrls, timeout, sizelimit, search_result_cb, search_entry_cb, search_ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_add(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, apr_array_header_t *adds, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_add_cb add_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->add(pool, ldap, dn, adds, serverctrls, clientctrls, timeout, add_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_modify(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, apr_array_header_t *mods, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_modify_cb modify_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->modify(pool, ldap, dn, mods, serverctrls, clientctrls, timeout, modify_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_rename(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, const char *newrdn, const char *newparent, apr_ldap_rename_e flags, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_rename_cb rename_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->rename(pool, ldap, dn, newrdn, newparent, flags, serverctrls, clientctrls, timeout, rename_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_delete(apr_pool_t *pool, apr_ldap_t *ldap, const char *dn, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_delete_cb delete_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->delete(pool, ldap, dn, serverctrls, clientctrls, timeout, delete_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_extended(apr_pool_t *pool, apr_ldap_t *ldap, const char *oid, apr_buffer_t *data, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apr_interval_time_t timeout, apr_ldap_extended_cb ext_cb, void *ctx, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->extended(pool, ldap, oid, data, serverctrls, clientctrls, timeout, ext_cb, ctx, err); } APU_DECLARE_LDAP(apr_status_t) apr_ldap_unbind(apr_ldap_t *ldap, apr_array_header_t *serverctrls, apr_array_header_t *clientctrls, apu_err_t *err) { CHECK_LDAP_STUB(APR_EINIT); return lfn->unbind(ldap, serverctrls, clientctrls, err); } #endif /* APU_DSO_BUILD */ #endif /* APR_HAS_LDAP */