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