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