ldap_connect.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ldap_connect.c 4585 2008-08-06 08:20:30Z klaus_darilion $
00003  *
00004  * Kamailio LDAP Module
00005  *
00006  * Copyright (C) 2007 University of North Carolina
00007  *
00008  * Original author: Christian Schlatter, cs@unc.edu
00009  *
00010  *
00011  * This file is part of Kamailio, a free SIP server.
00012  *
00013  * Kamailio is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version
00017  *
00018  * Kamailio is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  * History:
00028  * --------
00029  * 2007-02-18: Initial version
00030  */
00031 
00032 
00033 #include <string.h>
00034 #include <unistd.h>
00035 #include <stdio.h>
00036 
00037 #include <ldap.h>
00038 
00039 #include "ldap_connect.h"
00040 #include "ld_session.h"
00041 #include "../../mem/mem.h"
00042 #include "../../ut.h"
00043 
00044 int ldap_connect(char* _ld_name)
00045 {
00046    int rc;
00047    int ldap_bind_result_code;
00048    char *ldap_err_str;
00049    int ldap_proto_version;
00050    int msgid;
00051    LDAPMessage *result;
00052    struct ld_session* lds;
00053    struct berval ldap_cred;
00054 
00055    /*
00056    * get ld session and session config parameters
00057    */
00058    
00059    if ((lds = get_ld_session(_ld_name)) == NULL)
00060    {
00061       LM_ERR("ld_session [%s] not found\n", _ld_name);
00062       return -1;
00063    }
00064    
00065    /*
00066     * ldap_initialize
00067     */
00068 
00069    rc = ldap_initialize(&lds->handle, lds->host_name);
00070    if (rc != LDAP_SUCCESS)
00071    {
00072       LM_ERR(  "[%s]: ldap_initialize (%s) failed: %s\n",
00073          _ld_name,
00074          lds->host_name,
00075          ldap_err2string(rc));
00076       return -1;
00077    }
00078    
00079    /*
00080     * set LDAP OPTIONS
00081     */
00082 
00083    /* LDAP_OPT_PROTOCOL_VERSION */
00084    switch (lds->version) {
00085    case 2:
00086       ldap_proto_version = LDAP_VERSION2;
00087       break;
00088    case 3:
00089       ldap_proto_version = LDAP_VERSION3;
00090       break;
00091    default:
00092       LM_ERR(  "[%s]: Invalid LDAP protocol version [%d]\n",
00093          _ld_name, 
00094          lds->version);
00095       return -1;
00096    }
00097    if (ldap_set_option(lds->handle,
00098             LDAP_OPT_PROTOCOL_VERSION,
00099             &ldap_proto_version)
00100          != LDAP_OPT_SUCCESS) 
00101    {
00102       LM_ERR(  "[%s]: Could not set LDAP_OPT_PROTOCOL_VERSION [%d]\n",
00103          _ld_name, 
00104          ldap_proto_version);
00105       return -1;
00106    }
00107 
00108    /* LDAP_OPT_RESTART */
00109    if (ldap_set_option(lds->handle,
00110             LDAP_OPT_RESTART,
00111             LDAP_OPT_ON)
00112          != LDAP_OPT_SUCCESS) {
00113       LM_ERR("[%s]: Could not set LDAP_OPT_RESTART to ON\n", _ld_name);
00114       return -1;
00115    }
00116 
00117    /* LDAP_OPT_TIMELIMIT */
00118    /*
00119    if (lds->server_search_timeout > 0) {
00120       if (ldap_set_option(lds->handle,
00121             LDAP_OPT_TIMELIMIT,
00122             &lds->server_search_timeout)
00123          != LDAP_OPT_SUCCESS) {
00124          LM_ERR("[%s]: Could not set LDAP_OPT_TIMELIMIT to [%d]\n",
00125          _ld_name, lds->server_search_timeout);
00126          return -1;
00127       }
00128    }
00129    */
00130    
00131    /* LDAP_OPT_NETWORK_TIMEOUT */
00132    if ((lds->network_timeout.tv_sec > 0) || (lds->network_timeout.tv_usec > 0))
00133    {
00134       if (ldap_set_option(lds->handle,
00135                LDAP_OPT_NETWORK_TIMEOUT,
00136                (const void *)&lds->network_timeout)
00137             != LDAP_OPT_SUCCESS)
00138       {
00139          LM_ERR(  "[%s]: Could not set"
00140             " LDAP_NETWORK_TIMEOUT to [%d.%d]\n",
00141             _ld_name, 
00142             (int)lds->network_timeout.tv_sec,
00143             (int)lds->network_timeout.tv_usec);
00144       }
00145    }
00146    
00147    /*
00148      * ldap_sasl_bind (LDAP_SASL_SIMPLE)
00149     */
00150 
00151 
00152    ldap_cred.bv_val = lds->bind_pwd;
00153    ldap_cred.bv_len = strlen(lds->bind_pwd);
00154    rc = ldap_sasl_bind(
00155       lds->handle,
00156       lds->bind_dn,
00157       LDAP_SASL_SIMPLE,
00158       &ldap_cred,
00159       NULL,
00160       NULL,
00161       &msgid);
00162    if (rc != LDAP_SUCCESS)
00163    {
00164       LM_ERR(  "[%s]: ldap bind failed: %s\n",
00165          _ld_name,
00166          ldap_err2string(rc));
00167       return -1;
00168    }
00169 
00170 
00171 
00172    
00173    if ((lds->client_bind_timeout.tv_sec == 0) 
00174          && (lds->client_bind_timeout.tv_usec == 0))
00175    {
00176       rc = ldap_result(lds->handle, msgid, 1, NULL, &result);
00177    } else
00178    {
00179       rc = ldap_result(lds->handle, msgid, 1, &lds->client_bind_timeout,
00180             &result);
00181    }
00182 
00183 
00184    if (rc == -1)
00185    {
00186       ldap_get_option(lds->handle, LDAP_OPT_ERROR_NUMBER, &rc);
00187       ldap_err_str = ldap_err2string(rc);
00188       LM_ERR(  "[%s]: ldap_result failed: %s\n",
00189          _ld_name,
00190          ldap_err_str);
00191       return -1;
00192    } 
00193    else if (rc == 0)
00194    {
00195       LM_ERR("[%s]: bind operation timed out\n", _ld_name);
00196       return -1;
00197    }
00198 
00199 
00200    rc = ldap_parse_result(
00201       lds->handle,
00202       result,
00203       &ldap_bind_result_code,
00204       NULL,
00205       NULL,
00206       NULL,
00207       NULL,
00208       1);
00209    if (rc != LDAP_SUCCESS)
00210    {
00211       LM_ERR(  "[%s]: ldap_parse_result failed: %s\n",
00212          _ld_name, 
00213          ldap_err2string(rc));
00214       return -1;
00215    }
00216    if (ldap_bind_result_code != LDAP_SUCCESS)
00217    {
00218       LM_ERR(  "[%s]: ldap bind failed: %s\n",
00219          _ld_name, 
00220          ldap_err2string(ldap_bind_result_code));
00221       return -1;
00222    }
00223 
00224 
00225    /* freeing result leads to segfault ... bind result is probably used by openldap lib */
00226    /* ldap_msgfree(result); */
00227 
00228 
00229    LM_DBG(  "[%s]: LDAP bind successful (ldap_host [%s])\n",
00230       _ld_name, 
00231       lds->host_name);
00232 
00233    return 0;
00234 }
00235 
00236 int ldap_disconnect(char* _ld_name)
00237 {
00238    struct ld_session* lds;
00239 
00240    /*
00241       * get ld session
00242       */
00243 
00244    if ((lds = get_ld_session(_ld_name)) == NULL)
00245    {
00246       LM_ERR("ld_session [%s] not found\n", _ld_name);
00247       return -1;
00248    }
00249 
00250    if (lds->handle == NULL) {
00251       return 0;
00252    }
00253 
00254    ldap_unbind_ext(lds->handle, NULL, NULL);
00255    lds->handle = NULL;
00256 
00257    return 0;
00258 }
00259 
00260 int ldap_reconnect(char* _ld_name)
00261 {
00262    int rc;
00263    
00264    if (ldap_disconnect(_ld_name) != 0)
00265    {
00266       LM_ERR("[%s]: disconnect failed\n", _ld_name);
00267       return -1;
00268    }
00269 
00270    if ((rc = ldap_connect(_ld_name)) != 0)
00271    {
00272       LM_ERR("[%s]: reconnect failed\n",
00273             _ld_name);
00274    }
00275    else
00276    {
00277       LM_ERR("[%s]: LDAP reconnect successful\n",
00278             _ld_name);
00279    }
00280    return rc;
00281 }
00282 
00283 int ldap_get_vendor_version(char** _version)
00284 {
00285    static char version[128];
00286    LDAPAPIInfo api;
00287    int rc;
00288 
00289 #ifdef LDAP_API_INFO_VERSION
00290    api.ldapai_info_version = LDAP_API_INFO_VERSION;
00291 #else
00292    api.ldapai_info_version = 1;
00293 #endif
00294    
00295    if (ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) != LDAP_SUCCESS)
00296    {
00297       LM_ERR("ldap_get_option(API_INFO) failed\n");
00298       return -1;
00299    }
00300 
00301    rc = snprintf(version, 128, "%s - %d", api.ldapai_vendor_name,
00302          api.ldapai_vendor_version);
00303    if ((rc >= 128) || (rc < 0))
00304    {
00305       LM_ERR("snprintf failed\n");
00306       return -1;
00307    }
00308 
00309    *_version = version;
00310    return 0;
00311 }

Generated on Wed May 23 18:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6