1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* 18 * apr_ldap_init.c: LDAP v2/v3 common initialise 19 * 20 * Original code from auth_ldap module for Apache v1.3: 21 * Copyright 1998, 1999 Enbridge Pipelines Inc. 22 * Copyright 1999-2001 Dave Carrigan 23 */ 24 25#include "apr.h" 26#include "apu.h" 27#include "apu_config.h" 28 29#if APU_DSO_BUILD 30#define APU_DSO_LDAP_BUILD 31#endif 32 33#include "apr_ldap.h" 34#include "apu_internal.h" 35#include "apr_errno.h" 36#include "apr_pools.h" 37#include "apr_strings.h" 38 39#if APR_HAS_LDAP 40 41/** 42 * APR LDAP SSL Initialise function 43 * 44 * This function initialises SSL on the underlying LDAP toolkit 45 * if this is necessary. 46 * 47 * If a CA certificate is provided, this is set, however the setting 48 * of certificates via this method has been deprecated and will be removed in 49 * APR v2.0. 50 * 51 * The apr_ldap_set_option() function with the APR_LDAP_OPT_TLS_CERT option 52 * should be used instead to set certificates. 53 * 54 * If SSL support is not available on this platform, or a problem 55 * was encountered while trying to set the certificate, the function 56 * will return APR_EGENERAL. Further LDAP specific error information 57 * can be found in result_err. 58 */ 59APU_DECLARE_LDAP(int) apr_ldap_ssl_init(apr_pool_t *pool, 60 const char *cert_auth_file, 61 int cert_file_type, 62 apr_ldap_err_t **result_err) 63{ 64 65 apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t)); 66 *result_err = result; 67 68#if APR_HAS_LDAP_SSL /* compiled with ssl support */ 69 70 /* Novell */ 71#if APR_HAS_NOVELL_LDAPSDK 72 ldapssl_client_init(NULL, NULL); 73#endif 74 75 /* if a certificate was specified, set it */ 76 if (cert_auth_file) { 77 apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_pcalloc(pool, sizeof(apr_ldap_opt_tls_cert_t)); 78 cert->type = cert_file_type; 79 cert->path = cert_auth_file; 80 return apr_ldap_set_option(pool, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, result_err); 81 } 82 83#else /* not compiled with SSL Support */ 84 if (cert_auth_file) { 85 result->reason = "LDAP: Attempt to set certificate store failed. " 86 "Not built with SSL support"; 87 result->rc = -1; 88 } 89#endif /* APR_HAS_LDAP_SSL */ 90 91 if (result->rc != -1) { 92 result->msg = ldap_err2string(result->rc); 93 } 94 95 if (LDAP_SUCCESS != result->rc) { 96 return APR_EGENERAL; 97 } 98 99 return APR_SUCCESS; 100 101} 102 103 104/** 105 * APR LDAP SSL De-Initialise function 106 * 107 * This function tears down any SSL certificate setup previously 108 * set using apr_ldap_ssl_init(). It should be called to clean 109 * up if a graceful restart of a service is attempted. 110 * 111 * This function only does anything on Netware. 112 * 113 * @todo currently we do not check whether apr_ldap_ssl_init() 114 * has been called first - should we? 115 */ 116APU_DECLARE_LDAP(int) apr_ldap_ssl_deinit(void) 117{ 118 119#if APR_HAS_LDAP_SSL && APR_HAS_LDAPSSL_CLIENT_DEINIT 120 ldapssl_client_deinit(); 121#endif 122 return APR_SUCCESS; 123 124} 125 126 127/** 128 * APR LDAP initialise function 129 * 130 * This function is responsible for initialising an LDAP 131 * connection in a toolkit independant way. It does the 132 * job of ldap_init() from the C api. 133 * 134 * It handles both the SSL and non-SSL case, and attempts 135 * to hide the complexity setup from the user. This function 136 * assumes that any certificate setup necessary has already 137 * been done. 138 * 139 * If SSL or STARTTLS needs to be enabled, and the underlying 140 * toolkit supports it, the following values are accepted for 141 * secure: 142 * 143 * APR_LDAP_NONE: No encryption 144 * APR_LDAP_SSL: SSL encryption (ldaps://) 145 * APR_LDAP_STARTTLS: Force STARTTLS on ldap:// 146 */ 147APU_DECLARE_LDAP(int) apr_ldap_init(apr_pool_t *pool, 148 LDAP **ldap, 149 const char *hostname, 150 int portno, 151 int secure, 152 apr_ldap_err_t **result_err) 153{ 154 155 apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t)); 156 *result_err = result; 157 158#if APR_HAS_LDAPSSL_INIT 159#if APR_HAS_SOLARIS_LDAPSDK 160 /* 161 * Using the secure argument should aways be possible. But as LDAP SDKs 162 * tend to have different quirks and bugs, this needs to be tested for 163 * for each of them, first. For Solaris LDAP it works, and the method 164 * with ldap_set_option doesn't. 165 */ 166 *ldap = ldapssl_init(hostname, portno, secure == APR_LDAP_SSL); 167#else 168 *ldap = ldapssl_init(hostname, portno, 0); 169#endif 170#elif APR_HAS_LDAP_SSLINIT 171 *ldap = ldap_sslinit((char *)hostname, portno, 0); 172#else 173 *ldap = ldap_init((char *)hostname, portno); 174#endif 175 176 if (*ldap != NULL) { 177#if APR_HAS_SOLARIS_LDAPSDK 178 if (secure == APR_LDAP_SSL) 179 return APR_SUCCESS; 180 else 181#endif 182 return apr_ldap_set_option(pool, *ldap, APR_LDAP_OPT_TLS, &secure, result_err); 183 } 184 else { 185 /* handle the error case */ 186 apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t)); 187 *result_err = result; 188 189 result->reason = "APR LDAP: Unable to initialize the LDAP connection"; 190 result->rc = -1; 191 return APR_EGENERAL; 192 } 193 194} 195 196 197/** 198 * APR LDAP info function 199 * 200 * This function returns a string describing the LDAP toolkit 201 * currently in use. The string is placed inside result_err->reason. 202 */ 203APU_DECLARE_LDAP(int) apr_ldap_info(apr_pool_t *pool, 204 apr_ldap_err_t **result_err) 205{ 206 apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t)); 207 *result_err = result; 208 209 result->reason = "APR LDAP: Built with " 210 LDAP_VENDOR_NAME 211 " LDAP SDK"; 212 return APR_SUCCESS; 213 214} 215 216#if APU_DSO_BUILD 217 218/* For DSO builds, export the table of entry points into the apr_ldap DSO 219 * See include/private/apu_internal.h for the corresponding declarations 220 */ 221APU_MODULE_DECLARE_DATA struct apr__ldap_dso_fntable apr__ldap_fns = { 222 apr_ldap_info, 223 apr_ldap_init, 224 apr_ldap_ssl_init, 225 apr_ldap_ssl_deinit, 226 apr_ldap_get_option, 227 apr_ldap_set_option, 228 apr_ldap_rebind_init, 229 apr_ldap_rebind_add, 230 apr_ldap_rebind_remove 231}; 232 233#endif /* APU_DSO_BUILD */ 234 235#endif /* APR_HAS_LDAP */ 236