blob: cde8a194096dda9f978140805f01d2f2cc144cca [file] [log] [blame]
/* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.
*/
/*
* apr_ldap_init.c: LDAP v2/v3 common initialise
*
* Original code from auth_ldap module for Apache v1.3:
* Copyright 1998, 1999 Enbridge Pipelines Inc.
* Copyright 1999-2001 Dave Carrigan
*/
#include <apu.h>
#include <apr_ldap.h>
#include <apr_errno.h>
#include <apr_pools.h>
#include <apr_strings.h>
#if APR_HAS_LDAP
/**
* APR LDAP SSL Initialise function
*
* This function sets up any SSL certificate parameters as
* required by the application. It should be called once on
* system initialisation.
*
* If SSL support is not available on this platform, or a problem
* was encountered while trying to set the certificate, the function
* will return APR_EGENERAL. Further LDAP specific error information
* can be found in result_err.
*/
APU_DECLARE(int) apr_ldap_ssl_init(apr_pool_t *pool,
const char *cert_auth_file,
int cert_file_type,
apr_ldap_err_t **result_err) {
apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
*result_err = result;
if (cert_auth_file) {
#if APR_HAS_LDAP_SSL /* compiled with ssl support */
#if APR_HAS_NETSCAPE_LDAPSDK
/* Netscape sdk only supports a cert7.db file
*/
if (cert_file_type == APR_LDAP_CA_TYPE_CERT7_DB) {
result->rc = ldapssl_client_init(cert_auth_file, NULL);
}
else {
result->reason = "LDAP: Invalid certificate type: "
"CERT7_DB type required";
result->rc = -1;
}
#elif APR_HAS_NOVELL_LDAPSDK
/* Novell SDK supports DER or BASE64 files
*/
if (cert_file_type == APR_LDAP_CA_TYPE_DER ||
cert_file_type == APR_LDAP_CA_TYPE_BASE64 ) {
result->rc = ldapssl_client_init(NULL, NULL);
if (LDAP_SUCCESS == result->rc) {
if (cert_file_type == APR_LDAP_CA_TYPE_BASE64) {
result->rc = ldapssl_add_trusted_cert((void*)cert_auth_file,
LDAPSSL_CERT_FILETYPE_B64);
}
else {
result->rc = ldapssl_add_trusted_cert((void*)cert_auth_file,
LDAPSSL_CERT_FILETYPE_DER);
}
if (LDAP_SUCCESS != result->rc) {
ldapssl_client_deinit();
result->reason = apr_psprintf (pool,
"LDAP: Invalid certificate or path: "
"Could not add trusted cert %s",
cert_auth_file);
}
}
}
else {
result->reason = "LDAP: Invalid certificate type: "
"DER or BASE64 type required";
result->rc = -1;
}
#elif APR_HAS_OPENLDAP_LDAPSDK
/* OpenLDAP SDK supports BASE64 files
*/
if (cert_file_type == APR_LDAP_CA_TYPE_BASE64) {
result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, cert_auth_file);
}
else {
result->reason = "LDAP: Invalid certificate type: "
"BASE64 type required";
result->rc = -1;
}
#elif APR_HAS_MICROSOFT_LDAPSDK
/* Microsoft SDK use the registry certificate store - always
* assume support is always available
*/
result->rc = LDAP_SUCCESS;
#else
/* unknown toolkit type, assume no support available */
result->reason = "LDAP: Attempt to set certificate store failed. "
"Toolkit type not recognised as supporting SSL.";
result->rc = -1;
#endif /* APR_HAS_NETSCAPE_LDAPSDK */
#else /* not compiled with SSL Support */
result->reason = "LDAP: Attempt to set certificate store failed. "
"Not built with SSL support.";
result->rc = -1;
#endif /* APR_HAS_LDAP_SSL */
if (result->rc != -1) {
result->msg = ldap_err2string(result-> rc);
}
if (LDAP_SUCCESS == result->rc) {
return APR_SUCCESS;
}
else {
return APR_EGENERAL;
}
}
/* if no cert_auth_file was passed, we assume SSL support
* is possible, as we have not been specifically told otherwise.
*/
return APR_SUCCESS;
}
/**
* APR LDAP SSL De-Initialise function
*
* This function tears down any SSL certificate setup previously
* set using apr_ldap_ssl_init(). It should be called to clean
* up if a graceful restart of a service is attempted.
*
* This function only does anything on Netware.
*
* @todo currently we do not check whether apr_ldap_ssl_init()
* has been called first - should we?
*/
APU_DECLARE(int) apr_ldap_ssl_deinit() {
#if APR_HAS_LDAP_SSL && APR_HAS_NOVELL_LDAPSDK
ldapssl_client_deinit();
#endif
return APR_SUCCESS;
}
/**
* APR LDAP initialise function
*
* This function is responsible for initialising an LDAP
* connection in a toolkit independant way. It does the
* job of ldap_init() from the C api.
*
* It handles both the SSL and non-SSL case, and attempts
* to hide the complexity setup from the user. This function
* assumes that any certificate setup necessary has already
* been done.
*/
APU_DECLARE(int) apr_ldap_init(apr_pool_t *pool,
LDAP **ldap,
const char *hostname,
int portno,
int secure,
apr_ldap_err_t **result_err) {
apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
*result_err = result;
/* clear connection requested */
if (!secure) {
#if APR_HAS_MICROSOFT_LDAPSDK
*ldap = ldap_init((char *)hostname, portno);
#else
*ldap = ldap_init(hostname, portno);
#endif
}
else { /* ssl connnection requested */
#if APR_HAS_LDAP_SSL
#if APR_HAS_NOVELL_LDAPSDK
*ldap = ldapssl_init(hostname, portno, 1);
#elif APR_HAS_NETSCAPE_LDAPSDK
*ldap = ldapssl_init(hostname, portno, 1);
#elif APR_HAS_OPENLDAP_LDAPSDK
*ldap = ldap_init(hostname, portno);
if (NULL != *ldap) {
int SSLmode = LDAP_OPT_X_TLS_HARD;
result->rc = ldap_set_option(*ldap, LDAP_OPT_X_TLS, &SSLmode);
if (LDAP_SUCCESS != result->rc) {
ldap_unbind_s(*ldap);
result->reason = "LDAP: ldap_set_option - LDAP_OPT_X_TLS_HARD failed";
result->msg = ldap_err2string(result->rc);
*ldap = NULL;
/* @todo make proper APR error codes for LDAP codes */
return APR_EGENERAL;
}
}
#elif APR_HAS_MICROSOFT_LDAPSDK
*ldap = ldap_sslinit((char *)hostname, portno, 1);
#else
/* unknown toolkit - return not implemented */
return APR_ENOTIMPL;
#endif /* APR_HAS_NOVELL_LDAPSDK */
#endif /* APR_HAS_LDAP_SSL */
}
/* if the attempt returned a NULL object, return an error
* from the os as per the LDAP C SDK.
*/
if (NULL == *ldap) {
return apr_get_os_error();
}
/* otherwise we were successful */
return APR_SUCCESS;
}
/**
* APR LDAP info function
*
* This function returns a string describing the LDAP toolkit
* currently in use. The string is placed inside result_err->reason.
*/
APU_DECLARE(int) apr_ldap_info(apr_pool_t *pool, apr_ldap_err_t **result_err)
{
apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
*result_err = result;
#if APR_HAS_NETSCAPE_LDAPSDK
result->reason = "APR LDAP: Built with Netscape LDAP SDK";
#elif APR_HAS_NOVELL_LDAPSDK
result->reason = "APR LDAP: Built with Novell LDAP SDK";
#elif APR_HAS_OPENLDAP_LDAPSDK
result->reason = "APR LDAP: Built with OpenLDAP LDAP SDK";
#elif APR_HAS_MICROSOFT_LDAPSDK
result->reason = "APR LDAP: Built with Microsoft LDAP SDK";
#else
result->reason = "APR LDAP: Built with an unknown LDAP SDK";
#endif
return APR_SUCCESS;
}
#endif /* APR_HAS_LDAP */