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