PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - ldap - ldap.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 871
Code covered: 91.7 % Executed lines: 799
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Amitay Isaacs  <amitay@w-o-i.com>                           |
      16                 :    |          Eric Warnke    <ericw@albany.edu>                           |
      17                 :    |          Rasmus Lerdorf <rasmus@php.net>                             |
      18                 :    |          Gerrit Thomson <334647@swin.edu.au>                         |
      19                 :    |          Jani Taskinen  <sniper@iki.fi>                              |
      20                 :    |          Stig Venaas    <venaas@uninett.no>                          |
      21                 :    |          Doug Goldstein <cardoe@cardoe.com>                          |
      22                 :    |          Patrick Allaert <patrickallaert@php.net>                    |
      23                 :    | PHP 4.0 updates:  Zeev Suraski <zeev@zend.com>                       |
      24                 :    +----------------------------------------------------------------------+
      25                 :  */
      26                 :  
      27                 : /* $Id: ldap.c 290923 2009-11-18 17:44:58Z jani $ */
      28                 : #define IS_EXT_MODULE
      29                 : 
      30                 : #ifdef HAVE_CONFIG_H
      31                 : #include "config.h"
      32                 : #endif
      33                 : 
      34                 : /* Additional headers for NetWare */
      35                 : #if defined(NETWARE) && (NEW_LIBC)
      36                 : #include <sys/select.h>
      37                 : #include <sys/timeval.h>
      38                 : #endif
      39                 : 
      40                 : #include "php.h"
      41                 : #include "php_ini.h"
      42                 : 
      43                 : #include <stddef.h>
      44                 : 
      45                 : #include "ext/standard/dl.h"
      46                 : #include "php_ldap.h"
      47                 : 
      48                 : #ifdef PHP_WIN32
      49                 : #include <string.h>
      50                 : #if HAVE_NSLDAP
      51                 : #include <winsock2.h>
      52                 : #endif
      53                 : #define strdup _strdup
      54                 : #undef WINDOWS
      55                 : #undef strcasecmp
      56                 : #undef strncasecmp
      57                 : #define WINSOCK 1
      58                 : #define __STDC__ 1
      59                 : #endif
      60                 : 
      61                 : #include "ext/standard/php_string.h"
      62                 : #include "ext/standard/info.h"
      63                 : 
      64                 : #ifdef HAVE_LDAP_SASL_H
      65                 : #include <sasl.h>
      66                 : #elif defined(HAVE_LDAP_SASL_SASL_H)
      67                 : #include <sasl/sasl.h>
      68                 : #endif
      69                 : 
      70                 : typedef struct {
      71                 :         LDAP *link;
      72                 : #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
      73                 :         zval *rebindproc;
      74                 : #endif
      75                 : } ldap_linkdata;
      76                 : 
      77                 : typedef struct {
      78                 :         LDAPMessage *data;
      79                 :         BerElement *ber;
      80                 :         int id;
      81                 : } ldap_resultentry;
      82                 : 
      83                 : ZEND_DECLARE_MODULE_GLOBALS(ldap)
      84                 : static PHP_GINIT_FUNCTION(ldap);
      85                 : 
      86                 : static int le_link, le_result, le_result_entry;
      87                 : 
      88                 : #ifdef COMPILE_DL_LDAP
      89                 : ZEND_GET_MODULE(ldap)
      90                 : #endif
      91                 : 
      92                 : static void _close_ldap_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
      93             189 : {
      94             189 :         ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr;
      95                 : 
      96             189 :         ldap_unbind_s(ld->link);
      97                 : #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
      98             189 :         if (ld->rebindproc != NULL) {
      99               1 :                 zval_dtor(ld->rebindproc);
     100               1 :                 FREE_ZVAL(ld->rebindproc);
     101                 :         }
     102                 : #endif
     103             189 :         efree(ld);
     104             189 :         LDAPG(num_links)--;
     105             189 : }
     106                 : /* }}} */
     107                 : 
     108                 : static void _free_ldap_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
     109              46 : {
     110              46 :         LDAPMessage *result = (LDAPMessage *)rsrc->ptr;
     111              46 :         ldap_msgfree(result);
     112              46 : }
     113                 : /* }}} */
     114                 : 
     115                 : static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
     116              14 : {
     117              14 :         ldap_resultentry *entry = (ldap_resultentry *)rsrc->ptr;
     118                 : 
     119              14 :         if (entry->ber != NULL) {
     120               1 :                 ber_free(entry->ber, 0);
     121               1 :                 entry->ber = NULL;
     122                 :         }
     123              14 :         zend_list_delete(entry->id);
     124              14 :         efree(entry);
     125              14 : } 
     126                 : /* }}} */
     127                 : 
     128                 : /* {{{ PHP_INI_BEGIN
     129                 :  */
     130                 : PHP_INI_BEGIN()
     131                 :         STD_PHP_INI_ENTRY_EX("ldap.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_ldap_globals, ldap_globals, display_link_numbers)
     132                 : PHP_INI_END()
     133                 : /* }}} */
     134                 : 
     135                 : /* {{{ PHP_GINIT_FUNCTION
     136                 :  */
     137                 : static PHP_GINIT_FUNCTION(ldap)
     138           17007 : {
     139           17007 :         ldap_globals->num_links = 0;
     140           17007 : }
     141                 : /* }}} */
     142                 : 
     143                 : /* {{{ PHP_MINIT_FUNCTION
     144                 :  */
     145                 : PHP_MINIT_FUNCTION(ldap)
     146           17007 : {
     147           17007 :         REGISTER_INI_ENTRIES();
     148                 : 
     149                 :         /* Constants to be used with deref-parameter in php_ldap_do_search() */
     150           17007 :         REGISTER_LONG_CONSTANT("LDAP_DEREF_NEVER", LDAP_DEREF_NEVER, CONST_PERSISTENT | CONST_CS);
     151           17007 :         REGISTER_LONG_CONSTANT("LDAP_DEREF_SEARCHING", LDAP_DEREF_SEARCHING, CONST_PERSISTENT | CONST_CS);
     152           17007 :         REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS);
     153           17007 :         REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS);
     154                 : 
     155                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
     156                 :         /* LDAP options */
     157           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS);
     158           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_SIZELIMIT", LDAP_OPT_SIZELIMIT, CONST_PERSISTENT | CONST_CS);
     159           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_TIMELIMIT", LDAP_OPT_TIMELIMIT, CONST_PERSISTENT | CONST_CS);
     160                 : #ifdef LDAP_OPT_NETWORK_TIMEOUT
     161           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_NETWORK_TIMEOUT", LDAP_OPT_NETWORK_TIMEOUT, CONST_PERSISTENT | CONST_CS);
     162                 : #elif defined (LDAP_X_OPT_CONNECT_TIMEOUT)
     163                 :         REGISTER_LONG_CONSTANT("LDAP_OPT_NETWORK_TIMEOUT", LDAP_X_OPT_CONNECT_TIMEOUT, CONST_PERSISTENT | CONST_CS);
     164                 : #endif
     165           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_PROTOCOL_VERSION", LDAP_OPT_PROTOCOL_VERSION, CONST_PERSISTENT | CONST_CS);
     166           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_ERROR_NUMBER", LDAP_OPT_ERROR_NUMBER, CONST_PERSISTENT | CONST_CS);
     167           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_REFERRALS", LDAP_OPT_REFERRALS, CONST_PERSISTENT | CONST_CS);
     168                 : #ifdef LDAP_OPT_RESTART
     169           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_RESTART", LDAP_OPT_RESTART, CONST_PERSISTENT | CONST_CS);
     170                 : #endif
     171                 : #ifdef LDAP_OPT_HOST_NAME
     172           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_HOST_NAME", LDAP_OPT_HOST_NAME, CONST_PERSISTENT | CONST_CS);
     173                 : #endif
     174           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_ERROR_STRING", LDAP_OPT_ERROR_STRING, CONST_PERSISTENT | CONST_CS);
     175                 : #ifdef LDAP_OPT_MATCHED_DN
     176           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_MATCHED_DN", LDAP_OPT_MATCHED_DN, CONST_PERSISTENT | CONST_CS);
     177                 : #endif
     178           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_SERVER_CONTROLS", LDAP_OPT_SERVER_CONTROLS, CONST_PERSISTENT | CONST_CS);
     179           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_CLIENT_CONTROLS", LDAP_OPT_CLIENT_CONTROLS, CONST_PERSISTENT | CONST_CS);
     180                 : #endif
     181                 : #ifdef LDAP_OPT_DEBUG_LEVEL
     182           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_DEBUG_LEVEL", LDAP_OPT_DEBUG_LEVEL, CONST_PERSISTENT | CONST_CS);
     183                 : #endif
     184                 : 
     185                 : #ifdef HAVE_LDAP_SASL
     186           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_MECH", LDAP_OPT_X_SASL_MECH, CONST_PERSISTENT | CONST_CS);
     187           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_REALM", LDAP_OPT_X_SASL_REALM, CONST_PERSISTENT | CONST_CS);
     188           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHCID", LDAP_OPT_X_SASL_AUTHCID, CONST_PERSISTENT | CONST_CS);
     189           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHZID", LDAP_OPT_X_SASL_AUTHZID, CONST_PERSISTENT | CONST_CS);
     190                 : #endif
     191                 : 
     192                 : #ifdef LDAP_OPT_X_TLS
     193           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_CACERTFILE", LDAP_OPT_X_TLS_CACERTFILE, CONST_PERSISTENT | CONST_CS);
     194           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_CACERTDIR", LDAP_OPT_X_TLS_CACERTDIR, CONST_PERSISTENT | CONST_CS);
     195           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_CERTFILE", LDAP_OPT_X_TLS_CERTFILE, CONST_PERSISTENT | CONST_CS);
     196           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_KEYFILE",  LDAP_OPT_X_TLS_KEYFILE, CONST_PERSISTENT | CONST_CS);
     197           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_REQUIRE_CERT", LDAP_OPT_X_TLS_REQUIRE_CERT, CONST_PERSISTENT | CONST_CS);
     198                 : #ifdef LDAP_OPT_X_TLS_CRLCHECK
     199           17007 :         REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_CRLCHECK", LDAP_OPT_X_TLS_CRLCHECK, CONST_PERSISTENT | CONST_CS);
     200                 : #endif  
     201                 : #endif         
     202                 : 
     203                 : #ifdef ORALDAP
     204                 :         REGISTER_LONG_CONSTANT("GSLC_SSL_NO_AUTH", GSLC_SSL_NO_AUTH, CONST_PERSISTENT | CONST_CS);
     205                 :         REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_CS);
     206                 :         REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
     207                 : #endif
     208                 : 
     209           17007 :         le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
     210           17007 :         le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
     211           17007 :         le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
     212                 : 
     213           17007 :         Z_TYPE(ldap_module_entry) = type;
     214                 : 
     215           17007 :         return SUCCESS;
     216                 : }
     217                 : /* }}} */
     218                 : 
     219                 : /* {{{ PHP_MSHUTDOWN_FUNCTION
     220                 :  */
     221                 : PHP_MSHUTDOWN_FUNCTION(ldap)
     222           17039 : {
     223           17039 :         UNREGISTER_INI_ENTRIES();
     224           17039 :         return SUCCESS;
     225                 : }
     226                 : /* }}} */
     227                 : 
     228                 : /* {{{ PHP_MINFO_FUNCTION
     229                 :  */
     230                 : PHP_MINFO_FUNCTION(ldap)
     231              43 : {
     232                 :         char tmp[32];
     233                 : #if HAVE_NSLDAP
     234                 :         LDAPVersion ver;
     235                 :         double SDKVersion;
     236                 : #endif
     237                 : 
     238              43 :         php_info_print_table_start();
     239              43 :         php_info_print_table_row(2, "LDAP Support", "enabled");
     240              43 :         php_info_print_table_row(2, "RCS Version", "$Id: ldap.c 290923 2009-11-18 17:44:58Z jani $");
     241                 : 
     242              43 :         if (LDAPG(max_links) == -1) {
     243              43 :                 snprintf(tmp, 31, "%ld/unlimited", LDAPG(num_links));
     244                 :         } else {
     245               0 :                 snprintf(tmp, 31, "%ld/%ld", LDAPG(num_links), LDAPG(max_links));
     246                 :         }
     247              43 :         php_info_print_table_row(2, "Total Links", tmp);
     248                 : 
     249                 : #ifdef LDAP_API_VERSION
     250              43 :         snprintf(tmp, 31, "%d", LDAP_API_VERSION);
     251              43 :         php_info_print_table_row(2, "API Version", tmp);
     252                 : #endif
     253                 : 
     254                 : #ifdef LDAP_VENDOR_NAME
     255              43 :         php_info_print_table_row(2, "Vendor Name", LDAP_VENDOR_NAME);
     256                 : #endif
     257                 : 
     258                 : #ifdef LDAP_VENDOR_VERSION
     259              43 :         snprintf(tmp, 31, "%d", LDAP_VENDOR_VERSION);
     260              43 :         php_info_print_table_row(2, "Vendor Version", tmp);
     261                 : #endif
     262                 : 
     263                 : #if HAVE_NSLDAP
     264                 :         SDKVersion = ldap_version(&ver);
     265                 :         snprintf(tmp, 31, "%F", SDKVersion/100.0);
     266                 :         php_info_print_table_row(2, "SDK Version", tmp);
     267                 : 
     268                 :         snprintf(tmp, 31, "%F", ver.protocol_version/100.0);
     269                 :         php_info_print_table_row(2, "Highest LDAP Protocol Supported", tmp);
     270                 : 
     271                 :         snprintf(tmp, 31, "%F", ver.SSL_version/100.0);
     272                 :         php_info_print_table_row(2, "SSL Level Supported", tmp);
     273                 : 
     274                 :         if (ver.security_level != LDAP_SECURITY_NONE) {
     275                 :                 snprintf(tmp, 31, "%d", ver.security_level);
     276                 :         } else {
     277                 :                 strcpy(tmp, "SSL not enabled");
     278                 :         }
     279                 :         php_info_print_table_row(2, "Level of Encryption", tmp);
     280                 : #endif
     281                 : 
     282                 : #ifdef HAVE_LDAP_SASL
     283              43 :         php_info_print_table_row(2, "SASL Support", "Enabled");
     284                 : #endif
     285                 : 
     286              43 :         php_info_print_table_end();
     287              43 :         DISPLAY_INI_ENTRIES();
     288              43 : }
     289                 : /* }}} */
     290                 : 
     291                 : /* {{{ proto resource ldap_connect([string host [, int port [, string wallet [, string wallet_passwd [, int authmode]]]]]) U
     292                 :    Connect to an LDAP server */
     293                 : PHP_FUNCTION(ldap_connect)
     294             192 : {
     295             192 :         char *host = NULL;
     296                 :         int hostlen;
     297             192 :         long port = 389; /* Default port */
     298                 : #ifdef HAVE_ORALDAP
     299                 :         char *wallet = NULL, *walletpasswd = NULL;
     300                 :         int walletlen = 0, walletpasswdlen = 0;
     301                 :         long authmode = GSLC_SSL_NO_AUTH;
     302                 :         int ssl=0;
     303                 : #endif
     304                 :         ldap_linkdata *ld;
     305                 :         LDAP *ldap;
     306                 : 
     307                 : #ifdef HAVE_ORALDAP
     308                 :         if (ZEND_NUM_ARGS() == 3 || ZEND_NUM_ARGS() == 4) {
     309                 :                 WRONG_PARAM_COUNT;
     310                 :         }
     311                 : 
     312                 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&ls&s&l", &host, &hostlen, UG(utf8_conv), &port, &wallet, &walletlen, UG(utf8_conv), &walletpasswd, &walletpasswdlen, UG(utf8_conv), &authmode) != SUCCESS) {
     313                 :                 RETURN_FALSE;
     314                 :         }
     315                 : 
     316                 :         if (ZEND_NUM_ARGS() == 5) {
     317                 :                 ssl = 1;
     318                 :         }
     319                 : #else
     320             192 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sl", &host, &hostlen, &port) != SUCCESS) {
     321               1 :                 RETURN_FALSE;
     322                 :         }
     323                 : #endif
     324                 : 
     325             191 :         if (LDAPG(max_links) != -1 && LDAPG(num_links) >= LDAPG(max_links)) {
     326               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", LDAPG(num_links));
     327               1 :                 RETURN_FALSE;
     328                 :         }
     329                 : 
     330             190 :         ld = ecalloc(1, sizeof(ldap_linkdata));
     331                 : 
     332                 : #ifdef LDAP_API_FEATURE_X_OPENLDAP
     333             192 :         if (host != NULL && strchr(host, '/')) {
     334                 :                 int rc;
     335                 :                 
     336               3 :                 rc = ldap_initialize(&ldap, host);
     337               3 :                 if (rc != LDAP_SUCCESS) {
     338               1 :                         efree(ld);
     339               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc));
     340               1 :                         RETURN_FALSE;
     341                 :                 }
     342                 :         } else {
     343             187 :                 ldap = ldap_init(host, port);
     344                 :         }
     345                 : #else
     346                 :         ldap = ldap_open(host, port);
     347                 : #endif
     348                 :         
     349             189 :         if (ldap == NULL) {
     350               0 :                 efree(ld);
     351               0 :                 RETURN_FALSE;
     352                 :         } else {
     353                 : #ifdef HAVE_ORALDAP
     354                 :                 if (ssl) {
     355                 :                         if (ldap_init_SSL(&ldap->ld_sb, wallet, walletpasswd, authmode)) {
     356                 :                                 efree(ld);
     357                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL init failed");
     358                 :                                 RETURN_FALSE;
     359                 :                         }
     360                 :                 }                       
     361                 : #endif
     362             189 :                 LDAPG(num_links)++;
     363             189 :                 ld->link = ldap;
     364             189 :                 ZEND_REGISTER_RESOURCE(return_value, ld, le_link);
     365                 :         }
     366                 : 
     367                 : }
     368                 : /* }}} */
     369                 : 
     370                 : /* {{{ _get_lderrno
     371                 :  */
     372                 : static int _get_lderrno(LDAP *ldap)
     373              15 : {
     374                 : #if !HAVE_NSLDAP
     375                 : #if LDAP_API_VERSION > 2000 || HAVE_ORALDAP_10
     376                 :         int lderr;
     377                 : 
     378                 :         /* New versions of OpenLDAP do it this way */
     379              15 :         ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &lderr);
     380              15 :         return lderr;
     381                 : #else
     382                 :         return ldap->ld_errno;
     383                 : #endif
     384                 : #else
     385                 :         return ldap_get_lderrno(ldap, NULL, NULL);
     386                 : #endif
     387                 : }
     388                 : /* }}} */
     389                 : 
     390                 : /* {{{ proto bool ldap_bind(resource link [, string dn [, string password]]) U
     391                 :    Bind to LDAP directory */
     392                 : PHP_FUNCTION(ldap_bind)
     393             157 : {
     394                 :         zval *link;
     395             157 :         char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
     396                 :         int ldap_bind_dnlen, ldap_bind_pwlen;
     397                 :         ldap_linkdata *ld;
     398                 :         int rc;
     399                 : 
     400             157 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s&s&", &link, &ldap_bind_dn, &ldap_bind_dnlen, UG(utf8_conv), &ldap_bind_pw, &ldap_bind_pwlen, UG(utf8_conv)) != SUCCESS) {
     401               1 :                 RETURN_FALSE;
     402                 :         }
     403                 : 
     404             156 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     405                 : 
     406             156 :         if ((rc = ldap_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
     407               2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
     408               2 :                 RETURN_FALSE;
     409                 :         } else {
     410             154 :                 RETURN_TRUE;
     411                 :         }
     412                 : }
     413                 : /* }}} */
     414                 : 
     415                 : #ifdef HAVE_LDAP_SASL
     416                 : typedef struct {
     417                 :         char *mech;
     418                 :         char *realm;
     419                 :         char *authcid;
     420                 :         char *passwd;
     421                 :         char *authzid;
     422                 : } php_ldap_bictx;
     423                 : 
     424                 : /* {{{ _php_sasl_setdefs
     425                 :  */
     426                 : static php_ldap_bictx *_php_sasl_setdefs(LDAP *ld, char *sasl_mech, char *sasl_realm, char *sasl_authc_id, char *passwd, char *sasl_authz_id)
     427               6 : {
     428                 :         php_ldap_bictx *ctx;
     429                 : 
     430               6 :         ctx = ber_memalloc(sizeof(php_ldap_bictx));     
     431               6 :         ctx->mech    = (sasl_mech) ? ber_strdup(sasl_mech) : NULL;
     432               6 :         ctx->realm   = (sasl_realm) ? ber_strdup(sasl_realm) : NULL;
     433               6 :         ctx->authcid = (sasl_authc_id) ? ber_strdup(sasl_authc_id) : NULL;
     434               6 :         ctx->passwd  = (passwd) ? ber_strdup(passwd) : NULL;
     435               6 :         ctx->authzid = (sasl_authz_id) ? ber_strdup(sasl_authz_id) : NULL;
     436                 : 
     437               6 :         if (ctx->mech == NULL) {
     438               1 :                 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &ctx->mech);
     439                 :         }
     440               6 :         if (ctx->realm == NULL) {
     441               1 :                 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &ctx->realm);
     442                 :         }
     443               6 :         if (ctx->authcid == NULL) {
     444               1 :                 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &ctx->authcid);
     445                 :         }
     446               6 :         if (ctx->authzid == NULL) {
     447               5 :                 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &ctx->authzid);
     448                 :         }
     449                 : 
     450               6 :         return ctx;
     451                 : }
     452                 : /* }}} */
     453                 : 
     454                 : /* {{{ _php_sasl_freedefs
     455                 :  */
     456                 : static void _php_sasl_freedefs(php_ldap_bictx *ctx)
     457               6 : {
     458               6 :         if (ctx->mech) ber_memfree(ctx->mech);
     459               6 :         if (ctx->realm) ber_memfree(ctx->realm);
     460               6 :         if (ctx->authcid) ber_memfree(ctx->authcid);
     461               6 :         if (ctx->passwd) ber_memfree(ctx->passwd);
     462               6 :         if (ctx->authzid) ber_memfree(ctx->authzid);
     463               6 :         ber_memfree(ctx);
     464               6 : }
     465                 : /* }}} */
     466                 : 
     467                 : /* {{{ _php_sasl_interact
     468                 :    Internal interact function for SASL */
     469                 : static int _php_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *in)
     470               4 : {
     471               4 :         sasl_interact_t *interact = in;
     472                 :         const char *p;
     473               4 :         php_ldap_bictx *ctx = defaults;
     474                 : 
     475              16 :         for (;interact->id != SASL_CB_LIST_END;interact++) {
     476              12 :                 p = NULL;
     477              12 :                 switch(interact->id) {
     478                 :                         case SASL_CB_GETREALM:
     479               0 :                                 p = ctx->realm;
     480               0 :                                 break;
     481                 :                         case SASL_CB_AUTHNAME:
     482               4 :                                 p = ctx->authcid;
     483               4 :                                 break;
     484                 :                         case SASL_CB_USER:
     485               4 :                                 p = ctx->authzid;
     486               4 :                                 break;
     487                 :                         case SASL_CB_PASS:
     488               4 :                                 p = ctx->passwd;
     489                 :                                 break;
     490                 :                 }
     491              12 :                 if (p) {
     492               9 :                         interact->result = p;
     493               9 :                         interact->len = strlen(interact->result);
     494                 :                 }
     495                 :         }
     496               4 :         return LDAP_SUCCESS;
     497                 : }
     498                 : /* }}} */
     499                 : 
     500                 : /* {{{ proto bool ldap_sasl_bind(resource link [, string binddn [, string password [, string sasl_mech [, string sasl_realm [, string sasl_authc_id [, string sasl_authz_id [, string props]]]]]]]) U
     501                 :    Bind to LDAP directory using SASL */
     502                 : PHP_FUNCTION(ldap_sasl_bind)
     503               7 : {
     504                 :         zval *link;
     505                 :         ldap_linkdata *ld;
     506               7 :         char *binddn = NULL;
     507               7 :         char *passwd = NULL;
     508               7 :         char *sasl_mech = NULL;
     509               7 :         char *sasl_realm = NULL;
     510               7 :         char *sasl_authz_id = NULL;
     511               7 :         char *sasl_authc_id = NULL;
     512               7 :         char *props = NULL;
     513                 :         int rc, dn_len, passwd_len, mech_len, realm_len, authc_id_len, authz_id_len, props_len;
     514                 :         php_ldap_bictx *ctx;
     515                 : 
     516               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s&s&s&s&s&s&s&", &link, &binddn, &dn_len, UG(utf8_conv), &passwd, &passwd_len, UG(utf8_conv), &sasl_mech, &mech_len, UG(utf8_conv), &sasl_realm, &realm_len, UG(utf8_conv), &sasl_authc_id, &authc_id_len, UG(utf8_conv), &sasl_authz_id, &authz_id_len, UG(utf8_conv), &props, &props_len, UG(utf8_conv)) != SUCCESS) {
     517               1 :                 RETURN_FALSE;
     518                 :         }
     519                 : 
     520               6 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     521                 : 
     522               6 :         ctx = _php_sasl_setdefs(ld->link, sasl_mech, sasl_realm, sasl_authc_id, passwd, sasl_authz_id);
     523                 : 
     524               6 :         if (props) {
     525               0 :                 ldap_set_option(ld->link, LDAP_OPT_X_SASL_SECPROPS, props);
     526                 :         }
     527                 : 
     528               6 :         rc = ldap_sasl_interactive_bind_s(ld->link, binddn, ctx->mech, NULL, NULL, LDAP_SASL_QUIET, _php_sasl_interact, ctx);
     529               6 :         if (rc != LDAP_SUCCESS) {
     530               5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
     531               5 :                 RETVAL_FALSE;
     532                 :         } else {
     533               1 :                 RETVAL_TRUE;
     534                 :         }
     535               6 :         _php_sasl_freedefs(ctx);
     536                 : }
     537                 : /* }}} */
     538                 : #endif /* HAVE_LDAP_SASL */
     539                 : 
     540                 : /* {{{ proto bool ldap_unbind(resource link) U
     541                 :    Unbind from LDAP directory */
     542                 : PHP_FUNCTION(ldap_unbind)
     543              65 : {
     544                 :         zval *link;
     545                 :         ldap_linkdata *ld;
     546                 : 
     547              65 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &link) != SUCCESS) {
     548               3 :                 RETURN_FALSE;
     549                 :         }
     550                 : 
     551              62 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     552                 : 
     553              61 :         zend_list_delete(Z_LVAL_P(link));
     554              61 :         RETURN_TRUE;
     555                 : }
     556                 : /* }}} */
     557                 : 
     558                 : /* {{{ php_set_opts
     559                 :  */
     560                 : static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, int *old_sizelimit, int *old_timelimit, int *old_deref)
     561              93 : {
     562                 :         /* sizelimit */
     563              93 :         if (sizelimit > -1) {
     564                 : #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
     565              14 :                 ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit);
     566              14 :                 ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
     567                 : #else
     568                 :                 *old_sizelimit = ldap->ld_sizelimit; 
     569                 :                 ldap->ld_sizelimit = sizelimit; 
     570                 : #endif
     571                 :         }
     572                 : 
     573                 :         /* timelimit */
     574              93 :         if (timelimit > -1) {
     575                 : #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
     576              10 :                 ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_timelimit);
     577              10 :                 ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
     578                 : #else
     579                 :                 *old_timelimit = ldap->ld_timelimit; 
     580                 :                 ldap->ld_timelimit = timelimit; 
     581                 : #endif
     582                 :         }
     583                 : 
     584                 :         /* deref */
     585              93 :         if (deref > -1) {
     586                 : #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
     587               8 :                 ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_deref);
     588               8 :                 ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
     589                 : #else
     590                 :                 *old_deref = ldap->ld_deref; 
     591                 :                 ldap->ld_deref = deref; 
     592                 : #endif
     593                 :         }
     594              93 : }
     595                 : /* }}} */
     596                 : 
     597                 : /* {{{ php_ldap_do_search
     598                 :  */
     599                 : static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
     600              60 : {
     601                 :         zval *link, *base_dn, **filter, *attrs, **attr;
     602                 :         long attrsonly, sizelimit, timelimit, deref;
     603              60 :         char *ldap_base_dn = NULL, *ldap_filter = NULL, **ldap_attrs = NULL;
     604              60 :         ldap_linkdata *ld = NULL;
     605                 :         LDAPMessage *ldap_res;
     606              60 :         int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1;       
     607              60 :         int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1;       
     608              60 :         int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS();
     609                 : 
     610              60 :         if (zend_parse_parameters(argcount TSRMLS_CC, "zzZ|allll", &link, &base_dn, &filter, &attrs, &attrsonly, 
     611                 :                 &sizelimit, &timelimit, &deref) == FAILURE) {
     612              10 :                 return;
     613                 :         }
     614                 : 
     615                 :         /* Reverse -> fall through */
     616              50 :         switch (argcount) {
     617                 :                 case 8:
     618               4 :                         ldap_deref = deref;
     619                 :                 case 7:
     620               5 :                         ldap_timelimit = timelimit;
     621                 :                 case 6:
     622               7 :                         ldap_sizelimit = sizelimit;
     623                 :                 case 5:
     624               8 :                         ldap_attrsonly = attrsonly;
     625                 :                 case 4:
     626              20 :                         num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs));
     627              20 :                         ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0);
     628                 : 
     629              43 :                         for (i = 0; i<num_attribs; i++) {
     630              24 :                                 if (zend_hash_index_find(Z_ARRVAL_P(attrs), i, (void **) &attr) != SUCCESS) {
     631               1 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array initialization wrong");
     632               1 :                                         ret = 0;
     633               1 :                                         goto cleanup;
     634                 :                                 }
     635                 : 
     636              23 :                                 SEPARATE_ZVAL(attr);
     637              23 :                                 convert_to_string_ex(attr);
     638              23 :                                 ldap_attrs[i] = Z_STRVAL_PP(attr);
     639                 :                         }
     640              19 :                         ldap_attrs[num_attribs] = NULL;
     641                 :                 default:
     642                 :                         break;
     643                 :         }
     644                 : 
     645                 :         /* parallel search? */
     646              49 :         if (Z_TYPE_P(link) == IS_ARRAY) {
     647                 :                 int i, nlinks, nbases, nfilters, *rcs;
     648                 :                 ldap_linkdata **lds;
     649                 :                 zval **entry, *resource;
     650                 :                 
     651               6 :                 nlinks = zend_hash_num_elements(Z_ARRVAL_P(link));
     652               6 :                 if (nlinks == 0) {
     653               1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "No links in link array");
     654               1 :                         ret = 0;
     655               1 :                         goto cleanup;
     656                 :                 }
     657                 : 
     658               5 :                 if (Z_TYPE_P(base_dn) == IS_ARRAY) {
     659               1 :                         nbases = zend_hash_num_elements(Z_ARRVAL_P(base_dn));
     660               1 :                         if (nbases != nlinks) {
     661               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Base must either be a string, or an array with the same number of elements as the links array");
     662               1 :                                 ret = 0;
     663               1 :                                 goto cleanup;
     664                 :                         }
     665               0 :                         zend_hash_internal_pointer_reset(Z_ARRVAL_P(base_dn));
     666                 :                 } else {
     667               4 :                         nbases = 0; /* this means string, not array */
     668                 :                         /* If anything else than string is passed, ldap_base_dn = NULL */
     669               4 :                         if (Z_TYPE_P(base_dn) == IS_STRING) {
     670               0 :                                 ldap_base_dn = Z_STRVAL_P(base_dn);
     671               4 :                         } else if (Z_TYPE_P(base_dn) == IS_UNICODE) {
     672               2 :                                 ldap_base_dn = zend_unicode_to_ascii(Z_USTRVAL_P(base_dn), Z_USTRLEN_P(base_dn) TSRMLS_CC);
     673                 :                         } else {
     674               2 :                                 ldap_base_dn = NULL;
     675                 :                         }
     676                 :                 }
     677                 : 
     678               4 :                 if (Z_TYPE_PP(filter) == IS_ARRAY) {
     679               2 :                         nfilters = zend_hash_num_elements(Z_ARRVAL_PP(filter));
     680               2 :                         if (nfilters != nlinks) {
     681               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter must either be a string, or an array with the same number of elements as the links array");
     682               1 :                                 ret = 0;
     683               1 :                                 goto cleanup;
     684                 :                         }
     685               1 :                         zend_hash_internal_pointer_reset(Z_ARRVAL_PP(filter));
     686                 :                 } else {
     687               2 :                         nfilters = 0; /* this means string, not array */
     688               2 :                         convert_to_string_ex(filter);
     689               2 :                         ldap_filter = Z_STRVAL_PP(filter);
     690                 :                 }
     691                 : 
     692               3 :                 lds = safe_emalloc(nlinks, sizeof(ldap_linkdata), 0);
     693               3 :                 rcs = safe_emalloc(nlinks, sizeof(*rcs), 0);
     694                 :                 
     695               3 :                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(link));
     696               9 :                 for (i=0; i<nlinks; i++) {
     697               6 :                         zend_hash_get_current_data(Z_ARRVAL_P(link), (void **)&entry);
     698                 : 
     699               6 :                         ld = (ldap_linkdata *) zend_fetch_resource(entry TSRMLS_CC, -1, "ldap link", NULL, 1, le_link);
     700               6 :                         if (ld == NULL) {
     701               0 :                                 ret = 0;
     702               0 :                                 goto cleanup_parallel;
     703                 :                         }
     704               6 :                         if (nbases != 0) { /* base_dn an array? */
     705               0 :                                 zend_hash_get_current_data(Z_ARRVAL_P(base_dn), (void **)&entry);
     706               0 :                                 zend_hash_move_forward(Z_ARRVAL_P(base_dn));
     707                 : 
     708                 :                                 /* If anything else than string is passed, ldap_base_dn = NULL */
     709               0 :                                 if (Z_TYPE_PP(entry) == IS_STRING) {
     710               0 :                                         ldap_base_dn = Z_STRVAL_PP(entry);
     711               0 :                                 } else if (Z_TYPE_PP(entry) == IS_UNICODE) {
     712               0 :                                         ldap_base_dn = zend_unicode_to_ascii(Z_USTRVAL_PP(entry), Z_USTRLEN_PP(entry) TSRMLS_CC);
     713                 :                                 } else {
     714               0 :                                         ldap_base_dn = NULL;
     715                 :                                 }
     716                 :                         }
     717               6 :                         if (nfilters != 0) { /* filter an array? */
     718               2 :                                 zend_hash_get_current_data(Z_ARRVAL_PP(filter), (void **)&entry);
     719               2 :                                 zend_hash_move_forward(Z_ARRVAL_PP(filter));
     720               2 :                                 convert_to_string_ex(entry);
     721               2 :                                 ldap_filter = Z_STRVAL_PP(entry);
     722                 :                         }
     723                 : 
     724               6 :                         php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
     725                 : 
     726                 :                         /* Run the actual search */     
     727               6 :                         rcs[i] = ldap_search(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly);
     728               6 :                         lds[i] = ld;
     729               6 :                         zend_hash_move_forward(Z_ARRVAL_P(link));
     730                 :                 }
     731                 :                 
     732               3 :                 array_init(return_value);
     733                 : 
     734                 :                 /* Collect results from the searches */
     735               9 :                 for (i=0; i<nlinks; i++) {
     736               6 :                         MAKE_STD_ZVAL(resource);
     737               6 :                         if (rcs[i] != -1) {
     738               6 :                                 rcs[i] = ldap_result(lds[i]->link, LDAP_RES_ANY, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res);
     739                 :                         }
     740               6 :                         if (rcs[i] != -1) {
     741               6 :                                 ZEND_REGISTER_RESOURCE(resource, ldap_res, le_result);
     742               6 :                                 add_next_index_zval(return_value, resource);
     743                 :                         } else {
     744               0 :                                 add_next_index_bool(return_value, 0);
     745                 :                         }
     746                 :                 }
     747                 : 
     748               3 : cleanup_parallel:
     749               3 :                 efree(lds);
     750               3 :                 efree(rcs);
     751                 :         } else {
     752              43 :                 convert_to_string_ex(filter);
     753              43 :                 ldap_filter = Z_STRVAL_PP(filter);
     754                 : 
     755                 :                 /* If anything else than string is passed, ldap_base_dn = NULL */
     756              43 :                 if (Z_TYPE_P(base_dn) == IS_STRING) {
     757               0 :                         ldap_base_dn = Z_STRVAL_P(base_dn);
     758              43 :                 } else if (Z_TYPE_P(base_dn) == IS_UNICODE) {
     759              42 :                         ldap_base_dn = zend_unicode_to_ascii(Z_USTRVAL_P(base_dn), Z_USTRLEN_P(base_dn) TSRMLS_CC);
     760                 :                 }
     761                 : 
     762              43 :                 ld = (ldap_linkdata *) zend_fetch_resource(&link TSRMLS_CC, -1, "ldap link", NULL, 1, le_link);
     763              43 :                 if (ld == NULL) {
     764               1 :                         ret = 0;
     765               1 :                         goto cleanup;
     766                 :                 }
     767                 : 
     768              42 :                 php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
     769                 : 
     770                 :                 /* Run the actual search */     
     771              42 :                 errno = ldap_search_s(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, &ldap_res);
     772                 :         
     773              44 :                 if (errno != LDAP_SUCCESS
     774                 :                         && errno != LDAP_SIZELIMIT_EXCEEDED
     775                 : #ifdef LDAP_ADMINLIMIT_EXCEEDED
     776                 :                         && errno != LDAP_ADMINLIMIT_EXCEEDED
     777                 : #endif
     778                 : #ifdef LDAP_REFERRAL
     779                 :                         && errno != LDAP_REFERRAL
     780                 : #endif
     781                 :                 ) {
     782               2 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Search: %s", ldap_err2string(errno));
     783               2 :                         ret = 0;
     784                 :                 } else {
     785              40 :                         if (errno == LDAP_SIZELIMIT_EXCEEDED) {
     786               6 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Partial search results returned: Sizelimit exceeded");
     787                 :                         }
     788                 : #ifdef LDAP_ADMINLIMIT_EXCEEDED
     789              34 :                         else if (errno == LDAP_ADMINLIMIT_EXCEEDED) {
     790               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Partial search results returned: Adminlimit exceeded");
     791                 :                         }
     792                 : #endif
     793                 :                         
     794              40 :                         ZEND_REGISTER_RESOURCE(return_value, ldap_res, le_result);
     795                 :                 }
     796                 :         }
     797                 : 
     798              50 : cleanup:
     799              50 :         if (ld) {
     800                 :                 /* Restoring previous options */        
     801              45 :                 php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref);
     802                 :         }
     803              50 :         if (ldap_attrs != NULL) {
     804              20 :                 efree(ldap_attrs);
     805                 :         }
     806              50 :         if (Z_TYPE_P(base_dn) == IS_UNICODE && ldap_base_dn) {
     807              44 :                 efree(ldap_base_dn);
     808                 :         }
     809              50 :         if (!ret) {
     810               7 :                 RETVAL_BOOL(ret);
     811                 :         }
     812                 : }
     813                 : /* }}} */
     814                 : 
     815                 : /* {{{ proto resource ldap_read(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) U
     816                 :    Read an entry */
     817                 : PHP_FUNCTION(ldap_read)
     818               6 : {
     819               6 :         php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_BASE);
     820               6 : }
     821                 : /* }}} */
     822                 : 
     823                 : /* {{{ proto resource ldap_list(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) U
     824                 :    Single-level search */
     825                 : PHP_FUNCTION(ldap_list)
     826               6 : {
     827               6 :         php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_ONELEVEL);
     828               6 : }
     829                 : /* }}} */
     830                 : 
     831                 : /* {{{ proto resource ldap_search(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) U
     832                 :    Search LDAP tree under base_dn */
     833                 : PHP_FUNCTION(ldap_search)
     834              48 : {
     835              48 :         php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_SUBTREE);
     836              48 : }
     837                 : /* }}} */
     838                 : 
     839                 : /* {{{ proto bool ldap_free_result(resource result) U
     840                 :    Free result memory */
     841                 : PHP_FUNCTION(ldap_free_result)
     842               3 : {
     843                 :         zval *result;
     844                 :         LDAPMessage *ldap_result;
     845                 : 
     846               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) != SUCCESS) {
     847               1 :                 return;
     848                 :         }
     849                 : 
     850               2 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
     851                 : 
     852               1 :         zend_list_delete(Z_LVAL_P(result));  /* Delete list entry */
     853               1 :         RETVAL_TRUE;
     854                 : }
     855                 : /* }}} */
     856                 : 
     857                 : /* {{{ proto int ldap_count_entries(resource link, resource result) U
     858                 :    Count the number of entries in a search result */
     859                 : PHP_FUNCTION(ldap_count_entries)
     860               3 : {
     861                 :         zval *link, *result;
     862                 :         ldap_linkdata *ld;
     863                 :         LDAPMessage *ldap_result;
     864                 : 
     865               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result) != SUCCESS) {
     866               1 :                 return;
     867                 :         }
     868                 : 
     869               2 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     870               2 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
     871                 : 
     872               1 :         RETURN_LONG(ldap_count_entries(ld->link, ldap_result));
     873                 : }
     874                 : /* }}} */
     875                 : 
     876                 : /* {{{ proto resource ldap_first_entry(resource link, resource result) U
     877                 :    Return first result id */
     878                 : PHP_FUNCTION(ldap_first_entry)
     879              12 : {
     880                 :         zval *link, *result;
     881                 :         ldap_linkdata *ld;      
     882                 :         ldap_resultentry *resultentry;
     883                 :         LDAPMessage *ldap_result, *entry;
     884                 : 
     885              12 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result) != SUCCESS) {
     886               2 :                 return;
     887                 :         }
     888                 : 
     889              10 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     890              10 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
     891                 : 
     892               9 :         if ((entry = ldap_first_entry(ld->link, ldap_result)) == NULL) {
     893               0 :                 RETVAL_FALSE;
     894                 :         } else {
     895               9 :                 resultentry = emalloc(sizeof(ldap_resultentry));
     896               9 :                 ZEND_REGISTER_RESOURCE(return_value, resultentry, le_result_entry);
     897               9 :                 resultentry->id = Z_LVAL_P(result);
     898               9 :                 zend_list_addref(resultentry->id);
     899               9 :                 resultentry->data = entry;
     900               9 :                 resultentry->ber = NULL;
     901                 :         }
     902                 : }
     903                 : /* }}} */
     904                 : 
     905                 : /* {{{ proto resource ldap_next_entry(resource link, resource result_entry) U
     906                 :    Get next result entry */
     907                 : PHP_FUNCTION(ldap_next_entry)
     908               5 : {
     909                 :         zval *link, *result_entry;
     910                 :         ldap_linkdata *ld;
     911                 :         ldap_resultentry *resultentry, *resultentry_next;
     912                 :         LDAPMessage *entry_next;
     913                 : 
     914               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
     915               2 :                 return;
     916                 :         }
     917                 : 
     918               3 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     919               3 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
     920                 : 
     921               2 :         if ((entry_next = ldap_next_entry(ld->link, resultentry->data)) == NULL) {
     922               1 :                 RETVAL_FALSE;
     923                 :         } else {
     924               1 :                 resultentry_next = emalloc(sizeof(ldap_resultentry));
     925               1 :                 ZEND_REGISTER_RESOURCE(return_value, resultentry_next, le_result_entry);
     926               1 :                 resultentry_next->id = resultentry->id;
     927               1 :                 zend_list_addref(resultentry->id);
     928               1 :                 resultentry_next->data = entry_next;
     929               1 :                 resultentry_next->ber = NULL;
     930                 :         }
     931                 : }
     932                 : /* }}} */
     933                 : 
     934                 : /* {{{ proto array ldap_get_entries(resource link, resource result) U
     935                 :    Get all result entries */
     936                 : PHP_FUNCTION(ldap_get_entries)
     937              33 : {
     938                 :         zval *link, *result;
     939                 :         LDAPMessage *ldap_result, *ldap_result_entry;
     940                 :         zval *tmp1, *tmp2;
     941                 :         ldap_linkdata *ld;
     942                 :         LDAP *ldap;
     943                 :         int num_entries, num_attrib, num_values, i;
     944                 :         BerElement *ber;
     945                 :         char *attribute;
     946                 :         size_t attr_len;
     947                 :         struct berval **ldap_value;
     948                 :         char *dn;
     949                 : 
     950              33 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result) != SUCCESS) {
     951               3 :                 return;
     952                 :         }
     953                 : 
     954              30 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
     955              30 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
     956                 : 
     957              30 :         ldap = ld->link;
     958              30 :         num_entries = ldap_count_entries(ldap, ldap_result);
     959                 : 
     960              30 :         array_init(return_value);
     961              30 :         add_assoc_long(return_value, "count", num_entries);
     962                 : 
     963              30 :         if (num_entries == 0) {
     964               6 :                 return;
     965                 :         }
     966                 :         
     967              24 :         ldap_result_entry = ldap_first_entry(ldap, ldap_result);
     968              24 :         if (ldap_result_entry == NULL) {
     969               0 :                 zval_dtor(return_value);
     970               0 :                 RETURN_FALSE;
     971                 :         }
     972                 : 
     973              24 :         num_entries = 0;
     974              97 :         while (ldap_result_entry != NULL) {
     975              49 :                 MAKE_STD_ZVAL(tmp1);
     976              49 :                 array_init(tmp1);
     977                 : 
     978              49 :                 num_attrib = 0;
     979              49 :                 attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber);
     980                 : 
     981             215 :                 while (attribute != NULL) {
     982             117 :                         ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute);
     983             117 :                         num_values = ldap_count_values_len(ldap_value);
     984                 : 
     985             117 :                         MAKE_STD_ZVAL(tmp2);
     986             117 :                         array_init(tmp2);
     987             117 :                         add_assoc_long(tmp2, "count", num_values);
     988             232 :                         for (i = 0; i < num_values; i++) {
     989             115 :                                 add_index_stringl(tmp2, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len, 1);
     990                 :                         }       
     991             117 :                         ldap_value_free_len(ldap_value);
     992                 : 
     993             117 :                         attr_len = strlen(attribute);
     994             117 :                         zend_hash_update(Z_ARRVAL_P(tmp1), php_strtolower(attribute, attr_len), attr_len+1, (void *) &tmp2, sizeof(zval *), NULL);
     995             117 :                         add_index_string(tmp1, num_attrib, attribute, 1);
     996                 : 
     997             117 :                         num_attrib++;
     998                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
     999             117 :                         ldap_memfree(attribute);
    1000                 : #endif
    1001             117 :                         attribute = ldap_next_attribute(ldap, ldap_result_entry, ber);
    1002                 :                 }
    1003                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1004              49 :                 if (ber != NULL) {
    1005              49 :                         ber_free(ber, 0);
    1006                 :                 }
    1007                 : #endif
    1008                 : 
    1009              49 :                 add_assoc_long(tmp1, "count", num_attrib);
    1010              49 :                 dn = ldap_get_dn(ldap, ldap_result_entry);
    1011              49 :                 add_assoc_string(tmp1, "dn", dn, 1);
    1012                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1013              49 :                 ldap_memfree(dn);
    1014                 : #else
    1015                 :                 free(dn);
    1016                 : #endif
    1017                 : 
    1018              49 :                 zend_hash_index_update(Z_ARRVAL_P(return_value), num_entries, (void *) &tmp1, sizeof(zval *), NULL);
    1019                 :                 
    1020              49 :                 num_entries++;
    1021              49 :                 ldap_result_entry = ldap_next_entry(ldap, ldap_result_entry);
    1022                 :         }
    1023                 : 
    1024              24 :         add_assoc_long(return_value, "count", num_entries);
    1025                 : 
    1026                 : }
    1027                 : /* }}} */
    1028                 : 
    1029                 : /* {{{ proto string ldap_first_attribute(resource link, resource result_entry) U
    1030                 :    Return first attribute */
    1031                 : PHP_FUNCTION(ldap_first_attribute)
    1032               4 : {
    1033                 :         zval *link, *result_entry;
    1034                 :         ldap_linkdata *ld;
    1035                 :         ldap_resultentry *resultentry;
    1036                 :         char *attribute;
    1037                 : 
    1038               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
    1039               1 :                 return;
    1040                 :         }
    1041                 : 
    1042               3 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1043               3 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1044                 : 
    1045               2 :         if ((attribute = ldap_first_attribute(ld->link, resultentry->data, &resultentry->ber)) == NULL) {
    1046               0 :                 RETURN_FALSE;
    1047                 :         } else {
    1048               2 :                 RETVAL_STRING(attribute, 1);
    1049                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1050               2 :                 ldap_memfree(attribute);
    1051                 : #endif
    1052                 :         }
    1053                 : }
    1054                 : /* }}} */
    1055                 : 
    1056                 : /* {{{ proto string ldap_next_attribute(resource link, resource result_entry) U
    1057                 :    Get the next attribute in result */
    1058                 : PHP_FUNCTION(ldap_next_attribute)
    1059               6 : {
    1060                 :         zval *link, *result_entry;
    1061                 :         ldap_linkdata *ld;
    1062                 :         ldap_resultentry *resultentry;
    1063                 :         char *attribute;
    1064                 : 
    1065               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
    1066               1 :                 return;
    1067                 :         }
    1068                 : 
    1069               5 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1070               5 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1071                 : 
    1072               4 :         if (resultentry->ber == NULL) {
    1073               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "called before calling ldap_first_attribute() or no attributes found in result entry");
    1074               1 :                 RETURN_FALSE;
    1075                 :         }
    1076                 : 
    1077               3 :         if ((attribute = ldap_next_attribute(ld->link, resultentry->data, resultentry->ber)) == NULL) {
    1078                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1079               1 :                 if (resultentry->ber != NULL) {
    1080               1 :                         ber_free(resultentry->ber, 0);
    1081               1 :                         resultentry->ber = NULL;
    1082                 :                 }
    1083                 : #endif
    1084               1 :                 RETURN_FALSE;
    1085                 :         } else {
    1086               2 :                 RETVAL_STRING(attribute, 1);
    1087                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1088               2 :                 ldap_memfree(attribute);
    1089                 : #endif
    1090                 :         }
    1091                 : }
    1092                 : /* }}} */
    1093                 : 
    1094                 : /* {{{ proto array ldap_get_attributes(resource link, resource result_entry) U
    1095                 :    Get attributes from a search result entry */
    1096                 : PHP_FUNCTION(ldap_get_attributes)
    1097               3 : {
    1098                 :         zval *link, *result_entry;
    1099                 :         zval *tmp;
    1100                 :         ldap_linkdata *ld;
    1101                 :         ldap_resultentry *resultentry;
    1102                 :         char *attribute;
    1103                 :         struct berval **ldap_value;
    1104                 :         int i, num_values, num_attrib;
    1105                 :         BerElement *ber;
    1106                 : 
    1107               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
    1108               1 :                 return;
    1109                 :         }
    1110                 : 
    1111               2 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1112               2 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1113                 : 
    1114               1 :         array_init(return_value);
    1115               1 :         num_attrib = 0;
    1116                 :         
    1117               1 :         attribute = ldap_first_attribute(ld->link, resultentry->data, &ber);
    1118               5 :         while (attribute != NULL) {
    1119               3 :                 ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute);
    1120               3 :                 num_values = ldap_count_values_len(ldap_value);
    1121                 : 
    1122               3 :                 MAKE_STD_ZVAL(tmp);
    1123               3 :                 array_init(tmp);
    1124               3 :                 add_assoc_long(tmp, "count", num_values);
    1125               8 :                 for (i = 0; i < num_values; i++) {
    1126               5 :                         add_index_stringl(tmp, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len, 1);
    1127                 :                 }
    1128               3 :                 ldap_value_free_len(ldap_value);
    1129                 : 
    1130               3 :                 zend_hash_update(Z_ARRVAL_P(return_value), attribute, strlen(attribute)+1, (void *) &tmp, sizeof(zval *), NULL);
    1131               3 :                 add_index_string(return_value, num_attrib, attribute, 1);
    1132                 : 
    1133               3 :                 num_attrib++;
    1134                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1135               3 :                 ldap_memfree(attribute);
    1136                 : #endif
    1137               3 :                 attribute = ldap_next_attribute(ld->link, resultentry->data, ber);
    1138                 :         }
    1139                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1140               1 :         if (ber != NULL) {
    1141               1 :                 ber_free(ber, 0);
    1142                 :         }
    1143                 : #endif
    1144                 :         
    1145               1 :         add_assoc_long(return_value, "count", num_attrib);
    1146                 : }
    1147                 : /* }}} */
    1148                 : 
    1149                 : /* {{{ proto array ldap_get_values_len(resource link, resource result_entry, string attribute) U
    1150                 :    Get all values with lengths from a result entry */
    1151                 : PHP_FUNCTION(ldap_get_values_len)
    1152               7 : {
    1153                 :         zval *link, *result_entry;
    1154                 :         ldap_linkdata *ld;
    1155                 :         ldap_resultentry *resultentry;
    1156                 :         char *attr;
    1157                 :         struct berval **ldap_value_len;
    1158                 :         int i, num_values, attr_len;
    1159                 :         
    1160               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrs&", &link, &result_entry, &attr, &attr_len, UG(utf8_conv)) != SUCCESS) {
    1161               3 :                 return;
    1162                 :         }
    1163                 :         
    1164               4 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1165               4 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1166                 : 
    1167               4 :         if ((ldap_value_len = ldap_get_values_len(ld->link, resultentry->data, attr)) == NULL) {
    1168               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot get the value(s) of attribute %s", ldap_err2string(_get_lderrno(ld->link)));
    1169               1 :                 RETURN_FALSE;
    1170                 :         }
    1171                 :         
    1172               3 :         num_values = ldap_count_values_len(ldap_value_len);
    1173               3 :         array_init(return_value);
    1174                 :         
    1175               6 :         for (i=0; i<num_values; i++) {
    1176               3 :                 add_next_index_stringl(return_value, ldap_value_len[i]->bv_val, ldap_value_len[i]->bv_len, 1);
    1177                 :         }
    1178                 :         
    1179               3 :         add_assoc_long(return_value, "count", num_values);
    1180               3 :         ldap_value_free_len(ldap_value_len);
    1181                 : 
    1182                 : }
    1183                 : /* }}} */
    1184                 : 
    1185                 : /* {{{ proto string ldap_get_dn(resource link, resource result_entry) U
    1186                 :    Get the DN of a result entry */
    1187                 : PHP_FUNCTION(ldap_get_dn) 
    1188               3 : {
    1189                 :         zval *link, *result_entry;
    1190                 :         ldap_linkdata *ld;
    1191                 :         ldap_resultentry *resultentry;
    1192                 :         char *text;
    1193                 : 
    1194               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
    1195               1 :                 return;
    1196                 :         }
    1197                 :         
    1198               2 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1199               2 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1200                 : 
    1201               1 :         text = ldap_get_dn(ld->link, resultentry->data);
    1202               1 :         if (text != NULL) {
    1203               1 :                 RETVAL_STRING(text, 1);
    1204                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1205               1 :                 ldap_memfree(text);
    1206                 : #else
    1207                 :                 free(text);
    1208                 : #endif
    1209                 :         } else {
    1210               0 :                 RETURN_FALSE;
    1211                 :         }
    1212                 : }
    1213                 : /* }}} */
    1214                 : 
    1215                 : /* {{{ proto array ldap_explode_dn(string dn, int with_attrib) U
    1216                 :    Splits DN into its component parts */
    1217                 : PHP_FUNCTION(ldap_explode_dn)
    1218              10 : {
    1219                 :         long with_attrib;
    1220                 :         char *dn, **ldap_value;
    1221                 :         int i, count, dn_len;
    1222                 : 
    1223              10 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&l", &dn, &dn_len, UG(utf8_conv), &with_attrib) != SUCCESS) {
    1224               2 :                 return;
    1225                 :         }
    1226                 : 
    1227               8 :         if (!(ldap_value = ldap_explode_dn(dn, with_attrib))) {
    1228                 :                 /* Invalid parameters were passed to ldap_explode_dn */
    1229               4 :                 RETURN_FALSE;
    1230                 :         }
    1231                 : 
    1232               4 :         i=0;
    1233               4 :         while (ldap_value[i] != NULL) i++;
    1234               4 :         count = i;
    1235                 : 
    1236               4 :         array_init(return_value);
    1237                 : 
    1238               4 :         add_assoc_long(return_value, "count", count);
    1239              18 :         for (i = 0; i<count; i++) {
    1240              14 :                 add_index_string(return_value, i, ldap_value[i], 1);
    1241                 :         }
    1242                 : 
    1243               4 :         ldap_value_free(ldap_value);
    1244                 : }
    1245                 : /* }}} */
    1246                 : 
    1247                 : /* {{{ proto string ldap_dn2ufn(string dn) U
    1248                 :    Convert DN to User Friendly Naming format */
    1249                 : PHP_FUNCTION(ldap_dn2ufn)
    1250               5 : {
    1251                 :         char *dn, *ufn;
    1252                 :         int dn_len;
    1253                 : 
    1254               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &dn, &dn_len, UG(utf8_conv)) != SUCCESS) {
    1255               1 :                 return;
    1256                 :         }
    1257                 :         
    1258               4 :         ufn = ldap_dn2ufn(dn);
    1259                 :         
    1260               4 :         if (ufn != NULL) {
    1261               2 :                 RETVAL_STRING(ufn, 1);
    1262                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
    1263               2 :                 ldap_memfree(ufn);
    1264                 : #endif
    1265                 :         } else {
    1266               2 :                 RETURN_FALSE;
    1267                 :         }
    1268                 : }
    1269                 : /* }}} */
    1270                 : 
    1271                 : 
    1272                 : /* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */
    1273                 : #define PHP_LD_FULL_ADD 0xff
    1274                 : /* {{{ php_ldap_do_modify
    1275                 :  */
    1276                 : static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper)
    1277             206 : {
    1278                 :         zval *link, *entry, **value, **ivalue;
    1279                 :         ldap_linkdata *ld;
    1280                 :         char *dn;
    1281                 :         LDAPMod **ldap_mods;
    1282                 :         int i, j, num_attribs, num_values, dn_len, res;
    1283                 :         unsigned int attribute_len;
    1284                 :         int *num_berval;
    1285                 :         zstr attribute;
    1286                 :         ulong index;
    1287             206 :         int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */
    1288                 : 
    1289             206 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs&a", &link, &dn, &dn_len, UG(utf8_conv), &entry) != SUCCESS) {
    1290              20 :                 return;
    1291                 :         }       
    1292                 : 
    1293             186 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1294                 : 
    1295             186 :         num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
    1296             186 :         ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
    1297             186 :         num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
    1298             186 :         zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
    1299                 : 
    1300                 :         /* added by gerrit thomson to fix ldap_add using ldap_mod_add */
    1301             186 :         if (oper == PHP_LD_FULL_ADD) {
    1302             168 :                 oper = LDAP_MOD_ADD;
    1303             168 :                 is_full_add = 1;
    1304                 :         }
    1305                 :         /* end additional , gerrit thomson */
    1306                 : 
    1307             929 :         for (i = 0; i < num_attribs; i++) {
    1308             747 :                 ldap_mods[i] = emalloc(sizeof(LDAPMod));
    1309             747 :                 ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
    1310             747 :                 ldap_mods[i]->mod_type = NULL;
    1311                 : 
    1312             747 :                 res = zend_hash_get_current_key_ex(Z_ARRVAL_P(entry), &attribute, &attribute_len, &index, 0, NULL);
    1313             747 :                 if (res == HASH_KEY_IS_STRING) {
    1314               0 :                         ldap_mods[i]->mod_type = estrndup(attribute.s, attribute_len - 1);
    1315             747 :                 } else if (res == HASH_KEY_IS_UNICODE) {
    1316             744 :                         char *tmp = zend_unicode_to_ascii(attribute.u, attribute_len - 1 TSRMLS_CC);
    1317             744 :                         if (tmp) {
    1318             744 :                                 ldap_mods[i]->mod_type = estrdup(tmp);
    1319             744 :                                 efree(tmp);
    1320                 :                         } else {
    1321               0 :                                 goto error_out;
    1322                 :                         }
    1323                 :                 } else {
    1324               3 : error_out:
    1325               3 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown attribute in the data");
    1326                 :                         /* Free allocated memory */
    1327               9 :                         while (i >= 0) {
    1328               3 :                                 if (ldap_mods[i]->mod_type) {
    1329               0 :                                         efree(ldap_mods[i]->mod_type);
    1330                 :                                 }
    1331               3 :                                 efree(ldap_mods[i]);
    1332               3 :                                 i--;
    1333                 :                         }
    1334               3 :                         efree(num_berval);
    1335               3 :                         efree(ldap_mods);       
    1336               3 :                         RETURN_FALSE;
    1337                 :                 }
    1338                 : 
    1339             744 :                 zend_hash_get_current_data(Z_ARRVAL_P(entry), (void **)&value);
    1340                 : 
    1341             744 :                 if (Z_TYPE_PP(value) != IS_ARRAY) {
    1342             688 :                         num_values = 1;
    1343                 :                 } else {
    1344              56 :                         num_values = zend_hash_num_elements(Z_ARRVAL_PP(value));
    1345                 :                 }
    1346                 :                 
    1347             744 :                 num_berval[i] = num_values;
    1348             744 :                 ldap_mods[i]->mod_bvalues = safe_emalloc((num_values + 1), sizeof(struct berval *), 0);
    1349                 : 
    1350                 : /* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */
    1351            1432 :                 if ((num_values == 1) && (Z_TYPE_PP(value) != IS_ARRAY)) {
    1352             688 :                         convert_to_string_ex(value);
    1353             688 :                         ldap_mods[i]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval));
    1354             688 :                         ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_PP(value);
    1355             688 :                         ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_PP(value);
    1356                 :                 } else {        
    1357             217 :                         for (j = 0; j < num_values; j++) {
    1358             162 :                                 if (zend_hash_index_find(Z_ARRVAL_PP(value), j, (void **) &ivalue) != SUCCESS) {
    1359               1 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value array must have consecutive indices 0, 1, ...");
    1360               1 :                                         num_berval[i] = j;
    1361               1 :                                         num_attribs = i + 1;
    1362               1 :                                         RETVAL_FALSE;
    1363               1 :                                         goto errexit;
    1364                 :                                 }
    1365             161 :                                 convert_to_string_ex(ivalue);
    1366             161 :                                 ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval));
    1367             161 :                                 ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_PP(ivalue);
    1368             161 :                                 ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_PP(ivalue);
    1369                 :                         }
    1370                 :                 }
    1371             743 :                 ldap_mods[i]->mod_bvalues[num_values] = NULL;
    1372             743 :                 zend_hash_move_forward(Z_ARRVAL_P(entry));
    1373                 :         }
    1374             182 :         ldap_mods[num_attribs] = NULL;
    1375                 : 
    1376                 : /* check flag to see if do_mod was called to perform full add , gerrit thomson */
    1377             182 :         if (is_full_add == 1) {
    1378             166 :                 if ((i = ldap_add_s(ld->link, dn, ldap_mods)) != LDAP_SUCCESS) {
    1379               6 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Add: %s", ldap_err2string(i));
    1380               6 :                         RETVAL_FALSE;
    1381             160 :                 } else RETVAL_TRUE;
    1382                 :         } else {
    1383              16 :                 if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
    1384              12 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i));
    1385              12 :                         RETVAL_FALSE;
    1386               4 :                 } else RETVAL_TRUE;     
    1387                 :         }
    1388                 : 
    1389             183 : errexit:
    1390             927 :         for (i = 0; i < num_attribs; i++) {
    1391             744 :                 efree(ldap_mods[i]->mod_type);
    1392            1593 :                 for (j = 0; j < num_berval[i]; j++) {
    1393             849 :                         efree(ldap_mods[i]->mod_bvalues[j]);
    1394                 :                 }
    1395             744 :                 efree(ldap_mods[i]->mod_bvalues);
    1396             744 :                 efree(ldap_mods[i]);
    1397                 :         }
    1398             183 :         efree(num_berval);
    1399             183 :         efree(ldap_mods);       
    1400                 : 
    1401             183 :         return;
    1402                 : }
    1403                 : /* }}} */
    1404                 : 
    1405                 : /* {{{ proto bool ldap_add(resource link, string dn, array entry) U
    1406                 :    Add entries to LDAP directory */
    1407                 : PHP_FUNCTION(ldap_add)
    1408             172 : {
    1409                 :         /* use a newly define parameter into the do_modify so ldap_mod_add can be used the way it is supposed to be used , Gerrit THomson */
    1410             172 :         php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD);
    1411             172 : }
    1412                 : /* }}} */
    1413                 : 
    1414                 : /* three functions for attribute base modifications, gerrit Thomson */
    1415                 : 
    1416                 : /* {{{ proto bool ldap_mod_replace(resource link, string dn, array entry) U
    1417                 :    Replace attribute values with new ones */
    1418                 : PHP_FUNCTION(ldap_mod_replace)
    1419              17 : {
    1420              17 :         php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE);
    1421              17 : }
    1422                 : /* }}} */
    1423                 : 
    1424                 : /* {{{ proto bool ldap_mod_add(resource link, string dn, array entry) U
    1425                 :    Add attribute values to current */
    1426                 : PHP_FUNCTION(ldap_mod_add)
    1427               9 : {
    1428               9 :         php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD);
    1429               9 : }
    1430                 : /* }}} */
    1431                 : 
    1432                 : /* {{{ proto bool ldap_mod_del(resource link, string dn, array entry) U
    1433                 :    Delete attribute values */
    1434                 : PHP_FUNCTION(ldap_mod_del)
    1435               8 : {
    1436               8 :         php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE);
    1437               8 : }
    1438                 : /* }}} */
    1439                 : 
    1440                 : /* {{{ proto bool ldap_delete(resource link, string dn) U
    1441                 :    Delete an entry from a directory */
    1442                 : PHP_FUNCTION(ldap_delete)
    1443             168 : {
    1444                 :         zval *link;
    1445                 :         ldap_linkdata *ld;
    1446                 :         char *dn;
    1447                 :         int rc, dn_len;
    1448                 : 
    1449             168 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs&", &link, &dn, &dn_len, UG(utf8_conv)) != SUCCESS) {
    1450               3 :                 return;
    1451                 :         }
    1452                 : 
    1453             165 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1454                 : 
    1455             165 :         if ((rc = ldap_delete_s(ld->link, dn)) != LDAP_SUCCESS) {
    1456               5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Delete: %s", ldap_err2string(rc));
    1457               5 :                 RETURN_FALSE;
    1458                 :         }
    1459                 : 
    1460             160 :         RETURN_TRUE;
    1461                 : }
    1462                 : /* }}} */
    1463                 : 
    1464                 : /* {{{ proto int ldap_errno(resource link) U
    1465                 :    Get the current ldap error number */
    1466                 : PHP_FUNCTION(ldap_errno)
    1467               9 : {
    1468                 :         zval *link;
    1469                 :         ldap_linkdata *ld;
    1470                 : 
    1471               9 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &link) != SUCCESS) {
    1472               2 :                 return;
    1473                 :         }
    1474                 : 
    1475               7 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1476                 : 
    1477               7 :         RETURN_LONG(_get_lderrno(ld->link));
    1478                 : }
    1479                 : /* }}} */
    1480                 : 
    1481                 : /* {{{ proto string ldap_err2str(int errno) U
    1482                 :    Convert error number to error string */
    1483                 : PHP_FUNCTION(ldap_err2str)
    1484               4 : {
    1485                 :         long perrno;
    1486                 : 
    1487               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &perrno) != SUCCESS) {
    1488               3 :                 return;
    1489                 :         }
    1490                 : 
    1491               1 :         RETURN_STRING(ldap_err2string(perrno), 1);
    1492                 : }
    1493                 : /* }}} */
    1494                 : 
    1495                 : /* {{{ proto string ldap_error(resource link) U
    1496                 :    Get the current ldap error string */
    1497                 : PHP_FUNCTION(ldap_error) 
    1498               9 : {
    1499                 :         zval *link;
    1500                 :         ldap_linkdata *ld;
    1501                 :         int ld_errno;
    1502                 : 
    1503               9 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &link) != SUCCESS) {
    1504               2 :                 return;
    1505                 :         }
    1506                 : 
    1507               7 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1508                 : 
    1509               7 :         ld_errno = _get_lderrno(ld->link);
    1510                 : 
    1511               7 :         RETURN_STRING(ldap_err2string(ld_errno), 1);
    1512                 : }
    1513                 : /* }}} */
    1514                 : 
    1515                 : /* {{{ proto bool ldap_compare(resource link, string dn, string attr, string value) U
    1516                 :    Determine if an entry has a specific value for one of its attributes */
    1517                 : PHP_FUNCTION(ldap_compare) 
    1518               7 : {
    1519                 :         zval *link;
    1520                 :         char *dn, *attr, *value;
    1521                 :         int dn_len, attr_len, value_len;
    1522                 :         ldap_linkdata *ld;
    1523                 :         int errno;
    1524                 : 
    1525               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs&s&s&", &link, &dn, &dn_len, UG(utf8_conv), &attr, &attr_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) != SUCCESS) {
    1526               4 :                 return;
    1527                 :         }
    1528                 : 
    1529               3 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1530                 : 
    1531               3 :         errno = ldap_compare_s(ld->link, dn, attr, value);
    1532                 : 
    1533               3 :         switch (errno) {
    1534                 :                 case LDAP_COMPARE_TRUE:
    1535               1 :                         RETURN_TRUE;
    1536                 :                         break;
    1537                 : 
    1538                 :                 case LDAP_COMPARE_FALSE:
    1539               1 :                         RETURN_FALSE;
    1540                 :                         break;
    1541                 :         }
    1542                 :         
    1543               1 :         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compare: %s", ldap_err2string(errno));
    1544               1 :         RETURN_LONG(-1);
    1545                 : }
    1546                 : /* }}} */
    1547                 : 
    1548                 : /* {{{ proto bool ldap_sort(resource link, resource result, string sortfilter) U
    1549                 :    Sort LDAP result entries */
    1550                 : PHP_FUNCTION(ldap_sort)
    1551               7 : {
    1552                 :         zval *link, *result;
    1553                 :         ldap_linkdata *ld;
    1554                 :         char *sortfilter;
    1555                 :         int sflen;
    1556                 :         zend_rsrc_list_entry *le;
    1557                 : 
    1558               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrs&", &link, &result, &sortfilter, &sflen, UG(utf8_conv)) != SUCCESS) {
    1559               4 :                 RETURN_FALSE;
    1560                 :         }
    1561                 : 
    1562               3 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1563                 : 
    1564               3 :         if (zend_hash_index_find(&EG(regular_list), Z_LVAL_P(result), (void **) &le) != SUCCESS || le->type != le_result) {
    1565               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied resource is not a valid ldap result resource");
    1566               1 :                 RETURN_FALSE;
    1567                 :         }
    1568                 : 
    1569               2 :         if (ldap_sort_entries(ld->link, (LDAPMessage **) &le->ptr, sflen ? sortfilter : NULL, strcmp) != LDAP_SUCCESS) {
    1570               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ldap_err2string(errno));
    1571               0 :                 RETURN_FALSE;
    1572                 :         }
    1573                 : 
    1574               2 :         RETURN_TRUE;
    1575                 : }
    1576                 : /* }}} */
    1577                 : 
    1578                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
    1579                 : /* {{{ proto bool ldap_get_option(resource link, int option, mixed retval) U
    1580                 :    Get the current value of various session-wide parameters */
    1581                 : PHP_FUNCTION(ldap_get_option) 
    1582              23 : {
    1583                 :         zval *link, *retval;
    1584                 :         ldap_linkdata *ld;
    1585                 :         long option;
    1586                 :         
    1587              23 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &link, &option, &retval) != SUCCESS) {
    1588               4 :                 return;
    1589                 :         }
    1590                 : 
    1591              19 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1592                 : 
    1593              19 :         switch (option) {
    1594                 :         /* options with int value */
    1595                 :         case LDAP_OPT_DEREF:
    1596                 :         case LDAP_OPT_SIZELIMIT:
    1597                 :         case LDAP_OPT_TIMELIMIT:
    1598                 :         case LDAP_OPT_PROTOCOL_VERSION:
    1599                 :         case LDAP_OPT_ERROR_NUMBER:
    1600                 :         case LDAP_OPT_REFERRALS:
    1601                 : #ifdef LDAP_OPT_RESTART
    1602                 :         case LDAP_OPT_RESTART:
    1603                 : #endif
    1604                 : #ifdef LDAP_OPT_X_TLS
    1605                 :         case LDAP_OPT_X_TLS_REQUIRE_CERT:
    1606                 : #ifdef LDAP_OPT_X_TLS_CRLCHECK
    1607                 :         case LDAP_OPT_X_TLS_CRLCHECK:
    1608                 : #endif
    1609                 : #endif          
    1610                 :                 {
    1611                 :                         int val;
    1612                 : 
    1613              12 :                         if (ldap_get_option(ld->link, option, &val)) {
    1614               0 :                                 RETURN_FALSE;
    1615                 :                         }
    1616              12 :                         zval_dtor(retval);
    1617              12 :                         ZVAL_LONG(retval, val);
    1618              12 :                 } break;
    1619                 : #ifdef LDAP_OPT_NETWORK_TIMEOUT
    1620                 :         case LDAP_OPT_NETWORK_TIMEOUT:
    1621                 :                 {
    1622               2 :                         struct timeval *timeout = NULL;
    1623                 : 
    1624               2 :                         if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
    1625               0 :                                 if (timeout) {
    1626               0 :                                         ldap_memfree(timeout);
    1627                 :                                 }
    1628               0 :                                 RETURN_FALSE;
    1629                 :                         }                   
    1630               2 :                         if (!timeout) {
    1631               0 :                                 RETURN_FALSE;
    1632                 :                         }
    1633               2 :                         zval_dtor(retval);
    1634               2 :                         ZVAL_LONG(retval, timeout->tv_sec);
    1635               2 :                         ldap_memfree(timeout);
    1636               2 :                 } break;
    1637                 : #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
    1638                 :         case LDAP_X_OPT_CONNECT_TIMEOUT:
    1639                 :                 {
    1640                 :                         int timeout;
    1641                 : 
    1642                 :                         if (ldap_get_option(ld->link, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
    1643                 :                                 RETURN_FALSE;
    1644                 :                         }                       
    1645                 :                         zval_dtor(retval);
    1646                 :                         ZVAL_LONG(retval, (timeout / 1000));
    1647                 :                 } break;
    1648                 : #endif
    1649                 :         /* options with string value */
    1650                 :         case LDAP_OPT_ERROR_STRING:
    1651                 : #ifdef LDAP_OPT_HOST_NAME
    1652                 :         case LDAP_OPT_HOST_NAME:
    1653                 : #endif
    1654                 : #ifdef HAVE_LDAP_SASL
    1655                 :         case LDAP_OPT_X_SASL_MECH:   
    1656                 :         case LDAP_OPT_X_SASL_REALM:
    1657                 :         case LDAP_OPT_X_SASL_AUTHCID:
    1658                 :         case LDAP_OPT_X_SASL_AUTHZID:
    1659                 : #endif
    1660                 : #ifdef LDAP_OPT_X_TLS
    1661                 :         case LDAP_OPT_X_TLS_CACERTFILE:
    1662                 :         case LDAP_OPT_X_TLS_CACERTDIR:
    1663                 :         case LDAP_OPT_X_TLS_CERTFILE:
    1664                 :         case LDAP_OPT_X_TLS_KEYFILE:
    1665                 : #endif         
    1666                 : #ifdef LDAP_OPT_MATCHED_DN
    1667                 :         case LDAP_OPT_MATCHED_DN:
    1668                 : #endif
    1669                 :                 {
    1670               1 :                         char *val = NULL;
    1671                 : 
    1672               1 :                         if (ldap_get_option(ld->link, option, &val) || val == NULL || *val == '\0') {
    1673               0 :                                 if (val) {
    1674               0 :                                         ldap_memfree(val);
    1675                 :                                 }
    1676               0 :                                 RETURN_FALSE;
    1677                 :                         }
    1678               1 :                         zval_dtor(retval);
    1679               1 :                         ZVAL_STRING(retval, val, 1);
    1680               1 :                         ldap_memfree(val);
    1681               1 :                 } break;
    1682                 : /* options not implemented
    1683                 :         case LDAP_OPT_SERVER_CONTROLS:
    1684                 :         case LDAP_OPT_CLIENT_CONTROLS:
    1685                 :         case LDAP_OPT_API_INFO:
    1686                 :         case LDAP_OPT_API_FEATURE_INFO:
    1687                 : */
    1688                 :         default:
    1689               4 :                 RETURN_FALSE;
    1690                 :         }
    1691              15 :         RETURN_TRUE;
    1692                 : }
    1693                 : /* }}} */
    1694                 : 
    1695                 : /* {{{ proto bool ldap_set_option(resource link, int option, mixed newval) U
    1696                 :    Set the value of various session-wide parameters */
    1697                 : PHP_FUNCTION(ldap_set_option) 
    1698             194 : {
    1699                 :         zval *link, **newval;
    1700                 :         ldap_linkdata *ld;
    1701                 :         LDAP *ldap;
    1702                 :         long option;
    1703                 :         
    1704             194 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zlZ", &link, &option, &newval) != SUCCESS) {
    1705               4 :                 return;
    1706                 :         }
    1707                 : 
    1708             190 :         if (Z_TYPE_P(link) == IS_NULL) {
    1709               0 :                 ldap = NULL;
    1710                 :         } else {
    1711             190 :                 ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1712             190 :                 ldap = ld->link;
    1713                 :         }
    1714                 : 
    1715             190 :         switch (option) {
    1716                 :         /* options with int value */
    1717                 :         case LDAP_OPT_DEREF:
    1718                 :         case LDAP_OPT_SIZELIMIT:
    1719                 :         case LDAP_OPT_TIMELIMIT:
    1720                 :         case LDAP_OPT_PROTOCOL_VERSION:
    1721                 :         case LDAP_OPT_ERROR_NUMBER:
    1722                 : #ifdef LDAP_OPT_DEBUG_LEVEL
    1723                 :         case LDAP_OPT_DEBUG_LEVEL:
    1724                 : #endif
    1725                 : #ifdef LDAP_OPT_X_TLS
    1726                 :         case LDAP_OPT_X_TLS_REQUIRE_CERT:
    1727                 : #ifdef LDAP_OPT_X_TLS_CRLCHECK
    1728                 :         case LDAP_OPT_X_TLS_CRLCHECK:
    1729                 : #endif
    1730                 : #endif          
    1731                 :                 {
    1732                 :                         int val;
    1733                 : 
    1734             171 :                         convert_to_long_ex(newval);
    1735             171 :                         val = Z_LVAL_PP(newval);
    1736             171 :                         if (ldap_set_option(ldap, option, &val)) {
    1737               1 :                                 RETURN_FALSE;
    1738                 :                         }
    1739             170 :                 } break;
    1740                 : #ifdef LDAP_OPT_NETWORK_TIMEOUT
    1741                 :         case LDAP_OPT_NETWORK_TIMEOUT:
    1742                 :                 {
    1743                 :                         struct timeval timeout;
    1744                 : 
    1745               2 :                         convert_to_long_ex(newval);
    1746               2 :                         timeout.tv_sec = Z_LVAL_PP(newval);
    1747               2 :                         timeout.tv_usec = 0;
    1748               2 :                         if (ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
    1749               0 :                                 RETURN_FALSE;
    1750                 :                         }                       
    1751               2 :                 } break;
    1752                 : #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
    1753                 :         case LDAP_X_OPT_CONNECT_TIMEOUT:
    1754                 :                 {
    1755                 :                         int timeout;
    1756                 : 
    1757                 :                         convert_to_long_ex(newval);
    1758                 :                         timeout = 1000 * Z_LVAL_PP(newval); /* Convert to milliseconds */
    1759                 :                         if (ldap_set_option(ldap, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
    1760                 :                                 RETURN_FALSE;
    1761                 :                         }                       
    1762                 :                 } break;
    1763                 : #endif
    1764                 :                 /* options with string value */
    1765                 :         case LDAP_OPT_ERROR_STRING:
    1766                 : #ifdef LDAP_OPT_HOST_NAME
    1767                 :         case LDAP_OPT_HOST_NAME:
    1768                 : #endif
    1769                 : #ifdef HAVE_LDAP_SASL
    1770                 :         case LDAP_OPT_X_SASL_MECH:   
    1771                 :         case LDAP_OPT_X_SASL_REALM:
    1772                 :         case LDAP_OPT_X_SASL_AUTHCID:
    1773                 :         case LDAP_OPT_X_SASL_AUTHZID:
    1774                 : #endif
    1775                 : #ifdef LDAP_OPT_X_TLS
    1776                 :         case LDAP_OPT_X_TLS_CACERTFILE:
    1777                 :         case LDAP_OPT_X_TLS_CACERTDIR:
    1778                 :         case LDAP_OPT_X_TLS_CERTFILE:
    1779                 :         case LDAP_OPT_X_TLS_KEYFILE:
    1780                 : #endif         
    1781                 : #ifdef LDAP_OPT_MATCHED_DN
    1782                 :         case LDAP_OPT_MATCHED_DN:
    1783                 : #endif
    1784                 :                 {
    1785                 :                         char *val;
    1786               1 :                         convert_to_string_ex(newval);
    1787               1 :                         val = Z_STRVAL_PP(newval);
    1788               1 :                         if (ldap_set_option(ldap, option, val)) {
    1789               0 :                                 RETURN_FALSE;
    1790                 :                         }
    1791               1 :                 } break;
    1792                 :                 /* options with boolean value */
    1793                 :         case LDAP_OPT_REFERRALS:
    1794                 : #ifdef LDAP_OPT_RESTART
    1795                 :         case LDAP_OPT_RESTART:
    1796                 : #endif
    1797                 :                 {
    1798                 :                         void *val;
    1799               4 :                         convert_to_boolean_ex(newval);
    1800               4 :                         val = Z_LVAL_PP(newval)
    1801                 :                                 ? LDAP_OPT_ON : LDAP_OPT_OFF;
    1802               4 :                         if (ldap_set_option(ldap, option, val)) {
    1803               0 :                                 RETURN_FALSE;
    1804                 :                         }
    1805               4 :                 } break;
    1806                 :                 /* options with control list value */
    1807                 :         case LDAP_OPT_SERVER_CONTROLS:
    1808                 :         case LDAP_OPT_CLIENT_CONTROLS:
    1809                 :                 {
    1810                 :                         LDAPControl *ctrl, **ctrls, **ctrlp;
    1811                 :                         zval **ctrlval, **val;
    1812                 :                         int ncontrols;
    1813              11 :                         char error=0;
    1814                 : 
    1815              11 :                         if ((Z_TYPE_PP(newval) != IS_ARRAY) || !(ncontrols = zend_hash_num_elements(Z_ARRVAL_PP(newval)))) {
    1816               1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected non-empty array value for this option");
    1817               1 :                                 RETURN_FALSE;
    1818                 :                         }
    1819              10 :                         ctrls = safe_emalloc((1 + ncontrols), sizeof(*ctrls), 0);
    1820              10 :                         *ctrls = NULL;
    1821              10 :                         ctrlp = ctrls;
    1822              10 :                         zend_hash_internal_pointer_reset(Z_ARRVAL_PP(newval));
    1823              34 :                         while (zend_hash_get_current_data(Z_ARRVAL_PP(newval), (void**)&ctrlval) == SUCCESS) {
    1824              16 :                                 if (Z_TYPE_PP(ctrlval) != IS_ARRAY) {
    1825               1 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array value must contain only arrays, where each array is a control");
    1826               1 :                                         error = 1;
    1827               1 :                                         break;
    1828                 :                                 }
    1829              15 :                                 if (zend_utf8_hash_find(Z_ARRVAL_PP(ctrlval), "oid", sizeof("oid"), (void **) &val) != SUCCESS) {
    1830               1 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Control must have an oid key");
    1831               1 :                                         error = 1;
    1832               1 :                                         break;
    1833                 :                                 }
    1834              14 :                                 ctrl = *ctrlp = emalloc(sizeof(**ctrlp));
    1835              14 :                                 convert_to_string_ex(val);
    1836              14 :                                 ctrl->ldctl_oid = Z_STRVAL_PP(val);
    1837              14 :                                 if (zend_utf8_hash_find(Z_ARRVAL_PP(ctrlval), "value", sizeof("value"), (void **) &val) == SUCCESS) {
    1838               5 :                                         convert_to_string_ex(val);
    1839               5 :                                         ctrl->ldctl_value.bv_val = Z_STRVAL_PP(val);
    1840               5 :                                         ctrl->ldctl_value.bv_len = Z_STRLEN_PP(val);
    1841                 :                                 } else {
    1842               9 :                                         ctrl->ldctl_value.bv_val = NULL;
    1843               9 :                                         ctrl->ldctl_value.bv_len = 0;
    1844                 :                                 }
    1845              14 :                                 if (zend_utf8_hash_find(Z_ARRVAL_PP(ctrlval), "iscritical", sizeof("iscritical"), (void **) &val) == SUCCESS) {
    1846               5 :                                         convert_to_boolean_ex(val);
    1847               5 :                                         ctrl->ldctl_iscritical = Z_BVAL_PP(val);
    1848                 :                                 } else {
    1849               9 :                                         ctrl->ldctl_iscritical = 0;
    1850                 :                                 }
    1851                 :                                 
    1852              14 :                                 ++ctrlp;
    1853              14 :                                 *ctrlp = NULL;
    1854              14 :                                 zend_hash_move_forward(Z_ARRVAL_PP(newval));
    1855                 :                         }
    1856              10 :                         if (!error) {
    1857               8 :                                 error = ldap_set_option(ldap, option, ctrls);
    1858                 :                         }
    1859              10 :                         ctrlp = ctrls;
    1860              34 :                         while (*ctrlp) {
    1861              14 :                                 efree(*ctrlp);
    1862              14 :                                 ctrlp++;
    1863                 :                         }
    1864              10 :                         efree(ctrls);
    1865              10 :                         if (error) {
    1866               2 :                                 RETURN_FALSE;
    1867                 :                         }
    1868               8 :                 } break;
    1869                 :         default:
    1870               1 :                 RETURN_FALSE;
    1871                 :         }
    1872             185 :         RETURN_TRUE;
    1873                 : }
    1874                 : /* }}} */
    1875                 : 
    1876                 : #ifdef HAVE_LDAP_PARSE_RESULT
    1877                 : /* {{{ proto bool ldap_parse_result(resource link, resource result, int errcode, string matcheddn, string errmsg, array referrals) U
    1878                 :    Extract information from result */
    1879                 : PHP_FUNCTION(ldap_parse_result) 
    1880               2 : {
    1881                 :         zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals;
    1882                 :         ldap_linkdata *ld;
    1883                 :         LDAPMessage *ldap_result;
    1884                 :         char **lreferrals, **refp;
    1885                 :         char *lmatcheddn, *lerrmsg;
    1886               2 :         int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
    1887                 : 
    1888               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz|zzz", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
    1889               1 :                 return; 
    1890                 :         }
    1891                 : 
    1892               1 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1893               1 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
    1894                 : 
    1895               1 :         rc = ldap_parse_result(ld->link, ldap_result, &lerrcode,
    1896                 :                                 myargcount > 3 ? &lmatcheddn : NULL,
    1897                 :                                 myargcount > 4 ? &lerrmsg : NULL,
    1898                 :                                 myargcount > 5 ? &lreferrals : NULL,
    1899                 :                                 NULL /* &serverctrls */,
    1900                 :                                 0);
    1901               1 :         if (rc != LDAP_SUCCESS) {
    1902               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s", ldap_err2string(rc));
    1903               0 :                 RETURN_FALSE;
    1904                 :         }
    1905                 : 
    1906               1 :         zval_dtor(errcode);
    1907               1 :         ZVAL_LONG(errcode, lerrcode);
    1908                 : 
    1909                 :         /* Reverse -> fall through */
    1910               1 :         switch (myargcount) {
    1911                 :                 case 6:
    1912               1 :                         zval_dtor(referrals);
    1913               1 :                         array_init(referrals);
    1914               1 :                         if (lreferrals != NULL) {
    1915               1 :                                 refp = lreferrals;
    1916               3 :                                 while (*refp) {
    1917               1 :                                         add_next_index_string(referrals, *refp, 1);
    1918               1 :                                         refp++;
    1919                 :                                 }
    1920               1 :                                 ldap_value_free(lreferrals);
    1921                 :                         }
    1922                 :                 case 5:
    1923               1 :                         zval_dtor(errmsg);
    1924               1 :                         if (lerrmsg == NULL) {
    1925               0 :                                 ZVAL_EMPTY_STRING(errmsg);
    1926                 :                         } else {
    1927               1 :                                 ZVAL_STRING(errmsg, lerrmsg, 1);
    1928               1 :                                 ldap_memfree(lerrmsg);
    1929                 :                         }
    1930                 :                 case 4: 
    1931               1 :                         zval_dtor(matcheddn);
    1932               1 :                         if (lmatcheddn == NULL) {
    1933               0 :                                 ZVAL_EMPTY_STRING(matcheddn);
    1934                 :                         } else {
    1935               1 :                                 ZVAL_STRING(matcheddn, lmatcheddn, 1);
    1936               1 :                                 ldap_memfree(lmatcheddn);
    1937                 :                         }
    1938                 :         }
    1939               1 :         RETURN_TRUE;
    1940                 : }
    1941                 : /* }}} */
    1942                 : #endif
    1943                 : 
    1944                 : /* {{{ proto resource ldap_first_reference(resource link, resource result) U
    1945                 :    Return first reference */
    1946                 : PHP_FUNCTION(ldap_first_reference)
    1947               6 : {
    1948                 :         zval *link, *result;
    1949                 :         ldap_linkdata *ld;
    1950                 :         ldap_resultentry *resultentry;
    1951                 :         LDAPMessage *ldap_result, *entry;
    1952                 : 
    1953               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result) != SUCCESS) {
    1954               2 :                 return;
    1955                 :         }
    1956                 : 
    1957               4 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1958               4 :         ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
    1959                 : 
    1960               3 :         if ((entry = ldap_first_reference(ld->link, ldap_result)) == NULL) {
    1961               0 :                 RETVAL_FALSE;
    1962                 :         } else {
    1963               3 :                 resultentry = emalloc(sizeof(ldap_resultentry));
    1964               3 :                 ZEND_REGISTER_RESOURCE(return_value, resultentry, le_result_entry);
    1965               3 :                 resultentry->id = Z_LVAL_P(result);
    1966               3 :                 zend_list_addref(resultentry->id);
    1967               3 :                 resultentry->data = entry;
    1968                 :         }
    1969                 : }
    1970                 : /* }}} */
    1971                 : 
    1972                 : /* {{{ proto resource ldap_next_reference(resource link, resource reference_entry) U
    1973                 :    Get next reference */
    1974                 : PHP_FUNCTION(ldap_next_reference)
    1975               4 : {
    1976                 :         zval *link, *result_entry;
    1977                 :         ldap_linkdata *ld;
    1978                 :         ldap_resultentry *resultentry, *resultentry_next;
    1979                 :         LDAPMessage *entry_next;
    1980                 : 
    1981               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &link, &result_entry) != SUCCESS) {
    1982               2 :                 return;
    1983                 :         }
    1984                 : 
    1985               2 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    1986               2 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    1987                 : 
    1988               1 :         if ((entry_next = ldap_next_reference(ld->link, resultentry->data)) == NULL) {
    1989               0 :                 RETVAL_FALSE;
    1990                 :         } else {
    1991               1 :                 resultentry_next = emalloc(sizeof(ldap_resultentry));
    1992               1 :                 ZEND_REGISTER_RESOURCE(return_value, resultentry_next, le_result_entry);
    1993               1 :                 resultentry_next->id = resultentry->id;
    1994               1 :                 zend_list_addref(resultentry->id);
    1995               1 :                 resultentry_next->data = entry_next;
    1996                 :         }
    1997                 : }
    1998                 : /* }}} */
    1999                 : 
    2000                 : #ifdef HAVE_LDAP_PARSE_REFERENCE
    2001                 : /* {{{ proto bool ldap_parse_reference(resource link, resource reference_entry, array referrals) U
    2002                 :    Extract information from reference entry */
    2003                 : PHP_FUNCTION(ldap_parse_reference)
    2004               6 : {
    2005                 :         zval *link, *result_entry, *referrals;
    2006                 :         ldap_linkdata *ld;
    2007                 :         ldap_resultentry *resultentry;
    2008                 :         char **lreferrals, **refp;
    2009                 : 
    2010               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz", &link, &result_entry, &referrals) != SUCCESS) {
    2011               2 :                 return;
    2012                 :         }
    2013                 : 
    2014               4 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    2015               4 :         ZEND_FETCH_RESOURCE(resultentry, ldap_resultentry *, &result_entry, -1, "ldap result entry", le_result_entry);
    2016                 : 
    2017               3 :         if (ldap_parse_reference(ld->link, resultentry->data, &lreferrals, NULL /* &serverctrls */, 0) != LDAP_SUCCESS) {
    2018               0 :                 RETURN_FALSE;
    2019                 :         }
    2020                 : 
    2021               3 :         zval_dtor(referrals);
    2022               3 :         array_init(referrals);
    2023               3 :         if (lreferrals != NULL) {
    2024               3 :                 refp = lreferrals;
    2025               9 :                 while (*refp) {
    2026               3 :                         add_next_index_string(referrals, *refp, 1);
    2027               3 :                         refp++;
    2028                 :                 }
    2029               3 :                 ldap_value_free(lreferrals);
    2030                 :         }
    2031               3 :         RETURN_TRUE;
    2032                 : }
    2033                 : /* }}} */
    2034                 : #endif
    2035                 : 
    2036                 : /* {{{ proto bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn); U
    2037                 :    Modify the name of an entry */
    2038                 : PHP_FUNCTION(ldap_rename)
    2039               4 : {
    2040                 :         zval *link;
    2041                 :         ldap_linkdata *ld;
    2042                 :         int rc;
    2043                 :         char *dn, *newrdn, *newparent;
    2044                 :         int dn_len, newrdn_len, newparent_len;
    2045                 :         zend_bool deleteoldrdn;
    2046                 :         
    2047               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs&s&s&b", &link, &dn, &dn_len, UG(utf8_conv), &newrdn, &newrdn_len, UG(utf8_conv), &newparent, &newparent_len, UG(utf8_conv), &deleteoldrdn) != SUCCESS) {
    2048               1 :                 return;
    2049                 :         }
    2050                 : 
    2051               3 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    2052                 : 
    2053               3 :         if (newparent_len == 0) {
    2054               0 :                 newparent = NULL;
    2055                 :         }
    2056                 : 
    2057                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
    2058               3 :         rc = ldap_rename_s(ld->link, dn, newrdn, newparent, deleteoldrdn, NULL, NULL);
    2059                 : #else
    2060                 :         if (newparent_len != 0) {
    2061                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "You are using old LDAP API, newparent must be the empty string, can only modify RDN");
    2062                 :                 RETURN_FALSE;
    2063                 :         }
    2064                 : /* could support old APIs but need check for ldap_modrdn2()/ldap_modrdn() */
    2065                 :         rc = ldap_modrdn2_s(ld->link, dn, newrdn, deleteoldrdn);
    2066                 : #endif
    2067                 : 
    2068               3 :         if (rc == LDAP_SUCCESS) {
    2069               2 :                 RETURN_TRUE;
    2070                 :         }
    2071               1 :         RETURN_FALSE;
    2072                 : }
    2073                 : /* }}} */
    2074                 : 
    2075                 : #ifdef HAVE_LDAP_START_TLS_S
    2076                 : /* {{{ proto bool ldap_start_tls(resource link) U
    2077                 :    Start TLS */
    2078                 : PHP_FUNCTION(ldap_start_tls)
    2079               3 : {
    2080                 :         zval *link;
    2081                 :         ldap_linkdata *ld;
    2082               3 :         int rc, protocol = LDAP_VERSION3;
    2083                 : 
    2084               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &link) != SUCCESS) {
    2085               2 :                 return;
    2086                 :         }
    2087                 : 
    2088               1 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    2089                 : 
    2090               1 :         if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
    2091                 :                 ((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
    2092                 :         ) {
    2093               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to start TLS: %s", ldap_err2string(rc));
    2094               0 :                 RETURN_FALSE;
    2095                 :         } else {
    2096               1 :                 RETURN_TRUE;
    2097                 :         }
    2098                 : }
    2099                 : /* }}} */
    2100                 : #endif
    2101                 : #endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 */
    2102                 : 
    2103                 : #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
    2104                 : /* {{{ _ldap_rebind_proc()
    2105                 : */
    2106                 : int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params)
    2107               0 : {
    2108                 :         ldap_linkdata *ld;
    2109                 :         int retval;
    2110                 :         zval *cb_url;
    2111                 :         zval **cb_args[2];
    2112                 :         zval *cb_retval;
    2113               0 :         zval *cb_link = (zval *) params;
    2114                 :         TSRMLS_FETCH();
    2115                 : 
    2116               0 :         ld = (ldap_linkdata *) zend_fetch_resource(&cb_link TSRMLS_CC, -1, "ldap link", NULL, 1, le_link);
    2117                 : 
    2118                 :         /* link exists and callback set? */
    2119               0 :         if (ld == NULL || ld->rebindproc == NULL) {
    2120               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link not found or no callback set");
    2121               0 :                 return LDAP_OTHER;
    2122                 :         }
    2123                 : 
    2124                 :         /* callback */
    2125               0 :         MAKE_STD_ZVAL(cb_url);
    2126               0 :         ZVAL_STRING(cb_url, estrdup(url), 0);
    2127               0 :         cb_args[0] = &cb_link;
    2128               0 :         cb_args[1] = &cb_url;
    2129               0 :         if (call_user_function_ex(EG(function_table), NULL, ld->rebindproc, &cb_retval, 2, cb_args, 0, NULL TSRMLS_CC) == SUCCESS && cb_retval) {
    2130               0 :                 convert_to_long_ex(&cb_retval);
    2131               0 :                 retval = Z_LVAL_P(cb_retval);
    2132               0 :                 zval_ptr_dtor(&cb_retval);
    2133                 :         } else {
    2134               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "rebind_proc PHP callback failed");
    2135               0 :                 retval = LDAP_OTHER;
    2136                 :         }
    2137               0 :         zval_dtor(cb_url);
    2138               0 :         FREE_ZVAL(cb_url);
    2139               0 :         return retval;
    2140                 : }
    2141                 : /* }}} */
    2142                 : 
    2143                 : /* {{{ proto bool ldap_set_rebind_proc(resource link, string callback) U
    2144                 :    Set a callback function to do re-binds on referral chasing. */
    2145                 : PHP_FUNCTION(ldap_set_rebind_proc)
    2146               6 : {
    2147                 :         zval *link, *callback;
    2148                 :         ldap_linkdata *ld;
    2149                 :         zval callback_name;
    2150                 : 
    2151               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &link, &callback) != SUCCESS) {
    2152               2 :                 RETURN_FALSE;
    2153                 :         }
    2154                 : 
    2155               4 :         ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
    2156                 : 
    2157               4 :         if ((Z_TYPE_P(callback) == IS_STRING && Z_STRLEN_P(callback) == 0) ||
    2158                 :             (Z_TYPE_P(callback) == IS_UNICODE && Z_USTRLEN_P(callback) == 0)) {
    2159                 :                 /* unregister rebind procedure */
    2160               1 :                 if (ld->rebindproc != NULL) {
    2161               1 :                         zval_dtor(ld->rebindproc);
    2162               1 :                         ld->rebindproc = NULL;
    2163               1 :                         ldap_set_rebind_proc(ld->link, NULL, NULL);
    2164                 :                 }
    2165               1 :                 RETURN_TRUE;
    2166                 :         }
    2167                 : 
    2168                 :         /* callable? */
    2169               3 :         if (!zend_is_callable(callback, 0, &callback_name TSRMLS_CC)) {
    2170               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Two arguments expected for '%R' to be a valid callback", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
    2171               1 :                 zval_dtor(&callback_name);
    2172               1 :                 RETURN_FALSE;
    2173                 :         }
    2174               2 :         zval_dtor(&callback_name);
    2175                 : 
    2176                 :         /* register rebind procedure */
    2177               2 :         if (ld->rebindproc == NULL) {
    2178               2 :                 ldap_set_rebind_proc(ld->link, _ldap_rebind_proc, (void *) link);
    2179                 :         } else {
    2180               0 :                 zval_dtor(ld->rebindproc);
    2181                 :         }
    2182                 : 
    2183               2 :         ALLOC_ZVAL(ld->rebindproc);
    2184               2 :         *ld->rebindproc = *callback;
    2185               2 :         zval_copy_ctor(ld->rebindproc);
    2186               2 :         RETURN_TRUE;
    2187                 : }
    2188                 : /* }}} */
    2189                 : #endif
    2190                 : 
    2191                 : #ifdef STR_TRANSLATION
    2192                 : /* {{{ php_ldap_do_translate
    2193                 :  */
    2194                 : static void php_ldap_do_translate(INTERNAL_FUNCTION_PARAMETERS, int way) 
    2195                 : {
    2196                 :         char *value;
    2197                 :         int result, ldap_len;
    2198                 :                 
    2199                 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &value, &value_len, UG(utf8_conv)) != SUCCESS) {
    2200                 :                 return;
    2201                 :         }
    2202                 : 
    2203                 :         if (value_len == 0) {
    2204                 :                 RETURN_FALSE;
    2205                 :         }
    2206                 : 
    2207                 :         if (way == 1) {
    2208                 :                 result = ldap_8859_to_t61(&value, &value_len, 0);
    2209                 :         } else {
    2210                 :                 result = ldap_t61_to_8859(&value, &value_len, 0);
    2211                 :         }
    2212                 : 
    2213                 :         if (result == LDAP_SUCCESS) {
    2214                 :                 RETVAL_STRINGL(value, value_len, 1);
    2215                 :                 free(value);
    2216                 :         } else {
    2217                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Conversion from iso-8859-1 to t61 failed: %s", ldap_err2string(result));
    2218                 :                 RETVAL_FALSE;
    2219                 :         }
    2220                 : }
    2221                 : /* }}} */
    2222                 : 
    2223                 : /* {{{ proto string ldap_t61_to_8859(string value) U
    2224                 :    Translate t61 characters to 8859 characters */
    2225                 : PHP_FUNCTION(ldap_t61_to_8859)
    2226                 : {
    2227                 :         php_ldap_do_translate(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    2228                 : }
    2229                 : /* }}} */
    2230                 : 
    2231                 : /* {{{ proto string ldap_8859_to_t61(string value) U
    2232                 :    Translate 8859 characters to t61 characters */
    2233                 : PHP_FUNCTION(ldap_8859_to_t61)
    2234                 : {
    2235                 :         php_ldap_do_translate(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    2236                 : }
    2237                 : /* }}} */
    2238                 : #endif
    2239                 : 
    2240                 : /* {{{ arginfo */
    2241                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
    2242                 :         ZEND_ARG_INFO(0, hostname)
    2243                 :         ZEND_ARG_INFO(0, port)
    2244                 : #ifdef HAVE_ORALDAP
    2245                 :         ZEND_ARG_INFO(0, wallet)
    2246                 :         ZEND_ARG_INFO(0, wallet_passwd)
    2247                 :         ZEND_ARG_INFO(0, authmode)
    2248                 : #endif
    2249                 : ZEND_END_ARG_INFO()
    2250                 : 
    2251                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
    2252                 :         ZEND_ARG_INFO(0, link_identifier)
    2253                 : ZEND_END_ARG_INFO()
    2254                 : 
    2255                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
    2256                 :         ZEND_ARG_INFO(0, link_identifier)
    2257                 :         ZEND_ARG_INFO(0, bind_rdn)
    2258                 :         ZEND_ARG_INFO(0, bind_password)
    2259                 : ZEND_END_ARG_INFO()
    2260                 : 
    2261                 : #ifdef HAVE_LDAP_SASL
    2262                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
    2263                 :         ZEND_ARG_INFO(0, link)
    2264                 :         ZEND_ARG_INFO(0, binddn)
    2265                 :         ZEND_ARG_INFO(0, password)
    2266                 :         ZEND_ARG_INFO(0, sasl_mech)
    2267                 :         ZEND_ARG_INFO(0, sasl_realm)
    2268                 :         ZEND_ARG_INFO(0, sasl_authz_id)
    2269                 :         ZEND_ARG_INFO(0, props)
    2270                 : ZEND_END_ARG_INFO()
    2271                 : #endif
    2272                 : 
    2273                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
    2274                 :         ZEND_ARG_INFO(0, link_identifier)
    2275                 :         ZEND_ARG_INFO(0, base_dn)
    2276                 :         ZEND_ARG_INFO(0, filter)
    2277                 :         ZEND_ARG_INFO(0, attributes)
    2278                 :         ZEND_ARG_INFO(0, attrsonly)
    2279                 :         ZEND_ARG_INFO(0, sizelimit)
    2280                 :         ZEND_ARG_INFO(0, timelimit)
    2281                 :         ZEND_ARG_INFO(0, deref)
    2282                 : ZEND_END_ARG_INFO()
    2283                 : 
    2284                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
    2285                 :         ZEND_ARG_INFO(0, link_identifier)
    2286                 :         ZEND_ARG_INFO(0, base_dn)
    2287                 :         ZEND_ARG_INFO(0, filter)
    2288                 :         ZEND_ARG_INFO(0, attributes)
    2289                 :         ZEND_ARG_INFO(0, attrsonly)
    2290                 :         ZEND_ARG_INFO(0, sizelimit)
    2291                 :         ZEND_ARG_INFO(0, timelimit)
    2292                 :         ZEND_ARG_INFO(0, deref)
    2293                 : ZEND_END_ARG_INFO()
    2294                 : 
    2295                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_search, 0, 0, 3)
    2296                 :         ZEND_ARG_INFO(0, link_identifier)
    2297                 :         ZEND_ARG_INFO(0, base_dn)
    2298                 :         ZEND_ARG_INFO(0, filter)
    2299                 :         ZEND_ARG_INFO(0, attributes)
    2300                 :         ZEND_ARG_INFO(0, attrsonly)
    2301                 :         ZEND_ARG_INFO(0, sizelimit)
    2302                 :         ZEND_ARG_INFO(0, timelimit)
    2303                 :         ZEND_ARG_INFO(0, deref)
    2304                 : ZEND_END_ARG_INFO()
    2305                 : 
    2306                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_count_entries, 0, 0, 2)
    2307                 :         ZEND_ARG_INFO(0, link_identifier)
    2308                 :         ZEND_ARG_INFO(0, result_identifier)
    2309                 : ZEND_END_ARG_INFO()
    2310                 : 
    2311                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_entry, 0, 0, 2)
    2312                 :         ZEND_ARG_INFO(0, link_identifier)
    2313                 :         ZEND_ARG_INFO(0, result_identifier)
    2314                 : ZEND_END_ARG_INFO()
    2315                 : 
    2316                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_entry, 0, 0, 2)
    2317                 :         ZEND_ARG_INFO(0, link_identifier)
    2318                 :         ZEND_ARG_INFO(0, result_identifier)
    2319                 : ZEND_END_ARG_INFO()
    2320                 : 
    2321                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_entries, 0, 0, 2)
    2322                 :         ZEND_ARG_INFO(0, link_identifier)
    2323                 :         ZEND_ARG_INFO(0, result_identifier)
    2324                 : ZEND_END_ARG_INFO()
    2325                 : 
    2326                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_attribute, 0, 0, 2)
    2327                 :         ZEND_ARG_INFO(0, link_identifier)
    2328                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2329                 : ZEND_END_ARG_INFO()
    2330                 : 
    2331                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_attribute, 0, 0, 2)
    2332                 :         ZEND_ARG_INFO(0, link_identifier)
    2333                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2334                 : ZEND_END_ARG_INFO()
    2335                 : 
    2336                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_attributes, 0, 0, 2)
    2337                 :         ZEND_ARG_INFO(0, link_identifier)
    2338                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2339                 : ZEND_END_ARG_INFO()
    2340                 : 
    2341                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_values, 0, 0, 3)
    2342                 :         ZEND_ARG_INFO(0, link_identifier)
    2343                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2344                 :         ZEND_ARG_INFO(0, attribute)
    2345                 : ZEND_END_ARG_INFO()
    2346                 : 
    2347                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_values_len, 0, 0, 3)
    2348                 :         ZEND_ARG_INFO(0, link_identifier)
    2349                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2350                 :         ZEND_ARG_INFO(0, attribute)
    2351                 : ZEND_END_ARG_INFO()
    2352                 : 
    2353                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_dn, 0, 0, 2)
    2354                 :         ZEND_ARG_INFO(0, link_identifier)
    2355                 :         ZEND_ARG_INFO(0, result_entry_identifier)
    2356                 : ZEND_END_ARG_INFO()
    2357                 : 
    2358                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_explode_dn, 0, 0, 2)
    2359                 :         ZEND_ARG_INFO(0, dn)
    2360                 :         ZEND_ARG_INFO(0, with_attrib)
    2361                 : ZEND_END_ARG_INFO()
    2362                 : 
    2363                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_dn2ufn, 0, 0, 1)
    2364                 :         ZEND_ARG_INFO(0, dn)
    2365                 : ZEND_END_ARG_INFO()
    2366                 : 
    2367                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add, 0, 0, 3)
    2368                 :         ZEND_ARG_INFO(0, link_identifier)
    2369                 :         ZEND_ARG_INFO(0, dn)
    2370                 :         ZEND_ARG_INFO(0, entry)
    2371                 : ZEND_END_ARG_INFO()
    2372                 : 
    2373                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_delete, 0, 0, 2)
    2374                 :         ZEND_ARG_INFO(0, link_identifier)
    2375                 :         ZEND_ARG_INFO(0, dn)
    2376                 : ZEND_END_ARG_INFO()
    2377                 : 
    2378                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify, 0, 0, 3)
    2379                 :         ZEND_ARG_INFO(0, link_identifier)
    2380                 :         ZEND_ARG_INFO(0, dn)
    2381                 :         ZEND_ARG_INFO(0, entry)
    2382                 : ZEND_END_ARG_INFO()
    2383                 : 
    2384                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_add, 0, 0, 3)
    2385                 :         ZEND_ARG_INFO(0, link_identifier)
    2386                 :         ZEND_ARG_INFO(0, dn)
    2387                 :         ZEND_ARG_INFO(0, entry)
    2388                 : ZEND_END_ARG_INFO()
    2389                 : 
    2390                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_replace, 0, 0, 3)
    2391                 :         ZEND_ARG_INFO(0, link_identifier)
    2392                 :         ZEND_ARG_INFO(0, dn)
    2393                 :         ZEND_ARG_INFO(0, entry)
    2394                 : ZEND_END_ARG_INFO()
    2395                 : 
    2396                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_del, 0, 0, 3)
    2397                 :         ZEND_ARG_INFO(0, link_identifier)
    2398                 :         ZEND_ARG_INFO(0, dn)
    2399                 :         ZEND_ARG_INFO(0, entry)
    2400                 : ZEND_END_ARG_INFO()
    2401                 : 
    2402                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_err2str, 0, 0, 1)
    2403                 :         ZEND_ARG_INFO(0, errno)
    2404                 : ZEND_END_ARG_INFO()
    2405                 : 
    2406                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_compare, 0, 0, 4)
    2407                 :         ZEND_ARG_INFO(0, link_identifier)
    2408                 :         ZEND_ARG_INFO(0, dn)
    2409                 :         ZEND_ARG_INFO(0, attribute)
    2410                 :         ZEND_ARG_INFO(0, value)
    2411                 : ZEND_END_ARG_INFO()
    2412                 : 
    2413                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sort, 0, 0, 3)
    2414                 :         ZEND_ARG_INFO(0, link)
    2415                 :         ZEND_ARG_INFO(0, result)
    2416                 :         ZEND_ARG_INFO(0, sortfilter)
    2417                 : ZEND_END_ARG_INFO()
    2418                 : 
    2419                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
    2420                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5)
    2421                 :         ZEND_ARG_INFO(0, link_identifier)
    2422                 :         ZEND_ARG_INFO(0, dn)
    2423                 :         ZEND_ARG_INFO(0, newrdn)
    2424                 :         ZEND_ARG_INFO(0, newparent)
    2425                 :         ZEND_ARG_INFO(0, deleteoldrdn)
    2426                 : ZEND_END_ARG_INFO()
    2427                 : 
    2428                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_option, 0, 0, 3)
    2429                 :         ZEND_ARG_INFO(0, link_identifier)
    2430                 :         ZEND_ARG_INFO(0, option)
    2431                 :         ZEND_ARG_INFO(1, retval)
    2432                 : ZEND_END_ARG_INFO()
    2433                 : 
    2434                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_option, 0, 0, 3)
    2435                 :         ZEND_ARG_INFO(0, link_identifier)
    2436                 :         ZEND_ARG_INFO(0, option)
    2437                 :         ZEND_ARG_INFO(0, newval)
    2438                 : ZEND_END_ARG_INFO()
    2439                 : 
    2440                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_reference, 0, 0, 2)
    2441                 :         ZEND_ARG_INFO(0, link)
    2442                 :         ZEND_ARG_INFO(0, result)
    2443                 : ZEND_END_ARG_INFO()
    2444                 : 
    2445                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_reference, 0, 0, 2)
    2446                 :         ZEND_ARG_INFO(0, link)
    2447                 :         ZEND_ARG_INFO(0, entry)
    2448                 : ZEND_END_ARG_INFO()
    2449                 : 
    2450                 : #ifdef HAVE_LDAP_PARSE_REFERENCE
    2451                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_reference, 0, 0, 3)
    2452                 :         ZEND_ARG_INFO(0, link)
    2453                 :         ZEND_ARG_INFO(0, entry)
    2454                 :         ZEND_ARG_INFO(1, referrals)
    2455                 : ZEND_END_ARG_INFO()
    2456                 : #endif
    2457                 : 
    2458                 : 
    2459                 : #ifdef HAVE_LDAP_PARSE_RESULT
    2460                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_result, 0, 0, 3)
    2461                 :         ZEND_ARG_INFO(0, link)
    2462                 :         ZEND_ARG_INFO(0, result)
    2463                 :         ZEND_ARG_INFO(1, errcode)
    2464                 :         ZEND_ARG_INFO(1, matcheddn)
    2465                 :         ZEND_ARG_INFO(1, errmsg)
    2466                 :         ZEND_ARG_INFO(1, referrals)
    2467                 : ZEND_END_ARG_INFO()
    2468                 : #endif
    2469                 : #endif
    2470                 : 
    2471                 : #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
    2472                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2)
    2473                 :         ZEND_ARG_INFO(0, link)
    2474                 :         ZEND_ARG_INFO(0, callback)
    2475                 : ZEND_END_ARG_INFO()
    2476                 : #endif
    2477                 : 
    2478                 : #ifdef STR_TRANSLATION
    2479                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1)
    2480                 :         ZEND_ARG_INFO(0, value)
    2481                 : ZEND_END_ARG_INFO()
    2482                 : 
    2483                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
    2484                 :         ZEND_ARG_INFO(0, value)
    2485                 : ZEND_END_ARG_INFO()
    2486                 : #endif
    2487                 : /* }}} */
    2488                 :         
    2489                 : /*
    2490                 :         This is just a small subset of the functionality provided by the LDAP library. All the 
    2491                 :         operations are synchronous. Referrals are not handled automatically.
    2492                 : */
    2493                 : /* {{{ ldap_functions[]
    2494                 :  */
    2495                 : const zend_function_entry ldap_functions[] = {
    2496                 :         PHP_FE(ldap_connect,                                                            arginfo_ldap_connect)
    2497                 :         PHP_FALIAS(ldap_close,          ldap_unbind,                    arginfo_ldap_resource)
    2498                 :         PHP_FE(ldap_bind,                                                                       arginfo_ldap_bind)
    2499                 : #ifdef HAVE_LDAP_SASL
    2500                 :         PHP_FE(ldap_sasl_bind,                                                          arginfo_ldap_sasl_bind)
    2501                 : #endif
    2502                 :         PHP_FE(ldap_unbind,                                                                     arginfo_ldap_resource)
    2503                 :         PHP_FE(ldap_read,                                                                       arginfo_ldap_read)
    2504                 :         PHP_FE(ldap_list,                                                                       arginfo_ldap_list)
    2505                 :         PHP_FE(ldap_search,                                                                     arginfo_ldap_search)
    2506                 :         PHP_FE(ldap_free_result,                                                        arginfo_ldap_resource)
    2507                 :         PHP_FE(ldap_count_entries,                                                      arginfo_ldap_count_entries)
    2508                 :         PHP_FE(ldap_first_entry,                                                        arginfo_ldap_first_entry)
    2509                 :         PHP_FE(ldap_next_entry,                                                         arginfo_ldap_next_entry)
    2510                 :         PHP_FE(ldap_get_entries,                                                        arginfo_ldap_get_entries)
    2511                 :         PHP_FE(ldap_first_attribute,                                            arginfo_ldap_first_attribute)
    2512                 :         PHP_FE(ldap_next_attribute,                                                     arginfo_ldap_next_attribute)
    2513                 :         PHP_FE(ldap_get_attributes,                                                     arginfo_ldap_get_attributes)
    2514                 :         PHP_FALIAS(ldap_get_values,     ldap_get_values_len,    arginfo_ldap_get_values)
    2515                 :         PHP_FE(ldap_get_values_len,                                                     arginfo_ldap_get_values_len)
    2516                 :         PHP_FE(ldap_get_dn,                                                                     arginfo_ldap_get_dn)
    2517                 :         PHP_FE(ldap_explode_dn,                                                         arginfo_ldap_explode_dn)
    2518                 :         PHP_FE(ldap_dn2ufn,                                                                     arginfo_ldap_dn2ufn)
    2519                 :         PHP_FE(ldap_add,                                                                        arginfo_ldap_add)
    2520                 :         PHP_FE(ldap_delete,                                                                     arginfo_ldap_delete)
    2521                 :         PHP_FALIAS(ldap_modify,         ldap_mod_replace,               arginfo_ldap_modify)
    2522                 : 
    2523                 : /* additional functions for attribute based modifications, Gerrit Thomson */
    2524                 :         PHP_FE(ldap_mod_add,                                                            arginfo_ldap_mod_add)
    2525                 :         PHP_FE(ldap_mod_replace,                                                        arginfo_ldap_mod_replace)
    2526                 :         PHP_FE(ldap_mod_del,                                                            arginfo_ldap_mod_del)
    2527                 : /* end gjt mod */
    2528                 : 
    2529                 :         PHP_FE(ldap_errno,                                                                      arginfo_ldap_resource)
    2530                 :         PHP_FE(ldap_err2str,                                                            arginfo_ldap_err2str)
    2531                 :         PHP_FE(ldap_error,                                                                      arginfo_ldap_resource)
    2532                 :         PHP_FE(ldap_compare,                                                            arginfo_ldap_compare)
    2533                 :         PHP_FE(ldap_sort,                                                                       arginfo_ldap_sort)
    2534                 : 
    2535                 : #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
    2536                 :         PHP_FE(ldap_rename,                                                                     arginfo_ldap_rename)
    2537                 :         PHP_FE(ldap_get_option,                                                         arginfo_ldap_get_option)
    2538                 :         PHP_FE(ldap_set_option,                                                         arginfo_ldap_set_option)
    2539                 :         PHP_FE(ldap_first_reference,                                            arginfo_ldap_first_reference)
    2540                 :         PHP_FE(ldap_next_reference,                                                     arginfo_ldap_next_reference)
    2541                 : #ifdef HAVE_LDAP_PARSE_REFERENCE
    2542                 :         PHP_FE(ldap_parse_reference,                                            arginfo_ldap_parse_reference)
    2543                 : #endif
    2544                 : #ifdef HAVE_LDAP_PARSE_RESULT
    2545                 :         PHP_FE(ldap_parse_result,                                                       arginfo_ldap_parse_result)
    2546                 : #endif
    2547                 : #ifdef HAVE_LDAP_START_TLS_S
    2548                 :         PHP_FE(ldap_start_tls,                                                          arginfo_ldap_resource)
    2549                 : #endif
    2550                 : #endif
    2551                 : 
    2552                 : #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
    2553                 :         PHP_FE(ldap_set_rebind_proc,                                            arginfo_ldap_set_rebind_proc)
    2554                 : #endif
    2555                 : 
    2556                 : #ifdef STR_TRANSLATION
    2557                 :         PHP_FE(ldap_t61_to_8859,                                                        arginfo_ldap_t61_to_8859)
    2558                 :         PHP_FE(ldap_8859_to_t61,                                                        arginfo_ldap_8859_to_t61)
    2559                 : #endif
    2560                 : 
    2561                 :         {NULL, NULL, NULL}
    2562                 : };
    2563                 : /* }}} */
    2564                 : 
    2565                 : zend_module_entry ldap_module_entry = { /* {{{ */
    2566                 :         STANDARD_MODULE_HEADER,
    2567                 :         "ldap", 
    2568                 :         ldap_functions, 
    2569                 :         PHP_MINIT(ldap), 
    2570                 :         PHP_MSHUTDOWN(ldap), 
    2571                 :         NULL, 
    2572                 :         NULL,
    2573                 :         PHP_MINFO(ldap), 
    2574                 :         NO_VERSION_YET,
    2575                 :         PHP_MODULE_GLOBALS(ldap),
    2576                 :         PHP_GINIT(ldap),
    2577                 :         NULL,
    2578                 :         NULL,
    2579                 :         STANDARD_MODULE_PROPERTIES_EX
    2580                 : };
    2581                 : /* }}} */
    2582                 : 
    2583                 : /*
    2584                 :  * Local variables:
    2585                 :  * tab-width: 4
    2586                 :  * c-basic-offset: 4
    2587                 :  * End:
    2588                 :  * vim600: sw=4 ts=4 fdm=marker
    2589                 :  * vim<600: sw=4 ts=4
    2590                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:31 +0000 (35 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.