This source file includes following definitions.
- ldap_control_find
- ldap_memvfree
- ZEND_DECLARE_MODULE_GLOBALS
- _free_ldap_result
- _free_ldap_result_entry
- PHP_INI_BEGIN
- PHP_MINIT_FUNCTION
- PHP_MSHUTDOWN_FUNCTION
- PHP_MINFO_FUNCTION
- PHP_FUNCTION
- _get_lderrno
- _set_lderrno
- PHP_FUNCTION
- _php_sasl_setdefs
- _php_sasl_freedefs
- _php_sasl_interact
- PHP_FUNCTION
- PHP_FUNCTION
- php_set_opts
- php_ldap_do_search
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- php_ldap_do_modify
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- _ldap_str_equal_to_const
- _ldap_strlen_max
- _ldap_hash_fetch
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- _ldap_rebind_proc
- PHP_FUNCTION
- php_ldap_do_escape
- php_ldap_escape_map_set_chars
- PHP_FUNCTION
- php_ldap_do_translate
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #define IS_EXT_MODULE
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33
34 #if defined(NETWARE) && (NEW_LIBC)
35 #include <sys/select.h>
36 #include <sys/timeval.h>
37 #endif
38
39 #include "php.h"
40 #include "php_ini.h"
41
42 #include <stddef.h>
43
44 #include "ext/standard/dl.h"
45 #include "php_ldap.h"
46
47 #ifdef PHP_WIN32
48 #include <string.h>
49 #include "config.w32.h"
50 #if HAVE_NSLDAP
51 #include <winsock2.h>
52 #endif
53 #define strdup _strdup
54 #undef WINDOWS
55 #undef strcasecmp
56 #undef strncasecmp
57 #define WINSOCK 1
58 #define __STDC__ 1
59 #endif
60
61 #include "ext/standard/php_string.h"
62 #include "ext/standard/info.h"
63
64 #ifdef HAVE_LDAP_SASL_H
65 #include <sasl.h>
66 #elif defined(HAVE_LDAP_SASL_SASL_H)
67 #include <sasl/sasl.h>
68 #endif
69
70 #define PHP_LDAP_ESCAPE_FILTER 0x01
71 #define PHP_LDAP_ESCAPE_DN 0x02
72
73 #if defined(LDAP_CONTROL_PAGEDRESULTS) && !defined(HAVE_LDAP_CONTROL_FIND)
74 LDAPControl *ldap_control_find( const char *oid, LDAPControl **ctrls, LDAPControl ***nextctrlp)
75 {
76 assert(nextctrlp == NULL);
77 return ldap_find_control(oid, ctrls);
78 }
79 #endif
80
81 #if !defined(LDAP_API_FEATURE_X_OPENLDAP)
82 void ldap_memvfree(void **v)
83 {
84 ldap_value_free((char **)v);
85 }
86 #endif
87
88 typedef struct {
89 LDAP *link;
90 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
91 zval rebindproc;
92 #endif
93 } ldap_linkdata;
94
95 typedef struct {
96 LDAPMessage *data;
97 BerElement *ber;
98 zval res;
99 } ldap_resultentry;
100
101 ZEND_DECLARE_MODULE_GLOBALS(ldap)
102 static PHP_GINIT_FUNCTION(ldap);
103
104 static int le_link, le_result, le_result_entry;
105
106 #ifdef COMPILE_DL_LDAP
107 ZEND_GET_MODULE(ldap)
108 #endif
109
110 static void _close_ldap_link(zend_resource *rsrc)
111 {
112 ldap_linkdata *ld = (ldap_linkdata *)rsrc->ptr;
113
114 ldap_unbind_ext(ld->link, NULL, NULL);
115 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
116 zval_ptr_dtor(&ld->rebindproc);
117 #endif
118
119 efree(ld);
120 LDAPG(num_links)--;
121 }
122
123
124 static void _free_ldap_result(zend_resource *rsrc)
125 {
126 LDAPMessage *result = (LDAPMessage *)rsrc->ptr;
127 ldap_msgfree(result);
128 }
129
130
131 static void _free_ldap_result_entry(zend_resource *rsrc)
132 {
133 ldap_resultentry *entry = (ldap_resultentry *)rsrc->ptr;
134
135 if (entry->ber != NULL) {
136 ber_free(entry->ber, 0);
137 entry->ber = NULL;
138 }
139 zval_ptr_dtor(&entry->res);
140 efree(entry);
141 }
142
143
144
145
146 PHP_INI_BEGIN()
147 STD_PHP_INI_ENTRY_EX("ldap.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_ldap_globals, ldap_globals, display_link_numbers)
148 PHP_INI_END()
149
150
151
152
153 static PHP_GINIT_FUNCTION(ldap)
154 {
155 ldap_globals->num_links = 0;
156 }
157
158
159
160
161 PHP_MINIT_FUNCTION(ldap)
162 {
163 REGISTER_INI_ENTRIES();
164
165
166 REGISTER_LONG_CONSTANT("LDAP_DEREF_NEVER", LDAP_DEREF_NEVER, CONST_PERSISTENT | CONST_CS);
167 REGISTER_LONG_CONSTANT("LDAP_DEREF_SEARCHING", LDAP_DEREF_SEARCHING, CONST_PERSISTENT | CONST_CS);
168 REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS);
169 REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS);
170
171
172 REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_ADD", LDAP_MODIFY_BATCH_ADD, CONST_PERSISTENT | CONST_CS);
173 REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REMOVE", LDAP_MODIFY_BATCH_REMOVE, CONST_PERSISTENT | CONST_CS);
174 REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REMOVE_ALL", LDAP_MODIFY_BATCH_REMOVE_ALL, CONST_PERSISTENT | CONST_CS);
175 REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REPLACE", LDAP_MODIFY_BATCH_REPLACE, CONST_PERSISTENT | CONST_CS);
176 REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_ATTRIB", LDAP_MODIFY_BATCH_ATTRIB, CONST_PERSISTENT | CONST_CS);
177 REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_MODTYPE", LDAP_MODIFY_BATCH_MODTYPE, CONST_PERSISTENT | CONST_CS);
178 REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_VALUES", LDAP_MODIFY_BATCH_VALUES, CONST_PERSISTENT | CONST_CS);
179
180 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
181
182 REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS);
183 REGISTER_LONG_CONSTANT("LDAP_OPT_SIZELIMIT", LDAP_OPT_SIZELIMIT, CONST_PERSISTENT | CONST_CS);
184 REGISTER_LONG_CONSTANT("LDAP_OPT_TIMELIMIT", LDAP_OPT_TIMELIMIT, CONST_PERSISTENT | CONST_CS);
185 #ifdef LDAP_OPT_NETWORK_TIMEOUT
186 REGISTER_LONG_CONSTANT("LDAP_OPT_NETWORK_TIMEOUT", LDAP_OPT_NETWORK_TIMEOUT, CONST_PERSISTENT | CONST_CS);
187 #elif defined (LDAP_X_OPT_CONNECT_TIMEOUT)
188 REGISTER_LONG_CONSTANT("LDAP_OPT_NETWORK_TIMEOUT", LDAP_X_OPT_CONNECT_TIMEOUT, CONST_PERSISTENT | CONST_CS);
189 #endif
190 #ifdef LDAP_OPT_TIMEOUT
191 REGISTER_LONG_CONSTANT("LDAP_OPT_TIMEOUT", LDAP_OPT_TIMEOUT, CONST_PERSISTENT | CONST_CS);
192 #endif
193 REGISTER_LONG_CONSTANT("LDAP_OPT_PROTOCOL_VERSION", LDAP_OPT_PROTOCOL_VERSION, CONST_PERSISTENT | CONST_CS);
194 REGISTER_LONG_CONSTANT("LDAP_OPT_ERROR_NUMBER", LDAP_OPT_ERROR_NUMBER, CONST_PERSISTENT | CONST_CS);
195 REGISTER_LONG_CONSTANT("LDAP_OPT_REFERRALS", LDAP_OPT_REFERRALS, CONST_PERSISTENT | CONST_CS);
196 #ifdef LDAP_OPT_RESTART
197 REGISTER_LONG_CONSTANT("LDAP_OPT_RESTART", LDAP_OPT_RESTART, CONST_PERSISTENT | CONST_CS);
198 #endif
199 #ifdef LDAP_OPT_HOST_NAME
200 REGISTER_LONG_CONSTANT("LDAP_OPT_HOST_NAME", LDAP_OPT_HOST_NAME, CONST_PERSISTENT | CONST_CS);
201 #endif
202 REGISTER_LONG_CONSTANT("LDAP_OPT_ERROR_STRING", LDAP_OPT_ERROR_STRING, CONST_PERSISTENT | CONST_CS);
203 #ifdef LDAP_OPT_MATCHED_DN
204 REGISTER_LONG_CONSTANT("LDAP_OPT_MATCHED_DN", LDAP_OPT_MATCHED_DN, CONST_PERSISTENT | CONST_CS);
205 #endif
206 REGISTER_LONG_CONSTANT("LDAP_OPT_SERVER_CONTROLS", LDAP_OPT_SERVER_CONTROLS, CONST_PERSISTENT | CONST_CS);
207 REGISTER_LONG_CONSTANT("LDAP_OPT_CLIENT_CONTROLS", LDAP_OPT_CLIENT_CONTROLS, CONST_PERSISTENT | CONST_CS);
208 #endif
209 #ifdef LDAP_OPT_DEBUG_LEVEL
210 REGISTER_LONG_CONSTANT("LDAP_OPT_DEBUG_LEVEL", LDAP_OPT_DEBUG_LEVEL, CONST_PERSISTENT | CONST_CS);
211 #endif
212
213 #ifdef LDAP_OPT_DIAGNOSTIC_MESSAGE
214 REGISTER_LONG_CONSTANT("LDAP_OPT_DIAGNOSTIC_MESSAGE", LDAP_OPT_DIAGNOSTIC_MESSAGE, CONST_PERSISTENT | CONST_CS);
215 #endif
216
217 #ifdef HAVE_LDAP_SASL
218 REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_MECH", LDAP_OPT_X_SASL_MECH, CONST_PERSISTENT | CONST_CS);
219 REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_REALM", LDAP_OPT_X_SASL_REALM, CONST_PERSISTENT | CONST_CS);
220 REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHCID", LDAP_OPT_X_SASL_AUTHCID, CONST_PERSISTENT | CONST_CS);
221 REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_AUTHZID", LDAP_OPT_X_SASL_AUTHZID, CONST_PERSISTENT | CONST_CS);
222 #endif
223
224 #ifdef ORALDAP
225 REGISTER_LONG_CONSTANT("GSLC_SSL_NO_AUTH", GSLC_SSL_NO_AUTH, CONST_PERSISTENT | CONST_CS);
226 REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_CS);
227 REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
228 #endif
229
230 #if (LDAP_API_VERSION > 2000)
231 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_REQUIRE_CERT", LDAP_OPT_X_TLS_REQUIRE_CERT, CONST_PERSISTENT | CONST_CS);
232
233 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_NEVER", LDAP_OPT_X_TLS_NEVER, CONST_PERSISTENT | CONST_CS);
234 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_HARD", LDAP_OPT_X_TLS_HARD, CONST_PERSISTENT | CONST_CS);
235 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_DEMAND", LDAP_OPT_X_TLS_DEMAND, CONST_PERSISTENT | CONST_CS);
236 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_ALLOW", LDAP_OPT_X_TLS_ALLOW, CONST_PERSISTENT | CONST_CS);
237 REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_TRY", LDAP_OPT_X_TLS_TRY, CONST_PERSISTENT | CONST_CS);
238 #endif
239
240 REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS);
241 REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS);
242
243 le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
244 le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
245 le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
246
247 ldap_module_entry.type = type;
248
249 return SUCCESS;
250 }
251
252
253
254
255 PHP_MSHUTDOWN_FUNCTION(ldap)
256 {
257 UNREGISTER_INI_ENTRIES();
258 return SUCCESS;
259 }
260
261
262
263
264 PHP_MINFO_FUNCTION(ldap)
265 {
266 char tmp[32];
267 #if HAVE_NSLDAP
268 LDAPVersion ver;
269 double SDKVersion;
270 #endif
271
272 php_info_print_table_start();
273 php_info_print_table_row(2, "LDAP Support", "enabled");
274 php_info_print_table_row(2, "RCS Version", "$Id: c439c7358da4f516666244bec94da72b8aa630c4 $");
275
276 if (LDAPG(max_links) == -1) {
277 snprintf(tmp, 31, ZEND_LONG_FMT "/unlimited", LDAPG(num_links));
278 } else {
279 snprintf(tmp, 31, ZEND_LONG_FMT "/" ZEND_LONG_FMT, LDAPG(num_links), LDAPG(max_links));
280 }
281 php_info_print_table_row(2, "Total Links", tmp);
282
283 #ifdef LDAP_API_VERSION
284 snprintf(tmp, 31, "%d", LDAP_API_VERSION);
285 php_info_print_table_row(2, "API Version", tmp);
286 #endif
287
288 #ifdef LDAP_VENDOR_NAME
289 php_info_print_table_row(2, "Vendor Name", LDAP_VENDOR_NAME);
290 #endif
291
292 #ifdef LDAP_VENDOR_VERSION
293 snprintf(tmp, 31, "%d", LDAP_VENDOR_VERSION);
294 php_info_print_table_row(2, "Vendor Version", tmp);
295 #endif
296
297 #if HAVE_NSLDAP
298 SDKVersion = ldap_version(&ver);
299 snprintf(tmp, 31, "%F", SDKVersion/100.0);
300 php_info_print_table_row(2, "SDK Version", tmp);
301
302 snprintf(tmp, 31, "%F", ver.protocol_version/100.0);
303 php_info_print_table_row(2, "Highest LDAP Protocol Supported", tmp);
304
305 snprintf(tmp, 31, "%F", ver.SSL_version/100.0);
306 php_info_print_table_row(2, "SSL Level Supported", tmp);
307
308 if (ver.security_level != LDAP_SECURITY_NONE) {
309 snprintf(tmp, 31, "%d", ver.security_level);
310 } else {
311 strcpy(tmp, "SSL not enabled");
312 }
313 php_info_print_table_row(2, "Level of Encryption", tmp);
314 #endif
315
316 #ifdef HAVE_LDAP_SASL
317 php_info_print_table_row(2, "SASL Support", "Enabled");
318 #endif
319
320 php_info_print_table_end();
321 DISPLAY_INI_ENTRIES();
322 }
323
324
325
326
327 PHP_FUNCTION(ldap_connect)
328 {
329 char *host = NULL;
330 size_t hostlen = 0;
331 zend_long port = LDAP_PORT;
332 #ifdef HAVE_ORALDAP
333 char *wallet = NULL, *walletpasswd = NULL;
334 size_t walletlen = 0, walletpasswdlen = 0;
335 zend_long authmode = GSLC_SSL_NO_AUTH;
336 int ssl=0;
337 #endif
338 ldap_linkdata *ld;
339 LDAP *ldap = NULL;
340
341 #ifdef HAVE_ORALDAP
342 if (ZEND_NUM_ARGS() == 3 || ZEND_NUM_ARGS() == 4) {
343 WRONG_PARAM_COUNT;
344 }
345
346 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|slssl", &host, &hostlen, &port, &wallet, &walletlen, &walletpasswd, &walletpasswdlen, &authmode) != SUCCESS) {
347 RETURN_FALSE;
348 }
349
350 if (ZEND_NUM_ARGS() == 5) {
351 ssl = 1;
352 }
353 #else
354 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sl", &host, &hostlen, &port) != SUCCESS) {
355 RETURN_FALSE;
356 }
357 #endif
358
359 if (LDAPG(max_links) != -1 && LDAPG(num_links) >= LDAPG(max_links)) {
360 php_error_docref(NULL, E_WARNING, "Too many open links (%pd)", LDAPG(num_links));
361 RETURN_FALSE;
362 }
363
364 ld = ecalloc(1, sizeof(ldap_linkdata));
365
366 {
367 int rc = LDAP_SUCCESS;
368 char *url = host;
369 if (!ldap_is_ldap_url(url)) {
370 int urllen = hostlen + sizeof( "ldap://:65535" );
371
372 if (port <= 0 || port > 65535) {
373 php_error_docref(NULL, E_WARNING, "invalid port number: %ld", port);
374 RETURN_FALSE;
375 }
376
377 url = emalloc(urllen);
378 snprintf( url, urllen, "ldap://%s:%ld", host ? host : "", port );
379 }
380
381 #ifdef LDAP_API_FEATURE_X_OPENLDAP
382
383
384 rc = ldap_initialize(&ldap, url);
385 #else
386
387
388
389 ldap = ldap_init(host, port);
390 if (ldap == NULL) {
391 efree(ld);
392 php_error_docref(NULL, E_WARNING, "Could not create session handle");
393 RETURN_FALSE;
394 }
395 #endif
396 if (url != host) {
397 efree(url);
398 }
399 if (rc != LDAP_SUCCESS) {
400 efree(ld);
401 php_error_docref(NULL, E_WARNING, "Could not create session handle: %s", ldap_err2string(rc));
402 RETURN_FALSE;
403 }
404 }
405
406 if (ldap == NULL) {
407 efree(ld);
408 RETURN_FALSE;
409 } else {
410 #ifdef HAVE_ORALDAP
411 if (ssl) {
412 if (ldap_init_SSL(&ldap->ld_sb, wallet, walletpasswd, authmode)) {
413 efree(ld);
414 php_error_docref(NULL, E_WARNING, "SSL init failed");
415 RETURN_FALSE;
416 }
417 }
418 #endif
419 LDAPG(num_links)++;
420 ld->link = ldap;
421 RETURN_RES(zend_register_resource(ld, le_link));
422 }
423
424 }
425
426
427
428
429 static int _get_lderrno(LDAP *ldap)
430 {
431 #if !HAVE_NSLDAP
432 #if LDAP_API_VERSION > 2000 || HAVE_ORALDAP
433 int lderr;
434
435
436 ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &lderr);
437 return lderr;
438 #else
439 return ldap->ld_errno;
440 #endif
441 #else
442 return ldap_get_lderrno(ldap, NULL, NULL);
443 #endif
444 }
445
446
447
448
449 static void _set_lderrno(LDAP *ldap, int lderr)
450 {
451 #if !HAVE_NSLDAP
452 #if LDAP_API_VERSION > 2000 || HAVE_ORALDAP
453
454 ldap_set_option(ldap, LDAP_OPT_ERROR_NUMBER, &lderr);
455 #else
456 ldap->ld_errno = lderr;
457 #endif
458 #else
459 ldap_set_lderrno(ldap, lderr, NULL, NULL);
460 #endif
461 }
462
463
464
465
466 PHP_FUNCTION(ldap_bind)
467 {
468 zval *link;
469 char *ldap_bind_dn = NULL, *ldap_bind_pw = NULL;
470 size_t ldap_bind_dnlen, ldap_bind_pwlen;
471 ldap_linkdata *ld;
472 int rc;
473
474 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ss", &link, &ldap_bind_dn, &ldap_bind_dnlen, &ldap_bind_pw, &ldap_bind_pwlen) != SUCCESS) {
475 RETURN_FALSE;
476 }
477
478 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
479 RETURN_FALSE;
480 }
481
482 if (ldap_bind_dn != NULL && memchr(ldap_bind_dn, '\0', ldap_bind_dnlen) != NULL) {
483 _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS);
484 php_error_docref(NULL, E_WARNING, "DN contains a null byte");
485 RETURN_FALSE;
486 }
487
488 if (ldap_bind_pw != NULL && memchr(ldap_bind_pw, '\0', ldap_bind_pwlen) != NULL) {
489 _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS);
490 php_error_docref(NULL, E_WARNING, "Password contains a null byte");
491 RETURN_FALSE;
492 }
493
494 {
495 #ifdef LDAP_API_FEATURE_X_OPENLDAP
496
497
498 struct berval cred;
499
500 cred.bv_val = ldap_bind_pw;
501 cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0;
502 rc = ldap_sasl_bind_s(ld->link, ldap_bind_dn, LDAP_SASL_SIMPLE, &cred,
503 NULL, NULL,
504 NULL);
505 #else
506 rc = ldap_simple_bind_s(ld->link, ldap_bind_dn, ldap_bind_pw);
507 #endif
508 }
509 if ( rc != LDAP_SUCCESS) {
510 php_error_docref(NULL, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
511 RETURN_FALSE;
512 } else {
513 RETURN_TRUE;
514 }
515 }
516
517
518 #ifdef HAVE_LDAP_SASL
519 typedef struct {
520 char *mech;
521 char *realm;
522 char *authcid;
523 char *passwd;
524 char *authzid;
525 } php_ldap_bictx;
526
527
528
529 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)
530 {
531 php_ldap_bictx *ctx;
532
533 ctx = ber_memalloc(sizeof(php_ldap_bictx));
534 ctx->mech = (sasl_mech) ? ber_strdup(sasl_mech) : NULL;
535 ctx->realm = (sasl_realm) ? ber_strdup(sasl_realm) : NULL;
536 ctx->authcid = (sasl_authc_id) ? ber_strdup(sasl_authc_id) : NULL;
537 ctx->passwd = (passwd) ? ber_strdup(passwd) : NULL;
538 ctx->authzid = (sasl_authz_id) ? ber_strdup(sasl_authz_id) : NULL;
539
540 if (ctx->mech == NULL) {
541 ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &ctx->mech);
542 }
543 if (ctx->realm == NULL) {
544 ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &ctx->realm);
545 }
546 if (ctx->authcid == NULL) {
547 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &ctx->authcid);
548 }
549 if (ctx->authzid == NULL) {
550 ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &ctx->authzid);
551 }
552
553 return ctx;
554 }
555
556
557
558
559 static void _php_sasl_freedefs(php_ldap_bictx *ctx)
560 {
561 if (ctx->mech) ber_memfree(ctx->mech);
562 if (ctx->realm) ber_memfree(ctx->realm);
563 if (ctx->authcid) ber_memfree(ctx->authcid);
564 if (ctx->passwd) ber_memfree(ctx->passwd);
565 if (ctx->authzid) ber_memfree(ctx->authzid);
566 ber_memfree(ctx);
567 }
568
569
570
571
572 static int _php_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *in)
573 {
574 sasl_interact_t *interact = in;
575 const char *p;
576 php_ldap_bictx *ctx = defaults;
577
578 for (;interact->id != SASL_CB_LIST_END;interact++) {
579 p = NULL;
580 switch(interact->id) {
581 case SASL_CB_GETREALM:
582 p = ctx->realm;
583 break;
584 case SASL_CB_AUTHNAME:
585 p = ctx->authcid;
586 break;
587 case SASL_CB_USER:
588 p = ctx->authzid;
589 break;
590 case SASL_CB_PASS:
591 p = ctx->passwd;
592 break;
593 }
594 if (p) {
595 interact->result = p;
596 interact->len = strlen(interact->result);
597 }
598 }
599 return LDAP_SUCCESS;
600 }
601
602
603
604
605 PHP_FUNCTION(ldap_sasl_bind)
606 {
607 zval *link;
608 ldap_linkdata *ld;
609 char *binddn = NULL;
610 char *passwd = NULL;
611 char *sasl_mech = NULL;
612 char *sasl_realm = NULL;
613 char *sasl_authz_id = NULL;
614 char *sasl_authc_id = NULL;
615 char *props = NULL;
616 size_t rc, dn_len, passwd_len, mech_len, realm_len, authc_id_len, authz_id_len, props_len;
617 php_ldap_bictx *ctx;
618
619 if (zend_parse_parameters(ZEND_NUM_ARGS(), "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) {
620 RETURN_FALSE;
621 }
622
623 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
624 RETURN_FALSE;
625 }
626
627 ctx = _php_sasl_setdefs(ld->link, sasl_mech, sasl_realm, sasl_authc_id, passwd, sasl_authz_id);
628
629 if (props) {
630 ldap_set_option(ld->link, LDAP_OPT_X_SASL_SECPROPS, props);
631 }
632
633 rc = ldap_sasl_interactive_bind_s(ld->link, binddn, ctx->mech, NULL, NULL, LDAP_SASL_QUIET, _php_sasl_interact, ctx);
634 if (rc != LDAP_SUCCESS) {
635 php_error_docref(NULL, E_WARNING, "Unable to bind to server: %s", ldap_err2string(rc));
636 RETVAL_FALSE;
637 } else {
638 RETVAL_TRUE;
639 }
640 _php_sasl_freedefs(ctx);
641 }
642
643 #endif
644
645
646
647 PHP_FUNCTION(ldap_unbind)
648 {
649 zval *link;
650 ldap_linkdata *ld;
651
652 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
653 RETURN_FALSE;
654 }
655
656 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
657 RETURN_FALSE;
658 }
659
660 zend_list_close(Z_RES_P(link));
661 RETURN_TRUE;
662 }
663
664
665
666
667 static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, int *old_sizelimit, int *old_timelimit, int *old_deref)
668 {
669
670 if (sizelimit > -1) {
671 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
672 ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit);
673 ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
674 #else
675 *old_sizelimit = ldap->ld_sizelimit;
676 ldap->ld_sizelimit = sizelimit;
677 #endif
678 }
679
680
681 if (timelimit > -1) {
682 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
683 ldap_get_option(ldap, LDAP_OPT_TIMELIMIT, old_timelimit);
684 ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
685 #else
686 *old_timelimit = ldap->ld_timelimit;
687 ldap->ld_timelimit = timelimit;
688 #endif
689 }
690
691
692 if (deref > -1) {
693 #if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
694 ldap_get_option(ldap, LDAP_OPT_DEREF, old_deref);
695 ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
696 #else
697 *old_deref = ldap->ld_deref;
698 ldap->ld_deref = deref;
699 #endif
700 }
701 }
702
703
704
705
706 static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
707 {
708 zval *link, *base_dn, *filter, *attrs = NULL, *attr;
709 zend_long attrsonly, sizelimit, timelimit, deref;
710 char *ldap_base_dn = NULL, *ldap_filter = NULL, **ldap_attrs = NULL;
711 ldap_linkdata *ld = NULL;
712 LDAPMessage *ldap_res;
713 int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1;
714 int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1;
715 int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS();
716
717 if (zend_parse_parameters(argcount, "zzz|allll", &link, &base_dn, &filter, &attrs, &attrsonly,
718 &sizelimit, &timelimit, &deref) == FAILURE) {
719 return;
720 }
721
722
723 switch (argcount) {
724 case 8:
725 ldap_deref = deref;
726 case 7:
727 ldap_timelimit = timelimit;
728 case 6:
729 ldap_sizelimit = sizelimit;
730 case 5:
731 ldap_attrsonly = attrsonly;
732 case 4:
733 num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs));
734 ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0);
735
736 for (i = 0; i<num_attribs; i++) {
737 if ((attr = zend_hash_index_find(Z_ARRVAL_P(attrs), i)) == NULL) {
738 php_error_docref(NULL, E_WARNING, "Array initialization wrong");
739 ret = 0;
740 goto cleanup;
741 }
742
743 convert_to_string_ex(attr);
744 ldap_attrs[i] = Z_STRVAL_P(attr);
745 }
746 ldap_attrs[num_attribs] = NULL;
747 default:
748 break;
749 }
750
751
752 if (Z_TYPE_P(link) == IS_ARRAY) {
753 int i, nlinks, nbases, nfilters, *rcs;
754 ldap_linkdata **lds;
755 zval *entry, resource;
756
757 nlinks = zend_hash_num_elements(Z_ARRVAL_P(link));
758 if (nlinks == 0) {
759 php_error_docref(NULL, E_WARNING, "No links in link array");
760 ret = 0;
761 goto cleanup;
762 }
763
764 if (Z_TYPE_P(base_dn) == IS_ARRAY) {
765 nbases = zend_hash_num_elements(Z_ARRVAL_P(base_dn));
766 if (nbases != nlinks) {
767 php_error_docref(NULL, E_WARNING, "Base must either be a string, or an array with the same number of elements as the links array");
768 ret = 0;
769 goto cleanup;
770 }
771 zend_hash_internal_pointer_reset(Z_ARRVAL_P(base_dn));
772 } else {
773 nbases = 0;
774
775 if (Z_TYPE_P(base_dn) == IS_STRING) {
776 ldap_base_dn = Z_STRVAL_P(base_dn);
777 } else {
778 ldap_base_dn = NULL;
779 }
780 }
781
782 if (Z_TYPE_P(filter) == IS_ARRAY) {
783 nfilters = zend_hash_num_elements(Z_ARRVAL_P(filter));
784 if (nfilters != nlinks) {
785 php_error_docref(NULL, E_WARNING, "Filter must either be a string, or an array with the same number of elements as the links array");
786 ret = 0;
787 goto cleanup;
788 }
789 zend_hash_internal_pointer_reset(Z_ARRVAL_P(filter));
790 } else {
791 nfilters = 0;
792 convert_to_string_ex(filter);
793 ldap_filter = Z_STRVAL_P(filter);
794 }
795
796 lds = safe_emalloc(nlinks, sizeof(ldap_linkdata), 0);
797 rcs = safe_emalloc(nlinks, sizeof(*rcs), 0);
798
799 zend_hash_internal_pointer_reset(Z_ARRVAL_P(link));
800 for (i=0; i<nlinks; i++) {
801 entry = zend_hash_get_current_data(Z_ARRVAL_P(link));
802
803 ld = (ldap_linkdata *) zend_fetch_resource_ex(entry, "ldap link", le_link);
804 if (ld == NULL) {
805 ret = 0;
806 goto cleanup_parallel;
807 }
808 if (nbases != 0) {
809 entry = zend_hash_get_current_data(Z_ARRVAL_P(base_dn));
810 zend_hash_move_forward(Z_ARRVAL_P(base_dn));
811
812
813 if (Z_TYPE_P(entry) == IS_STRING) {
814 ldap_base_dn = Z_STRVAL_P(entry);
815 } else {
816 ldap_base_dn = NULL;
817 }
818 }
819 if (nfilters != 0) {
820 entry = zend_hash_get_current_data(Z_ARRVAL_P(filter));
821 zend_hash_move_forward(Z_ARRVAL_P(filter));
822 convert_to_string_ex(entry);
823 ldap_filter = Z_STRVAL_P(entry);
824 }
825
826 php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
827
828
829 ldap_search_ext(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, NULL, NULL, NULL, ldap_sizelimit, &rcs[i]);
830 lds[i] = ld;
831 zend_hash_move_forward(Z_ARRVAL_P(link));
832 }
833
834 array_init(return_value);
835
836
837 for (i=0; i<nlinks; i++) {
838 if (rcs[i] != -1) {
839 rcs[i] = ldap_result(lds[i]->link, LDAP_RES_ANY, 1 , NULL, &ldap_res);
840 }
841 if (rcs[i] != -1) {
842 ZVAL_RES(&resource, zend_register_resource(ldap_res, le_result));
843 add_next_index_zval(return_value, &resource);
844 } else {
845 add_next_index_bool(return_value, 0);
846 }
847 }
848
849 cleanup_parallel:
850 efree(lds);
851 efree(rcs);
852 } else {
853 convert_to_string_ex(filter);
854 ldap_filter = Z_STRVAL_P(filter);
855
856
857 if (Z_TYPE_P(base_dn) == IS_STRING) {
858 ldap_base_dn = Z_STRVAL_P(base_dn);
859 }
860
861 ld = (ldap_linkdata *) zend_fetch_resource_ex(link, "ldap link", le_link);
862 if (ld == NULL) {
863 ret = 0;
864 goto cleanup;
865 }
866
867 php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref);
868
869
870 errno = ldap_search_ext_s(ld->link, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly, NULL, NULL, NULL, ldap_sizelimit, &ldap_res);
871
872 if (errno != LDAP_SUCCESS
873 && errno != LDAP_SIZELIMIT_EXCEEDED
874 #ifdef LDAP_ADMINLIMIT_EXCEEDED
875 && errno != LDAP_ADMINLIMIT_EXCEEDED
876 #endif
877 #ifdef LDAP_REFERRAL
878 && errno != LDAP_REFERRAL
879 #endif
880 ) {
881 php_error_docref(NULL, E_WARNING, "Search: %s", ldap_err2string(errno));
882 ret = 0;
883 } else {
884 if (errno == LDAP_SIZELIMIT_EXCEEDED) {
885 php_error_docref(NULL, E_WARNING, "Partial search results returned: Sizelimit exceeded");
886 }
887 #ifdef LDAP_ADMINLIMIT_EXCEEDED
888 else if (errno == LDAP_ADMINLIMIT_EXCEEDED) {
889 php_error_docref(NULL, E_WARNING, "Partial search results returned: Adminlimit exceeded");
890 }
891 #endif
892
893 RETVAL_RES(zend_register_resource(ldap_res, le_result));
894 }
895 }
896
897 cleanup:
898 if (ld) {
899
900 php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref);
901 }
902 if (ldap_attrs != NULL) {
903 efree(ldap_attrs);
904 }
905 if (!ret) {
906 RETVAL_BOOL(ret);
907 }
908 }
909
910
911
912
913 PHP_FUNCTION(ldap_read)
914 {
915 php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_BASE);
916 }
917
918
919
920
921 PHP_FUNCTION(ldap_list)
922 {
923 php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_ONELEVEL);
924 }
925
926
927
928
929 PHP_FUNCTION(ldap_search)
930 {
931 php_ldap_do_search(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_SCOPE_SUBTREE);
932 }
933
934
935
936
937 PHP_FUNCTION(ldap_free_result)
938 {
939 zval *result;
940 LDAPMessage *ldap_result;
941
942 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) != SUCCESS) {
943 return;
944 }
945
946 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
947 RETURN_FALSE;
948 }
949
950 zend_list_close(Z_RES_P(result));
951 RETVAL_TRUE;
952 }
953
954
955
956
957 PHP_FUNCTION(ldap_count_entries)
958 {
959 zval *link, *result;
960 ldap_linkdata *ld;
961 LDAPMessage *ldap_result;
962
963 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result) != SUCCESS) {
964 return;
965 }
966
967 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
968 RETURN_FALSE;
969 }
970
971 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
972 RETURN_FALSE;
973 }
974
975 RETURN_LONG(ldap_count_entries(ld->link, ldap_result));
976 }
977
978
979
980
981 PHP_FUNCTION(ldap_first_entry)
982 {
983 zval *link, *result;
984 ldap_linkdata *ld;
985 ldap_resultentry *resultentry;
986 LDAPMessage *ldap_result, *entry;
987
988 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result) != SUCCESS) {
989 return;
990 }
991
992 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
993 RETURN_FALSE;
994 }
995
996 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
997 RETURN_FALSE;
998 }
999
1000 if ((entry = ldap_first_entry(ld->link, ldap_result)) == NULL) {
1001 RETVAL_FALSE;
1002 } else {
1003 resultentry = emalloc(sizeof(ldap_resultentry));
1004 RETVAL_RES(zend_register_resource(resultentry, le_result_entry));
1005 ZVAL_COPY(&resultentry->res, result);
1006 resultentry->data = entry;
1007 resultentry->ber = NULL;
1008 }
1009 }
1010
1011
1012
1013
1014 PHP_FUNCTION(ldap_next_entry)
1015 {
1016 zval *link, *result_entry;
1017 ldap_linkdata *ld;
1018 ldap_resultentry *resultentry, *resultentry_next;
1019 LDAPMessage *entry_next;
1020
1021 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result_entry) != SUCCESS) {
1022 return;
1023 }
1024
1025 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1026 RETURN_FALSE;
1027 }
1028 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1029 RETURN_FALSE;
1030 }
1031
1032 if ((entry_next = ldap_next_entry(ld->link, resultentry->data)) == NULL) {
1033 RETVAL_FALSE;
1034 } else {
1035 resultentry_next = emalloc(sizeof(ldap_resultentry));
1036 RETVAL_RES(zend_register_resource(resultentry_next, le_result_entry));
1037 ZVAL_COPY(&resultentry_next->res, &resultentry->res);
1038 resultentry_next->data = entry_next;
1039 resultentry_next->ber = NULL;
1040 }
1041 }
1042
1043
1044
1045
1046 PHP_FUNCTION(ldap_get_entries)
1047 {
1048 zval *link, *result;
1049 LDAPMessage *ldap_result, *ldap_result_entry;
1050 zval tmp1, tmp2;
1051 ldap_linkdata *ld;
1052 LDAP *ldap;
1053 int num_entries, num_attrib, num_values, i;
1054 BerElement *ber;
1055 char *attribute;
1056 size_t attr_len;
1057 struct berval **ldap_value;
1058 char *dn;
1059
1060 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result) != SUCCESS) {
1061 return;
1062 }
1063
1064 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1065 RETURN_FALSE;
1066 }
1067 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
1068 RETURN_FALSE;
1069 }
1070
1071 ldap = ld->link;
1072 num_entries = ldap_count_entries(ldap, ldap_result);
1073
1074 array_init(return_value);
1075 add_assoc_long(return_value, "count", num_entries);
1076
1077 if (num_entries == 0) {
1078 return;
1079 }
1080
1081 ldap_result_entry = ldap_first_entry(ldap, ldap_result);
1082 if (ldap_result_entry == NULL) {
1083 zval_dtor(return_value);
1084 RETURN_FALSE;
1085 }
1086
1087 num_entries = 0;
1088 while (ldap_result_entry != NULL) {
1089 array_init(&tmp1);
1090
1091 num_attrib = 0;
1092 attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber);
1093
1094 while (attribute != NULL) {
1095 ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute);
1096 num_values = ldap_count_values_len(ldap_value);
1097
1098 array_init(&tmp2);
1099 add_assoc_long(&tmp2, "count", num_values);
1100 for (i = 0; i < num_values; i++) {
1101 add_index_stringl(&tmp2, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len);
1102 }
1103 ldap_value_free_len(ldap_value);
1104
1105 attr_len = strlen(attribute);
1106 zend_hash_str_update(Z_ARRVAL(tmp1), php_strtolower(attribute, attr_len), attr_len, &tmp2);
1107 add_index_string(&tmp1, num_attrib, attribute);
1108
1109 num_attrib++;
1110 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1111 ldap_memfree(attribute);
1112 #endif
1113 attribute = ldap_next_attribute(ldap, ldap_result_entry, ber);
1114 }
1115 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1116 if (ber != NULL) {
1117 ber_free(ber, 0);
1118 }
1119 #endif
1120
1121 add_assoc_long(&tmp1, "count", num_attrib);
1122 dn = ldap_get_dn(ldap, ldap_result_entry);
1123 add_assoc_string(&tmp1, "dn", dn);
1124 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1125 ldap_memfree(dn);
1126 #else
1127 free(dn);
1128 #endif
1129
1130 zend_hash_index_update(Z_ARRVAL_P(return_value), num_entries, &tmp1);
1131
1132 num_entries++;
1133 ldap_result_entry = ldap_next_entry(ldap, ldap_result_entry);
1134 }
1135
1136 add_assoc_long(return_value, "count", num_entries);
1137
1138 }
1139
1140
1141
1142
1143 PHP_FUNCTION(ldap_first_attribute)
1144 {
1145 zval *link, *result_entry;
1146 ldap_linkdata *ld;
1147 ldap_resultentry *resultentry;
1148 char *attribute;
1149 zend_long dummy_ber;
1150
1151 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|l", &link, &result_entry, &dummy_ber) != SUCCESS) {
1152 return;
1153 }
1154
1155 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1156 RETURN_FALSE;
1157 }
1158
1159 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1160 RETURN_FALSE;
1161 }
1162
1163 if ((attribute = ldap_first_attribute(ld->link, resultentry->data, &resultentry->ber)) == NULL) {
1164 RETURN_FALSE;
1165 } else {
1166 RETVAL_STRING(attribute);
1167 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1168 ldap_memfree(attribute);
1169 #endif
1170 }
1171 }
1172
1173
1174
1175
1176 PHP_FUNCTION(ldap_next_attribute)
1177 {
1178 zval *link, *result_entry;
1179 ldap_linkdata *ld;
1180 ldap_resultentry *resultentry;
1181 char *attribute;
1182 zend_long dummy_ber;
1183
1184 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|l", &link, &result_entry, &dummy_ber) != SUCCESS) {
1185 return;
1186 }
1187
1188 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1189 RETURN_FALSE;
1190 }
1191
1192 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1193 RETURN_FALSE;
1194 }
1195
1196 if (resultentry->ber == NULL) {
1197 php_error_docref(NULL, E_WARNING, "called before calling ldap_first_attribute() or no attributes found in result entry");
1198 RETURN_FALSE;
1199 }
1200
1201 if ((attribute = ldap_next_attribute(ld->link, resultentry->data, resultentry->ber)) == NULL) {
1202 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1203 if (resultentry->ber != NULL) {
1204 ber_free(resultentry->ber, 0);
1205 resultentry->ber = NULL;
1206 }
1207 #endif
1208 RETURN_FALSE;
1209 } else {
1210 RETVAL_STRING(attribute);
1211 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1212 ldap_memfree(attribute);
1213 #endif
1214 }
1215 }
1216
1217
1218
1219
1220 PHP_FUNCTION(ldap_get_attributes)
1221 {
1222 zval *link, *result_entry;
1223 zval tmp;
1224 ldap_linkdata *ld;
1225 ldap_resultentry *resultentry;
1226 char *attribute;
1227 struct berval **ldap_value;
1228 int i, num_values, num_attrib;
1229 BerElement *ber;
1230
1231 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result_entry) != SUCCESS) {
1232 return;
1233 }
1234
1235 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1236 RETURN_FALSE;
1237 }
1238
1239 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1240 RETURN_FALSE;
1241 }
1242
1243 array_init(return_value);
1244 num_attrib = 0;
1245
1246 attribute = ldap_first_attribute(ld->link, resultentry->data, &ber);
1247 while (attribute != NULL) {
1248 ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute);
1249 num_values = ldap_count_values_len(ldap_value);
1250
1251 array_init(&tmp);
1252 add_assoc_long(&tmp, "count", num_values);
1253 for (i = 0; i < num_values; i++) {
1254 add_index_stringl(&tmp, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len);
1255 }
1256 ldap_value_free_len(ldap_value);
1257
1258 zend_hash_str_update(Z_ARRVAL_P(return_value), attribute, strlen(attribute), &tmp);
1259 add_index_string(return_value, num_attrib, attribute);
1260
1261 num_attrib++;
1262 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1263 ldap_memfree(attribute);
1264 #endif
1265 attribute = ldap_next_attribute(ld->link, resultentry->data, ber);
1266 }
1267 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1268 if (ber != NULL) {
1269 ber_free(ber, 0);
1270 }
1271 #endif
1272
1273 add_assoc_long(return_value, "count", num_attrib);
1274 }
1275
1276
1277
1278
1279 PHP_FUNCTION(ldap_get_values_len)
1280 {
1281 zval *link, *result_entry;
1282 ldap_linkdata *ld;
1283 ldap_resultentry *resultentry;
1284 char *attr;
1285 struct berval **ldap_value_len;
1286 int i, num_values;
1287 size_t attr_len;
1288
1289 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs", &link, &result_entry, &attr, &attr_len) != SUCCESS) {
1290 return;
1291 }
1292
1293 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1294 RETURN_FALSE;
1295 }
1296
1297 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1298 RETURN_FALSE;
1299 }
1300
1301 if ((ldap_value_len = ldap_get_values_len(ld->link, resultentry->data, attr)) == NULL) {
1302 php_error_docref(NULL, E_WARNING, "Cannot get the value(s) of attribute %s", ldap_err2string(_get_lderrno(ld->link)));
1303 RETURN_FALSE;
1304 }
1305
1306 num_values = ldap_count_values_len(ldap_value_len);
1307 array_init(return_value);
1308
1309 for (i=0; i<num_values; i++) {
1310 add_next_index_stringl(return_value, ldap_value_len[i]->bv_val, ldap_value_len[i]->bv_len);
1311 }
1312
1313 add_assoc_long(return_value, "count", num_values);
1314 ldap_value_free_len(ldap_value_len);
1315
1316 }
1317
1318
1319
1320
1321 PHP_FUNCTION(ldap_get_dn)
1322 {
1323 zval *link, *result_entry;
1324 ldap_linkdata *ld;
1325 ldap_resultentry *resultentry;
1326 char *text;
1327
1328 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result_entry) != SUCCESS) {
1329 return;
1330 }
1331
1332 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1333 RETURN_FALSE;
1334 }
1335
1336 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
1337 RETURN_FALSE;
1338 }
1339
1340 text = ldap_get_dn(ld->link, resultentry->data);
1341 if (text != NULL) {
1342 RETVAL_STRING(text);
1343 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1344 ldap_memfree(text);
1345 #else
1346 free(text);
1347 #endif
1348 } else {
1349 RETURN_FALSE;
1350 }
1351 }
1352
1353
1354
1355
1356 PHP_FUNCTION(ldap_explode_dn)
1357 {
1358 zend_long with_attrib;
1359 char *dn, **ldap_value;
1360 int i, count;
1361 size_t dn_len;
1362
1363 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &dn, &dn_len, &with_attrib) != SUCCESS) {
1364 return;
1365 }
1366
1367 if (!(ldap_value = ldap_explode_dn(dn, with_attrib))) {
1368
1369 RETURN_FALSE;
1370 }
1371
1372 i=0;
1373 while (ldap_value[i] != NULL) i++;
1374 count = i;
1375
1376 array_init(return_value);
1377
1378 add_assoc_long(return_value, "count", count);
1379 for (i = 0; i<count; i++) {
1380 add_index_string(return_value, i, ldap_value[i]);
1381 }
1382
1383 ldap_memvfree((void **)ldap_value);
1384 }
1385
1386
1387
1388
1389 PHP_FUNCTION(ldap_dn2ufn)
1390 {
1391 char *dn, *ufn;
1392 size_t dn_len;
1393
1394 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &dn, &dn_len) != SUCCESS) {
1395 return;
1396 }
1397
1398 ufn = ldap_dn2ufn(dn);
1399
1400 if (ufn != NULL) {
1401 RETVAL_STRING(ufn);
1402 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
1403 ldap_memfree(ufn);
1404 #endif
1405 } else {
1406 RETURN_FALSE;
1407 }
1408 }
1409
1410
1411
1412
1413 #define PHP_LD_FULL_ADD 0xff
1414
1415
1416 static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper)
1417 {
1418 zval *link, *entry, *value, *ivalue;
1419 ldap_linkdata *ld;
1420 char *dn;
1421 LDAPMod **ldap_mods;
1422 int i, j, num_attribs, num_values;
1423 size_t dn_len;
1424 int *num_berval;
1425 zend_string *attribute;
1426 zend_ulong index;
1427 int is_full_add=0;
1428
1429 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) {
1430 return;
1431 }
1432
1433 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1434 RETURN_FALSE;
1435 }
1436
1437 num_attribs = zend_hash_num_elements(Z_ARRVAL_P(entry));
1438 ldap_mods = safe_emalloc((num_attribs+1), sizeof(LDAPMod *), 0);
1439 num_berval = safe_emalloc(num_attribs, sizeof(int), 0);
1440 zend_hash_internal_pointer_reset(Z_ARRVAL_P(entry));
1441
1442
1443 if (oper == PHP_LD_FULL_ADD) {
1444 oper = LDAP_MOD_ADD;
1445 is_full_add = 1;
1446 }
1447
1448
1449 for (i = 0; i < num_attribs; i++) {
1450 ldap_mods[i] = emalloc(sizeof(LDAPMod));
1451 ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
1452 ldap_mods[i]->mod_type = NULL;
1453
1454 if (zend_hash_get_current_key(Z_ARRVAL_P(entry), &attribute, &index) == HASH_KEY_IS_STRING) {
1455 ldap_mods[i]->mod_type = estrndup(ZSTR_VAL(attribute), ZSTR_LEN(attribute));
1456 } else {
1457 php_error_docref(NULL, E_WARNING, "Unknown attribute in the data");
1458
1459 while (i >= 0) {
1460 if (ldap_mods[i]->mod_type) {
1461 efree(ldap_mods[i]->mod_type);
1462 }
1463 efree(ldap_mods[i]);
1464 i--;
1465 }
1466 efree(num_berval);
1467 efree(ldap_mods);
1468 RETURN_FALSE;
1469 }
1470
1471 value = zend_hash_get_current_data(Z_ARRVAL_P(entry));
1472
1473 ZVAL_DEREF(value);
1474 if (Z_TYPE_P(value) != IS_ARRAY) {
1475 num_values = 1;
1476 } else {
1477 num_values = zend_hash_num_elements(Z_ARRVAL_P(value));
1478 }
1479
1480 num_berval[i] = num_values;
1481 ldap_mods[i]->mod_bvalues = safe_emalloc((num_values + 1), sizeof(struct berval *), 0);
1482
1483
1484 if ((num_values == 1) && (Z_TYPE_P(value) != IS_ARRAY)) {
1485 convert_to_string_ex(value);
1486 ldap_mods[i]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval));
1487 ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value);
1488 ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_P(value);
1489 } else {
1490 for (j = 0; j < num_values; j++) {
1491 if ((ivalue = zend_hash_index_find(Z_ARRVAL_P(value), j)) == NULL) {
1492 php_error_docref(NULL, E_WARNING, "Value array must have consecutive indices 0, 1, ...");
1493 num_berval[i] = j;
1494 num_attribs = i + 1;
1495 RETVAL_FALSE;
1496 goto errexit;
1497 }
1498 convert_to_string_ex(ivalue);
1499 ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval));
1500 ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(ivalue);
1501 ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_P(ivalue);
1502 }
1503 }
1504 ldap_mods[i]->mod_bvalues[num_values] = NULL;
1505 zend_hash_move_forward(Z_ARRVAL_P(entry));
1506 }
1507 ldap_mods[num_attribs] = NULL;
1508
1509
1510 if (is_full_add == 1) {
1511 if ((i = ldap_add_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
1512 php_error_docref(NULL, E_WARNING, "Add: %s", ldap_err2string(i));
1513 RETVAL_FALSE;
1514 } else RETVAL_TRUE;
1515 } else {
1516 if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
1517 php_error_docref(NULL, E_WARNING, "Modify: %s", ldap_err2string(i));
1518 RETVAL_FALSE;
1519 } else RETVAL_TRUE;
1520 }
1521
1522 errexit:
1523 for (i = 0; i < num_attribs; i++) {
1524 efree(ldap_mods[i]->mod_type);
1525 for (j = 0; j < num_berval[i]; j++) {
1526 efree(ldap_mods[i]->mod_bvalues[j]);
1527 }
1528 efree(ldap_mods[i]->mod_bvalues);
1529 efree(ldap_mods[i]);
1530 }
1531 efree(num_berval);
1532 efree(ldap_mods);
1533
1534 return;
1535 }
1536
1537
1538
1539
1540 PHP_FUNCTION(ldap_add)
1541 {
1542
1543 php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD);
1544 }
1545
1546
1547
1548
1549
1550
1551 PHP_FUNCTION(ldap_mod_replace)
1552 {
1553 php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE);
1554 }
1555
1556
1557
1558
1559 PHP_FUNCTION(ldap_mod_add)
1560 {
1561 php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD);
1562 }
1563
1564
1565
1566
1567 PHP_FUNCTION(ldap_mod_del)
1568 {
1569 php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE);
1570 }
1571
1572
1573
1574
1575 PHP_FUNCTION(ldap_delete)
1576 {
1577 zval *link;
1578 ldap_linkdata *ld;
1579 char *dn;
1580 int rc;
1581 size_t dn_len;
1582
1583 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &link, &dn, &dn_len) != SUCCESS) {
1584 return;
1585 }
1586
1587 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1588 RETURN_FALSE;
1589 }
1590
1591 if ((rc = ldap_delete_ext_s(ld->link, dn, NULL, NULL)) != LDAP_SUCCESS) {
1592 php_error_docref(NULL, E_WARNING, "Delete: %s", ldap_err2string(rc));
1593 RETURN_FALSE;
1594 }
1595
1596 RETURN_TRUE;
1597 }
1598
1599
1600
1601
1602 static int _ldap_str_equal_to_const(const char *str, uint str_len, const char *cstr)
1603 {
1604 int i;
1605
1606 if (strlen(cstr) != str_len)
1607 return 0;
1608
1609 for (i = 0; i < str_len; ++i) {
1610 if (str[i] != cstr[i]) {
1611 return 0;
1612 }
1613 }
1614
1615 return 1;
1616 }
1617
1618
1619
1620
1621 static int _ldap_strlen_max(const char *str, uint max_len)
1622 {
1623 int i;
1624
1625 for (i = 0; i < max_len; ++i) {
1626 if (str[i] == '\0') {
1627 return i;
1628 }
1629 }
1630
1631 return max_len;
1632 }
1633
1634
1635
1636
1637 static void _ldap_hash_fetch(zval *hashTbl, const char *key, zval **out)
1638 {
1639 *out = zend_hash_str_find(Z_ARRVAL_P(hashTbl), key, strlen(key));
1640 }
1641
1642
1643
1644
1645 PHP_FUNCTION(ldap_modify_batch)
1646 {
1647 ldap_linkdata *ld;
1648 zval *link, *mods, *mod, *modinfo, *modval;
1649 zval *attrib, *modtype, *vals;
1650 zval *fetched;
1651 char *dn;
1652 size_t dn_len;
1653 int i, j, k;
1654 int num_mods, num_modprops, num_modvals;
1655 LDAPMod **ldap_mods;
1656 uint oper;
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &link, &dn, &dn_len, &mods) != SUCCESS) {
1683 return;
1684 }
1685
1686 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1687 RETURN_FALSE;
1688 }
1689
1690
1691 {
1692 zend_string *modkey;
1693 zend_long modtype;
1694
1695
1696 zend_ulong tmpUlong;
1697
1698
1699 if (_ldap_strlen_max(dn, dn_len) != dn_len) {
1700 php_error_docref(NULL, E_WARNING, "DN must not contain NUL bytes");
1701 RETURN_FALSE;
1702 }
1703
1704
1705 zend_hash_internal_pointer_reset(Z_ARRVAL_P(mods));
1706 if (zend_hash_get_current_key_type(Z_ARRVAL_P(mods)) != HASH_KEY_IS_LONG) {
1707 php_error_docref(NULL, E_WARNING, "Modifications array must not be string-indexed");
1708 RETURN_FALSE;
1709 }
1710
1711 num_mods = zend_hash_num_elements(Z_ARRVAL_P(mods));
1712
1713 for (i = 0; i < num_mods; i++) {
1714
1715 if ((fetched = zend_hash_index_find(Z_ARRVAL_P(mods), i)) == NULL) {
1716 php_error_docref(NULL, E_WARNING, "Modifications array must have consecutive indices 0, 1, ...");
1717 RETURN_FALSE;
1718 }
1719 mod = fetched;
1720
1721
1722 if (Z_TYPE_P(mod) != IS_ARRAY) {
1723 php_error_docref(NULL, E_WARNING, "Each entry of modifications array must be an array itself");
1724 RETURN_FALSE;
1725 }
1726
1727
1728 zend_hash_internal_pointer_reset(Z_ARRVAL_P(mod));
1729 num_modprops = zend_hash_num_elements(Z_ARRVAL_P(mod));
1730
1731 for (j = 0; j < num_modprops; j++) {
1732
1733 if (zend_hash_get_current_key(Z_ARRVAL_P(mod), &modkey, &tmpUlong) != HASH_KEY_IS_STRING) {
1734 php_error_docref(NULL, E_WARNING, "Each entry of modifications array must be string-indexed");
1735 RETURN_FALSE;
1736 }
1737
1738
1739 if (
1740 !_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_ATTRIB) &&
1741 !_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_MODTYPE) &&
1742 !_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_VALUES)
1743 ) {
1744 php_error_docref(NULL, E_WARNING, "The only allowed keys in entries of the modifications array are '" LDAP_MODIFY_BATCH_ATTRIB "', '" LDAP_MODIFY_BATCH_MODTYPE "' and '" LDAP_MODIFY_BATCH_VALUES "'");
1745 RETURN_FALSE;
1746 }
1747
1748 fetched = zend_hash_get_current_data(Z_ARRVAL_P(mod));
1749 modinfo = fetched;
1750
1751
1752 if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_ATTRIB)) {
1753 if (Z_TYPE_P(modinfo) != IS_STRING) {
1754 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must be a string");
1755 RETURN_FALSE;
1756 }
1757
1758 if (Z_STRLEN_P(modinfo) != _ldap_strlen_max(Z_STRVAL_P(modinfo), Z_STRLEN_P(modinfo))) {
1759 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must not contain NUL bytes");
1760 RETURN_FALSE;
1761 }
1762 }
1763 else if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_MODTYPE)) {
1764 if (Z_TYPE_P(modinfo) != IS_LONG) {
1765 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_MODTYPE "' value must be a long");
1766 RETURN_FALSE;
1767 }
1768
1769
1770 modtype = Z_LVAL_P(modinfo);
1771 if (
1772 modtype != LDAP_MODIFY_BATCH_ADD &&
1773 modtype != LDAP_MODIFY_BATCH_REMOVE &&
1774 modtype != LDAP_MODIFY_BATCH_REPLACE &&
1775 modtype != LDAP_MODIFY_BATCH_REMOVE_ALL
1776 ) {
1777 php_error_docref(NULL, E_WARNING, "The '" LDAP_MODIFY_BATCH_MODTYPE "' value must match one of the LDAP_MODIFY_BATCH_* constants");
1778 RETURN_FALSE;
1779 }
1780
1781
1782 if (modtype == LDAP_MODIFY_BATCH_REMOVE_ALL) {
1783 if (zend_hash_str_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES))) {
1784 php_error_docref(NULL, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must not be provided");
1785 RETURN_FALSE;
1786 }
1787 }
1788 else {
1789 if (!zend_hash_str_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES))) {
1790 php_error_docref(NULL, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is not LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must be provided");
1791 RETURN_FALSE;
1792 }
1793 }
1794 }
1795 else if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_VALUES)) {
1796 if (Z_TYPE_P(modinfo) != IS_ARRAY) {
1797 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' value must be an array");
1798 RETURN_FALSE;
1799 }
1800
1801
1802 zend_hash_internal_pointer_reset(Z_ARRVAL_P(modinfo));
1803 num_modvals = zend_hash_num_elements(Z_ARRVAL_P(modinfo));
1804 if (num_modvals == 0) {
1805 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have at least one element");
1806 RETURN_FALSE;
1807 }
1808
1809
1810 if (zend_hash_get_current_key_type(Z_ARRVAL_P(modinfo)) != HASH_KEY_IS_LONG) {
1811 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must not be string-indexed");
1812 RETURN_FALSE;
1813 }
1814
1815
1816 for (k = 0; k < num_modvals; k++) {
1817 if ((fetched = zend_hash_index_find(Z_ARRVAL_P(modinfo), k)) == NULL) {
1818 php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have consecutive indices 0, 1, ...");
1819 RETURN_FALSE;
1820 }
1821 modval = fetched;
1822
1823
1824 if (Z_TYPE_P(modval) != IS_STRING) {
1825 php_error_docref(NULL, E_WARNING, "Each element of a '" LDAP_MODIFY_BATCH_VALUES "' array must be a string");
1826 RETURN_FALSE;
1827 }
1828 }
1829 }
1830
1831 zend_hash_move_forward(Z_ARRVAL_P(mod));
1832 }
1833 }
1834 }
1835
1836
1837
1838 ldap_mods = safe_emalloc((num_mods+1), sizeof(LDAPMod *), 0);
1839
1840
1841 for (i = 0; i < num_mods; i++) {
1842
1843 ldap_mods[i] = safe_emalloc(1, sizeof(LDAPMod), 0);
1844
1845
1846 fetched = zend_hash_index_find(Z_ARRVAL_P(mods), i);
1847 mod = fetched;
1848
1849 _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_ATTRIB, &attrib);
1850 _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_MODTYPE, &modtype);
1851 _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_VALUES, &vals);
1852
1853
1854 switch (Z_LVAL_P(modtype)) {
1855 case LDAP_MODIFY_BATCH_ADD:
1856 oper = LDAP_MOD_ADD;
1857 break;
1858 case LDAP_MODIFY_BATCH_REMOVE:
1859 case LDAP_MODIFY_BATCH_REMOVE_ALL:
1860 oper = LDAP_MOD_DELETE;
1861 break;
1862 case LDAP_MODIFY_BATCH_REPLACE:
1863 oper = LDAP_MOD_REPLACE;
1864 break;
1865 default:
1866 php_error_docref(NULL, E_ERROR, "Unknown and uncaught modification type.");
1867 RETURN_FALSE;
1868 }
1869
1870
1871 ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES;
1872 ldap_mods[i]->mod_type = estrndup(Z_STRVAL_P(attrib), Z_STRLEN_P(attrib));
1873
1874 if (Z_LVAL_P(modtype) == LDAP_MODIFY_BATCH_REMOVE_ALL) {
1875
1876 ldap_mods[i]->mod_bvalues = NULL;
1877 }
1878 else {
1879
1880 num_modvals = zend_hash_num_elements(Z_ARRVAL_P(vals));
1881 ldap_mods[i]->mod_bvalues = safe_emalloc((num_modvals+1), sizeof(struct berval *), 0);
1882
1883
1884 for (j = 0; j < num_modvals; j++) {
1885
1886 fetched = zend_hash_index_find(Z_ARRVAL_P(vals), j);
1887 modval = fetched;
1888
1889
1890 ldap_mods[i]->mod_bvalues[j] = safe_emalloc(1, sizeof(struct berval), 0);
1891
1892
1893 ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(modval);
1894 ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(Z_STRVAL_P(modval), Z_STRLEN_P(modval));
1895 }
1896
1897
1898 ldap_mods[i]->mod_bvalues[num_modvals] = NULL;
1899 }
1900 }
1901
1902
1903 ldap_mods[num_mods] = NULL;
1904
1905
1906 if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
1907 php_error_docref(NULL, E_WARNING, "Batch Modify: %s", ldap_err2string(i));
1908 RETVAL_FALSE;
1909 } else RETVAL_TRUE;
1910
1911
1912 {
1913 for (i = 0; i < num_mods; i++) {
1914
1915 efree(ldap_mods[i]->mod_type);
1916
1917 if (ldap_mods[i]->mod_bvalues != NULL) {
1918
1919 for (j = 0; ldap_mods[i]->mod_bvalues[j] != NULL; j++) {
1920
1921 efree(ldap_mods[i]->mod_bvalues[j]->bv_val);
1922
1923
1924 efree(ldap_mods[i]->mod_bvalues[j]);
1925 }
1926
1927
1928 efree(ldap_mods[i]->mod_bvalues);
1929 }
1930
1931
1932 efree(ldap_mods[i]);
1933 }
1934
1935
1936 efree(ldap_mods);
1937 }
1938 }
1939
1940
1941
1942
1943 PHP_FUNCTION(ldap_errno)
1944 {
1945 zval *link;
1946 ldap_linkdata *ld;
1947
1948 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
1949 return;
1950 }
1951
1952 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1953 RETURN_FALSE;
1954 }
1955
1956 RETURN_LONG(_get_lderrno(ld->link));
1957 }
1958
1959
1960
1961
1962 PHP_FUNCTION(ldap_err2str)
1963 {
1964 zend_long perrno;
1965
1966 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &perrno) != SUCCESS) {
1967 return;
1968 }
1969
1970 RETURN_STRING(ldap_err2string(perrno));
1971 }
1972
1973
1974
1975
1976 PHP_FUNCTION(ldap_error)
1977 {
1978 zval *link;
1979 ldap_linkdata *ld;
1980 int ld_errno;
1981
1982 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
1983 return;
1984 }
1985
1986 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
1987 RETURN_FALSE;
1988 }
1989
1990 ld_errno = _get_lderrno(ld->link);
1991
1992 RETURN_STRING(ldap_err2string(ld_errno));
1993 }
1994
1995
1996
1997
1998 PHP_FUNCTION(ldap_compare)
1999 {
2000 zval *link;
2001 char *dn, *attr, *value;
2002 size_t dn_len, attr_len, value_len;
2003 ldap_linkdata *ld;
2004 int errno;
2005 struct berval lvalue;
2006
2007 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsss", &link, &dn, &dn_len, &attr, &attr_len, &value, &value_len) != SUCCESS) {
2008 return;
2009 }
2010
2011 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2012 RETURN_FALSE;
2013 }
2014
2015 lvalue.bv_val = value;
2016 lvalue.bv_len = value_len;
2017
2018 errno = ldap_compare_ext_s(ld->link, dn, attr, &lvalue, NULL, NULL);
2019
2020 switch (errno) {
2021 case LDAP_COMPARE_TRUE:
2022 RETURN_TRUE;
2023 break;
2024
2025 case LDAP_COMPARE_FALSE:
2026 RETURN_FALSE;
2027 break;
2028 }
2029
2030 php_error_docref(NULL, E_WARNING, "Compare: %s", ldap_err2string(errno));
2031 RETURN_LONG(-1);
2032 }
2033
2034
2035
2036
2037 PHP_FUNCTION(ldap_sort)
2038 {
2039 zval *link, *result;
2040 ldap_linkdata *ld;
2041 char *sortfilter;
2042 size_t sflen;
2043 zend_resource *le;
2044
2045 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs", &link, &result, &sortfilter, &sflen) != SUCCESS) {
2046 RETURN_FALSE;
2047 }
2048
2049 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2050 RETURN_FALSE;
2051 }
2052
2053 le = Z_RES_P(result);
2054 if (le->type != le_result) {
2055 php_error_docref(NULL, E_WARNING, "Supplied resource is not a valid ldap result resource");
2056 RETURN_FALSE;
2057 }
2058
2059 if (ldap_sort_entries(ld->link, (LDAPMessage **) &le->ptr, sflen ? sortfilter : NULL, strcmp) != LDAP_SUCCESS) {
2060 php_error_docref(NULL, E_WARNING, "%s", ldap_err2string(errno));
2061 RETURN_FALSE;
2062 }
2063
2064 RETURN_TRUE;
2065 }
2066
2067
2068 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
2069
2070
2071 PHP_FUNCTION(ldap_get_option)
2072 {
2073 zval *link, *retval;
2074 ldap_linkdata *ld;
2075 zend_long option;
2076
2077 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz/", &link, &option, &retval) != SUCCESS) {
2078 return;
2079 }
2080
2081 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2082 RETURN_FALSE;
2083 }
2084
2085 switch (option) {
2086
2087 case LDAP_OPT_DEREF:
2088 case LDAP_OPT_SIZELIMIT:
2089 case LDAP_OPT_TIMELIMIT:
2090 case LDAP_OPT_PROTOCOL_VERSION:
2091 case LDAP_OPT_ERROR_NUMBER:
2092 case LDAP_OPT_REFERRALS:
2093 #ifdef LDAP_OPT_RESTART
2094 case LDAP_OPT_RESTART:
2095 #endif
2096 #ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
2097 case LDAP_OPT_X_TLS_REQUIRE_CERT:
2098 #endif
2099 {
2100 int val;
2101
2102 if (ldap_get_option(ld->link, option, &val)) {
2103 RETURN_FALSE;
2104 }
2105 zval_ptr_dtor(retval);
2106 ZVAL_LONG(retval, val);
2107 } break;
2108 #ifdef LDAP_OPT_NETWORK_TIMEOUT
2109 case LDAP_OPT_NETWORK_TIMEOUT:
2110 {
2111 struct timeval *timeout = NULL;
2112
2113 if (ldap_get_option(ld->link, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
2114 if (timeout) {
2115 ldap_memfree(timeout);
2116 }
2117 RETURN_FALSE;
2118 }
2119 if (!timeout) {
2120 RETURN_FALSE;
2121 }
2122 zval_ptr_dtor(retval);
2123 ZVAL_LONG(retval, timeout->tv_sec);
2124 ldap_memfree(timeout);
2125 } break;
2126 #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
2127 case LDAP_X_OPT_CONNECT_TIMEOUT:
2128 {
2129 int timeout;
2130
2131 if (ldap_get_option(ld->link, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
2132 RETURN_FALSE;
2133 }
2134 zval_ptr_dtor(retval);
2135 ZVAL_LONG(retval, (timeout / 1000));
2136 } break;
2137 #endif
2138 #ifdef LDAP_OPT_TIMEOUT
2139 case LDAP_OPT_TIMEOUT:
2140 {
2141 struct timeval *timeout = NULL;
2142
2143 if (ldap_get_option(ld->link, LDAP_OPT_TIMEOUT, (void *) &timeout)) {
2144 if (timeout) {
2145 ldap_memfree(timeout);
2146 }
2147 RETURN_FALSE;
2148 }
2149 if (!timeout) {
2150 RETURN_FALSE;
2151 }
2152 zval_dtor(retval);
2153 ZVAL_LONG(retval, timeout->tv_sec);
2154 ldap_memfree(timeout);
2155 } break;
2156 #endif
2157
2158 case LDAP_OPT_ERROR_STRING:
2159 #ifdef LDAP_OPT_HOST_NAME
2160 case LDAP_OPT_HOST_NAME:
2161 #endif
2162 #ifdef HAVE_LDAP_SASL
2163 case LDAP_OPT_X_SASL_MECH:
2164 case LDAP_OPT_X_SASL_REALM:
2165 case LDAP_OPT_X_SASL_AUTHCID:
2166 case LDAP_OPT_X_SASL_AUTHZID:
2167 #endif
2168 #ifdef LDAP_OPT_MATCHED_DN
2169 case LDAP_OPT_MATCHED_DN:
2170 #endif
2171 {
2172 char *val = NULL;
2173
2174 if (ldap_get_option(ld->link, option, &val) || val == NULL || *val == '\0') {
2175 if (val) {
2176 ldap_memfree(val);
2177 }
2178 RETURN_FALSE;
2179 }
2180 zval_ptr_dtor(retval);
2181 ZVAL_STRING(retval, val);
2182 ldap_memfree(val);
2183 } break;
2184
2185
2186
2187
2188
2189
2190 default:
2191 RETURN_FALSE;
2192 }
2193 RETURN_TRUE;
2194 }
2195
2196
2197
2198
2199 PHP_FUNCTION(ldap_set_option)
2200 {
2201 zval *link, *newval;
2202 ldap_linkdata *ld;
2203 LDAP *ldap;
2204 zend_long option;
2205
2206 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zlz", &link, &option, &newval) != SUCCESS) {
2207 return;
2208 }
2209
2210 if (Z_TYPE_P(link) == IS_NULL) {
2211 ldap = NULL;
2212 } else {
2213 if ((ld = (ldap_linkdata *)zend_fetch_resource_ex(link, "ldap link", le_link)) == NULL) {
2214 RETURN_FALSE;
2215 }
2216 ldap = ld->link;
2217 }
2218
2219 switch (option) {
2220
2221 case LDAP_OPT_DEREF:
2222 case LDAP_OPT_SIZELIMIT:
2223 case LDAP_OPT_TIMELIMIT:
2224 case LDAP_OPT_PROTOCOL_VERSION:
2225 case LDAP_OPT_ERROR_NUMBER:
2226 #ifdef LDAP_OPT_DEBUG_LEVEL
2227 case LDAP_OPT_DEBUG_LEVEL:
2228 #endif
2229 #ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
2230 case LDAP_OPT_X_TLS_REQUIRE_CERT:
2231 #endif
2232 {
2233 int val;
2234
2235 convert_to_long_ex(newval);
2236 val = Z_LVAL_P(newval);
2237 if (ldap_set_option(ldap, option, &val)) {
2238 RETURN_FALSE;
2239 }
2240 } break;
2241 #ifdef LDAP_OPT_NETWORK_TIMEOUT
2242 case LDAP_OPT_NETWORK_TIMEOUT:
2243 {
2244 struct timeval timeout;
2245
2246 convert_to_long_ex(newval);
2247 timeout.tv_sec = Z_LVAL_P(newval);
2248 timeout.tv_usec = 0;
2249 if (ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, (void *) &timeout)) {
2250 RETURN_FALSE;
2251 }
2252 } break;
2253 #elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
2254 case LDAP_X_OPT_CONNECT_TIMEOUT:
2255 {
2256 int timeout;
2257
2258 convert_to_long_ex(newval);
2259 timeout = 1000 * Z_LVAL_P(newval);
2260 if (ldap_set_option(ldap, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout)) {
2261 RETURN_FALSE;
2262 }
2263 } break;
2264 #endif
2265 #ifdef LDAP_OPT_TIMEOUT
2266 case LDAP_OPT_TIMEOUT:
2267 {
2268 struct timeval timeout;
2269
2270 convert_to_long_ex(newval);
2271 timeout.tv_sec = Z_LVAL_P(newval);
2272 timeout.tv_usec = 0;
2273 if (ldap_set_option(ldap, LDAP_OPT_TIMEOUT, (void *) &timeout)) {
2274 RETURN_FALSE;
2275 }
2276 } break;
2277 #endif
2278
2279 case LDAP_OPT_ERROR_STRING:
2280 #ifdef LDAP_OPT_HOST_NAME
2281 case LDAP_OPT_HOST_NAME:
2282 #endif
2283 #ifdef HAVE_LDAP_SASL
2284 case LDAP_OPT_X_SASL_MECH:
2285 case LDAP_OPT_X_SASL_REALM:
2286 case LDAP_OPT_X_SASL_AUTHCID:
2287 case LDAP_OPT_X_SASL_AUTHZID:
2288 #endif
2289 #ifdef LDAP_OPT_MATCHED_DN
2290 case LDAP_OPT_MATCHED_DN:
2291 #endif
2292 {
2293 char *val;
2294 convert_to_string_ex(newval);
2295 val = Z_STRVAL_P(newval);
2296 if (ldap_set_option(ldap, option, val)) {
2297 RETURN_FALSE;
2298 }
2299 } break;
2300
2301 case LDAP_OPT_REFERRALS:
2302 #ifdef LDAP_OPT_RESTART
2303 case LDAP_OPT_RESTART:
2304 #endif
2305 {
2306 void *val;
2307 convert_to_boolean_ex(newval);
2308 val = Z_TYPE_P(newval) == IS_TRUE
2309 ? LDAP_OPT_ON : LDAP_OPT_OFF;
2310 if (ldap_set_option(ldap, option, val)) {
2311 RETURN_FALSE;
2312 }
2313 } break;
2314
2315 case LDAP_OPT_SERVER_CONTROLS:
2316 case LDAP_OPT_CLIENT_CONTROLS:
2317 {
2318 LDAPControl *ctrl, **ctrls, **ctrlp;
2319 zval *ctrlval, *val;
2320 int ncontrols;
2321 char error=0;
2322
2323 if ((Z_TYPE_P(newval) != IS_ARRAY) || !(ncontrols = zend_hash_num_elements(Z_ARRVAL_P(newval)))) {
2324 php_error_docref(NULL, E_WARNING, "Expected non-empty array value for this option");
2325 RETURN_FALSE;
2326 }
2327 ctrls = safe_emalloc((1 + ncontrols), sizeof(*ctrls), 0);
2328 *ctrls = NULL;
2329 ctrlp = ctrls;
2330 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(newval), ctrlval) {
2331 if (Z_TYPE_P(ctrlval) != IS_ARRAY) {
2332 php_error_docref(NULL, E_WARNING, "The array value must contain only arrays, where each array is a control");
2333 error = 1;
2334 break;
2335 }
2336 if ((val = zend_hash_str_find(Z_ARRVAL_P(ctrlval), "oid", sizeof("oid") - 1)) == NULL) {
2337 php_error_docref(NULL, E_WARNING, "Control must have an oid key");
2338 error = 1;
2339 break;
2340 }
2341 ctrl = *ctrlp = emalloc(sizeof(**ctrlp));
2342 convert_to_string_ex(val);
2343 ctrl->ldctl_oid = Z_STRVAL_P(val);
2344 if ((val = zend_hash_str_find(Z_ARRVAL_P(ctrlval), "value", sizeof("value") - 1)) != NULL) {
2345 convert_to_string_ex(val);
2346 ctrl->ldctl_value.bv_val = Z_STRVAL_P(val);
2347 ctrl->ldctl_value.bv_len = Z_STRLEN_P(val);
2348 } else {
2349 ctrl->ldctl_value.bv_val = NULL;
2350 ctrl->ldctl_value.bv_len = 0;
2351 }
2352 if ((val = zend_hash_str_find(Z_ARRVAL_P(ctrlval), "iscritical", sizeof("iscritical") - 1)) != NULL) {
2353 convert_to_boolean_ex(val);
2354 ctrl->ldctl_iscritical = Z_TYPE_P(val) == IS_TRUE;
2355 } else {
2356 ctrl->ldctl_iscritical = 0;
2357 }
2358
2359 ++ctrlp;
2360 *ctrlp = NULL;
2361 } ZEND_HASH_FOREACH_END();
2362 if (!error) {
2363 error = ldap_set_option(ldap, option, ctrls);
2364 }
2365 ctrlp = ctrls;
2366 while (*ctrlp) {
2367 efree(*ctrlp);
2368 ctrlp++;
2369 }
2370 efree(ctrls);
2371 if (error) {
2372 RETURN_FALSE;
2373 }
2374 } break;
2375 default:
2376 RETURN_FALSE;
2377 }
2378 RETURN_TRUE;
2379 }
2380
2381
2382 #ifdef HAVE_LDAP_PARSE_RESULT
2383
2384
2385 PHP_FUNCTION(ldap_parse_result)
2386 {
2387 zval *link, *result, *errcode, *matcheddn, *errmsg, *referrals;
2388 ldap_linkdata *ld;
2389 LDAPMessage *ldap_result;
2390 char **lreferrals, **refp;
2391 char *lmatcheddn, *lerrmsg;
2392 int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
2393
2394 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrz/|z/z/z/", &link, &result, &errcode, &matcheddn, &errmsg, &referrals) != SUCCESS) {
2395 return;
2396 }
2397
2398 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2399 RETURN_FALSE;
2400 }
2401
2402 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
2403 RETURN_FALSE;
2404 }
2405
2406 rc = ldap_parse_result(ld->link, ldap_result, &lerrcode,
2407 myargcount > 3 ? &lmatcheddn : NULL,
2408 myargcount > 4 ? &lerrmsg : NULL,
2409 myargcount > 5 ? &lreferrals : NULL,
2410 NULL ,
2411 0);
2412 if (rc != LDAP_SUCCESS) {
2413 php_error_docref(NULL, E_WARNING, "Unable to parse result: %s", ldap_err2string(rc));
2414 RETURN_FALSE;
2415 }
2416
2417 zval_ptr_dtor(errcode);
2418 ZVAL_LONG(errcode, lerrcode);
2419
2420
2421 switch (myargcount) {
2422 case 6:
2423 zval_ptr_dtor(referrals);
2424 array_init(referrals);
2425 if (lreferrals != NULL) {
2426 refp = lreferrals;
2427 while (*refp) {
2428 add_next_index_string(referrals, *refp);
2429 refp++;
2430 }
2431 ldap_memvfree((void**)lreferrals);
2432 }
2433 case 5:
2434 zval_ptr_dtor(errmsg);
2435 if (lerrmsg == NULL) {
2436 ZVAL_EMPTY_STRING(errmsg);
2437 } else {
2438 ZVAL_STRING(errmsg, lerrmsg);
2439 ldap_memfree(lerrmsg);
2440 }
2441 case 4:
2442 zval_ptr_dtor(matcheddn);
2443 if (lmatcheddn == NULL) {
2444 ZVAL_EMPTY_STRING(matcheddn);
2445 } else {
2446 ZVAL_STRING(matcheddn, lmatcheddn);
2447 ldap_memfree(lmatcheddn);
2448 }
2449 }
2450 RETURN_TRUE;
2451 }
2452
2453 #endif
2454
2455
2456
2457 PHP_FUNCTION(ldap_first_reference)
2458 {
2459 zval *link, *result;
2460 ldap_linkdata *ld;
2461 ldap_resultentry *resultentry;
2462 LDAPMessage *ldap_result, *entry;
2463
2464 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result) != SUCCESS) {
2465 return;
2466 }
2467
2468 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2469 RETURN_FALSE;
2470 }
2471
2472 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
2473 RETURN_FALSE;
2474 }
2475
2476 if ((entry = ldap_first_reference(ld->link, ldap_result)) == NULL) {
2477 RETVAL_FALSE;
2478 } else {
2479 resultentry = emalloc(sizeof(ldap_resultentry));
2480 RETVAL_RES(zend_register_resource(resultentry, le_result_entry));
2481 ZVAL_COPY(&resultentry->res, result);
2482 resultentry->data = entry;
2483 resultentry->ber = NULL;
2484 }
2485 }
2486
2487
2488
2489
2490 PHP_FUNCTION(ldap_next_reference)
2491 {
2492 zval *link, *result_entry;
2493 ldap_linkdata *ld;
2494 ldap_resultentry *resultentry, *resultentry_next;
2495 LDAPMessage *entry_next;
2496
2497 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &link, &result_entry) != SUCCESS) {
2498 return;
2499 }
2500
2501 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2502 RETURN_FALSE;
2503 }
2504
2505 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
2506 RETURN_FALSE;
2507 }
2508
2509 if ((entry_next = ldap_next_reference(ld->link, resultentry->data)) == NULL) {
2510 RETVAL_FALSE;
2511 } else {
2512 resultentry_next = emalloc(sizeof(ldap_resultentry));
2513 RETVAL_RES(zend_register_resource(resultentry_next, le_result_entry));
2514 ZVAL_COPY(&resultentry_next->res, &resultentry->res);
2515 resultentry_next->data = entry_next;
2516 resultentry_next->ber = NULL;
2517 }
2518 }
2519
2520
2521 #ifdef HAVE_LDAP_PARSE_REFERENCE
2522
2523
2524 PHP_FUNCTION(ldap_parse_reference)
2525 {
2526 zval *link, *result_entry, *referrals;
2527 ldap_linkdata *ld;
2528 ldap_resultentry *resultentry;
2529 char **lreferrals, **refp;
2530
2531 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrz/", &link, &result_entry, &referrals) != SUCCESS) {
2532 return;
2533 }
2534
2535 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2536 RETURN_FALSE;
2537 }
2538
2539 if ((resultentry = (ldap_resultentry *)zend_fetch_resource(Z_RES_P(result_entry), "ldap result entry", le_result_entry)) == NULL) {
2540 RETURN_FALSE;
2541 }
2542
2543 if (ldap_parse_reference(ld->link, resultentry->data, &lreferrals, NULL , 0) != LDAP_SUCCESS) {
2544 RETURN_FALSE;
2545 }
2546
2547 zval_ptr_dtor(referrals);
2548 array_init(referrals);
2549 if (lreferrals != NULL) {
2550 refp = lreferrals;
2551 while (*refp) {
2552 add_next_index_string(referrals, *refp);
2553 refp++;
2554 }
2555 ldap_memvfree((void**)lreferrals);
2556 }
2557 RETURN_TRUE;
2558 }
2559
2560 #endif
2561
2562
2563
2564 PHP_FUNCTION(ldap_rename)
2565 {
2566 zval *link;
2567 ldap_linkdata *ld;
2568 int rc;
2569 char *dn, *newrdn, *newparent;
2570 size_t dn_len, newrdn_len, newparent_len;
2571 zend_bool deleteoldrdn;
2572
2573 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsssb", &link, &dn, &dn_len, &newrdn, &newrdn_len, &newparent, &newparent_len, &deleteoldrdn) != SUCCESS) {
2574 return;
2575 }
2576
2577 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2578 RETURN_FALSE;
2579 }
2580
2581 if (newparent_len == 0) {
2582 newparent = NULL;
2583 }
2584
2585 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
2586 rc = ldap_rename_s(ld->link, dn, newrdn, newparent, deleteoldrdn, NULL, NULL);
2587 #else
2588 if (newparent_len != 0) {
2589 php_error_docref(NULL, E_WARNING, "You are using old LDAP API, newparent must be the empty string, can only modify RDN");
2590 RETURN_FALSE;
2591 }
2592
2593 rc = ldap_modrdn2_s(ld->link, dn, newrdn, deleteoldrdn);
2594 #endif
2595
2596 if (rc == LDAP_SUCCESS) {
2597 RETURN_TRUE;
2598 }
2599 RETURN_FALSE;
2600 }
2601
2602
2603 #ifdef HAVE_LDAP_START_TLS_S
2604
2605
2606 PHP_FUNCTION(ldap_start_tls)
2607 {
2608 zval *link;
2609 ldap_linkdata *ld;
2610 int rc, protocol = LDAP_VERSION3;
2611
2612 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
2613 return;
2614 }
2615
2616 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2617 RETURN_FALSE;
2618 }
2619
2620 if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
2621 ((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
2622 ) {
2623 php_error_docref(NULL, E_WARNING,"Unable to start TLS: %s", ldap_err2string(rc));
2624 RETURN_FALSE;
2625 } else {
2626 RETURN_TRUE;
2627 }
2628 }
2629
2630 #endif
2631 #endif
2632
2633 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
2634
2635
2636 int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params)
2637 {
2638 ldap_linkdata *ld;
2639 int retval;
2640 zval cb_args[2];
2641 zval cb_retval;
2642 zval *cb_link = (zval *) params;
2643
2644 ld = (ldap_linkdata *) zend_fetch_resource_ex(cb_link, "ldap link", le_link);
2645
2646
2647 if (ld == NULL || Z_ISUNDEF(ld->rebindproc)) {
2648 php_error_docref(NULL, E_WARNING, "Link not found or no callback set");
2649 return LDAP_OTHER;
2650 }
2651
2652
2653 ZVAL_COPY_VALUE(&cb_args[0], cb_link);
2654 ZVAL_STRING(&cb_args[1], url);
2655 if (call_user_function_ex(EG(function_table), NULL, &ld->rebindproc, &cb_retval, 2, cb_args, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) {
2656 convert_to_long_ex(&cb_retval);
2657 retval = Z_LVAL(cb_retval);
2658 zval_ptr_dtor(&cb_retval);
2659 } else {
2660 php_error_docref(NULL, E_WARNING, "rebind_proc PHP callback failed");
2661 retval = LDAP_OTHER;
2662 }
2663 zval_ptr_dtor(&cb_args[1]);
2664 return retval;
2665 }
2666
2667
2668
2669
2670 PHP_FUNCTION(ldap_set_rebind_proc)
2671 {
2672 zval *link, *callback;
2673 ldap_linkdata *ld;
2674 zend_string *callback_name;
2675
2676 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &link, &callback) != SUCCESS) {
2677 RETURN_FALSE;
2678 }
2679
2680 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2681 RETURN_FALSE;
2682 }
2683
2684 if (Z_TYPE_P(callback) == IS_STRING && Z_STRLEN_P(callback) == 0) {
2685
2686 if (!Z_ISUNDEF(ld->rebindproc)) {
2687 zval_ptr_dtor(&ld->rebindproc);
2688 ZVAL_UNDEF(&ld->rebindproc);
2689 ldap_set_rebind_proc(ld->link, NULL, NULL);
2690 }
2691 RETURN_TRUE;
2692 }
2693
2694
2695 if (!zend_is_callable(callback, 0, &callback_name)) {
2696 php_error_docref(NULL, E_WARNING, "Two arguments expected for '%s' to be a valid callback", ZSTR_VAL(callback_name));
2697 zend_string_release(callback_name);
2698 RETURN_FALSE;
2699 }
2700 zend_string_release(callback_name);
2701
2702
2703 if (Z_ISUNDEF(ld->rebindproc)) {
2704 ldap_set_rebind_proc(ld->link, _ldap_rebind_proc, (void *) link);
2705 } else {
2706 zval_ptr_dtor(&ld->rebindproc);
2707 }
2708
2709 ZVAL_COPY(&ld->rebindproc, callback);
2710 RETURN_TRUE;
2711 }
2712
2713 #endif
2714
2715 static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen)
2716 {
2717 char hex[] = "0123456789abcdef";
2718 int i, p = 0;
2719 size_t len = 0;
2720 zend_string *ret;
2721
2722 for (i = 0; i < valuelen; i++) {
2723 len += (map[(unsigned char) value[i]]) ? 3 : 1;
2724 }
2725
2726 ret = zend_string_alloc(len, 0);
2727
2728 for (i = 0; i < valuelen; i++) {
2729 unsigned char v = (unsigned char) value[i];
2730
2731 if (map[v]) {
2732 ZSTR_VAL(ret)[p++] = '\\';
2733 ZSTR_VAL(ret)[p++] = hex[v >> 4];
2734 ZSTR_VAL(ret)[p++] = hex[v & 0x0f];
2735 } else {
2736 ZSTR_VAL(ret)[p++] = v;
2737 }
2738 }
2739
2740 ZSTR_VAL(ret)[p] = '\0';
2741 ZSTR_LEN(ret) = p;
2742 return ret;
2743 }
2744
2745 static void php_ldap_escape_map_set_chars(zend_bool *map, const char *chars, const int charslen, char escape)
2746 {
2747 int i = 0;
2748 while (i < charslen) {
2749 map[(unsigned char) chars[i++]] = escape;
2750 }
2751 }
2752
2753 PHP_FUNCTION(ldap_escape)
2754 {
2755 char *value, *ignores;
2756 size_t valuelen = 0, ignoreslen = 0;
2757 int i;
2758 zend_long flags = 0;
2759 zend_bool map[256] = {0}, havecharlist = 0;
2760
2761 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) {
2762 return;
2763 }
2764
2765 if (!valuelen) {
2766 RETURN_EMPTY_STRING();
2767 }
2768
2769 if (flags & PHP_LDAP_ESCAPE_FILTER) {
2770 havecharlist = 1;
2771 php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1);
2772 }
2773
2774 if (flags & PHP_LDAP_ESCAPE_DN) {
2775 havecharlist = 1;
2776 php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1);
2777 }
2778
2779 if (!havecharlist) {
2780 for (i = 0; i < 256; i++) {
2781 map[i] = 1;
2782 }
2783 }
2784
2785 if (ignoreslen) {
2786 php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
2787 }
2788
2789 RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen));
2790 }
2791
2792 #ifdef STR_TRANSLATION
2793
2794
2795 static void php_ldap_do_translate(INTERNAL_FUNCTION_PARAMETERS, int way)
2796 {
2797 char *value;
2798 size_t value_len;
2799 int result;
2800
2801 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &value, &value_len) != SUCCESS) {
2802 return;
2803 }
2804
2805 if (value_len == 0) {
2806 RETURN_FALSE;
2807 }
2808
2809 if (way == 1) {
2810 result = ldap_8859_to_t61(&value, &value_len, 0);
2811 } else {
2812 result = ldap_t61_to_8859(&value, &value_len, 0);
2813 }
2814
2815 if (result == LDAP_SUCCESS) {
2816 RETVAL_STRINGL(value, value_len);
2817 free(value);
2818 } else {
2819 php_error_docref(NULL, E_WARNING, "Conversion from iso-8859-1 to t61 failed: %s", ldap_err2string(result));
2820 RETVAL_FALSE;
2821 }
2822 }
2823
2824
2825
2826
2827 PHP_FUNCTION(ldap_t61_to_8859)
2828 {
2829 php_ldap_do_translate(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2830 }
2831
2832
2833
2834
2835 PHP_FUNCTION(ldap_8859_to_t61)
2836 {
2837 php_ldap_do_translate(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2838 }
2839
2840 #endif
2841
2842 #ifdef LDAP_CONTROL_PAGEDRESULTS
2843
2844
2845 PHP_FUNCTION(ldap_control_paged_result)
2846 {
2847 zend_long pagesize;
2848 zend_bool iscritical;
2849 zval *link;
2850 char *cookie = NULL;
2851 size_t cookie_len = 0;
2852 struct berval lcookie = { 0, NULL };
2853 ldap_linkdata *ld;
2854 LDAP *ldap;
2855 BerElement *ber = NULL;
2856 LDAPControl ctrl, *ctrlsp[2];
2857 int rc, myargcount = ZEND_NUM_ARGS();
2858
2859 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|bs", &link, &pagesize, &iscritical, &cookie, &cookie_len) != SUCCESS) {
2860 return;
2861 }
2862
2863 if (Z_TYPE_P(link) == IS_NULL) {
2864 ldap = NULL;
2865 } else {
2866 if ((ld = (ldap_linkdata *)zend_fetch_resource_ex(link, "ldap link", le_link)) == NULL) {
2867 RETURN_FALSE;
2868 }
2869 ldap = ld->link;
2870 }
2871
2872 ber = ber_alloc_t(LBER_USE_DER);
2873 if (ber == NULL) {
2874 php_error_docref(NULL, E_WARNING, "Unable to alloc BER encoding resources for paged results control");
2875 RETURN_FALSE;
2876 }
2877
2878 ctrl.ldctl_iscritical = 0;
2879
2880 switch (myargcount) {
2881 case 4:
2882 lcookie.bv_val = cookie;
2883 lcookie.bv_len = cookie_len;
2884
2885 case 3:
2886 ctrl.ldctl_iscritical = (int)iscritical;
2887
2888 }
2889
2890 if (ber_printf(ber, "{iO}", (int)pagesize, &lcookie) == LBER_ERROR) {
2891 php_error_docref(NULL, E_WARNING, "Unable to BER printf paged results control");
2892 RETVAL_FALSE;
2893 goto lcpr_error_out;
2894 }
2895 rc = ber_flatten2(ber, &ctrl.ldctl_value, 0);
2896 if (rc == LBER_ERROR) {
2897 php_error_docref(NULL, E_WARNING, "Unable to BER encode paged results control");
2898 RETVAL_FALSE;
2899 goto lcpr_error_out;
2900 }
2901
2902 ctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
2903
2904 if (ldap) {
2905
2906 ctrlsp[0] = &ctrl;
2907 ctrlsp[1] = NULL;
2908
2909 rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
2910 if (rc != LDAP_SUCCESS) {
2911 php_error_docref(NULL, E_WARNING, "Unable to set paged results control: %s (%d)", ldap_err2string(rc), rc);
2912 RETVAL_FALSE;
2913 goto lcpr_error_out;
2914 }
2915 RETVAL_TRUE;
2916 } else {
2917
2918 array_init(return_value);
2919
2920 add_assoc_string(return_value, "oid", ctrl.ldctl_oid);
2921 if (ctrl.ldctl_value.bv_len) {
2922 add_assoc_stringl(return_value, "value", ctrl.ldctl_value.bv_val, ctrl.ldctl_value.bv_len);
2923 }
2924 if (ctrl.ldctl_iscritical) {
2925 add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
2926 }
2927 }
2928
2929 lcpr_error_out:
2930 if (ber != NULL) {
2931 ber_free(ber, 1);
2932 }
2933 return;
2934 }
2935
2936
2937
2938
2939 PHP_FUNCTION(ldap_control_paged_result_response)
2940 {
2941 zval *link, *result, *cookie, *estimated;
2942 struct berval lcookie;
2943 int lestimated;
2944 ldap_linkdata *ld;
2945 LDAPMessage *ldap_result;
2946 LDAPControl **lserverctrls, *lctrl;
2947 BerElement *ber;
2948 ber_tag_t tag;
2949 int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
2950
2951 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|z/z/", &link, &result, &cookie, &estimated) != SUCCESS) {
2952 return;
2953 }
2954
2955 if ((ld = (ldap_linkdata *)zend_fetch_resource(Z_RES_P(link), "ldap link", le_link)) == NULL) {
2956 RETURN_FALSE;
2957 }
2958
2959 if ((ldap_result = (LDAPMessage *)zend_fetch_resource(Z_RES_P(result), "ldap result", le_result)) == NULL) {
2960 RETURN_FALSE;
2961 }
2962
2963 rc = ldap_parse_result(ld->link,
2964 ldap_result,
2965 &lerrcode,
2966 NULL,
2967 NULL,
2968 NULL,
2969 &lserverctrls,
2970 0);
2971
2972 if (rc != LDAP_SUCCESS) {
2973 php_error_docref(NULL, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
2974 RETURN_FALSE;
2975 }
2976
2977 if (lerrcode != LDAP_SUCCESS) {
2978 php_error_docref(NULL, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
2979 RETURN_FALSE;
2980 }
2981
2982 if (lserverctrls == NULL) {
2983 php_error_docref(NULL, E_WARNING, "No server controls in result");
2984 RETURN_FALSE;
2985 }
2986
2987 lctrl = ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, lserverctrls, NULL);
2988 if (lctrl == NULL) {
2989 ldap_controls_free(lserverctrls);
2990 php_error_docref(NULL, E_WARNING, "No paged results control response in result");
2991 RETURN_FALSE;
2992 }
2993
2994 ber = ber_init(&lctrl->ldctl_value);
2995 if (ber == NULL) {
2996 ldap_controls_free(lserverctrls);
2997 php_error_docref(NULL, E_WARNING, "Unable to alloc BER decoding resources for paged results control response");
2998 RETURN_FALSE;
2999 }
3000
3001 tag = ber_scanf(ber, "{io}", &lestimated, &lcookie);
3002 (void)ber_free(ber, 1);
3003
3004 if (tag == LBER_ERROR) {
3005 ldap_controls_free(lserverctrls);
3006 php_error_docref(NULL, E_WARNING, "Unable to decode paged results control response");
3007 RETURN_FALSE;
3008 }
3009
3010 if (lestimated < 0) {
3011 ldap_controls_free(lserverctrls);
3012 php_error_docref(NULL, E_WARNING, "Invalid paged results control response value");
3013 RETURN_FALSE;
3014 }
3015
3016 ldap_controls_free(lserverctrls);
3017 if (myargcount == 4) {
3018 zval_dtor(estimated);
3019 ZVAL_LONG(estimated, lestimated);
3020 }
3021
3022 zval_ptr_dtor(cookie);
3023 if (lcookie.bv_len == 0) {
3024 ZVAL_EMPTY_STRING(cookie);
3025 } else {
3026 ZVAL_STRINGL(cookie, lcookie.bv_val, lcookie.bv_len);
3027 }
3028 ldap_memfree(lcookie.bv_val);
3029
3030 RETURN_TRUE;
3031 }
3032
3033 #endif
3034
3035
3036 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0)
3037 ZEND_ARG_INFO(0, hostname)
3038 ZEND_ARG_INFO(0, port)
3039 #ifdef HAVE_ORALDAP
3040 ZEND_ARG_INFO(0, wallet)
3041 ZEND_ARG_INFO(0, wallet_passwd)
3042 ZEND_ARG_INFO(0, authmode)
3043 #endif
3044 ZEND_END_ARG_INFO()
3045
3046 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_resource, 0, 0, 1)
3047 ZEND_ARG_INFO(0, link_identifier)
3048 ZEND_END_ARG_INFO()
3049
3050 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_bind, 0, 0, 1)
3051 ZEND_ARG_INFO(0, link_identifier)
3052 ZEND_ARG_INFO(0, bind_rdn)
3053 ZEND_ARG_INFO(0, bind_password)
3054 ZEND_END_ARG_INFO()
3055
3056 #ifdef HAVE_LDAP_SASL
3057 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sasl_bind, 0, 0, 1)
3058 ZEND_ARG_INFO(0, link)
3059 ZEND_ARG_INFO(0, binddn)
3060 ZEND_ARG_INFO(0, password)
3061 ZEND_ARG_INFO(0, sasl_mech)
3062 ZEND_ARG_INFO(0, sasl_realm)
3063 ZEND_ARG_INFO(0, sasl_authz_id)
3064 ZEND_ARG_INFO(0, props)
3065 ZEND_END_ARG_INFO()
3066 #endif
3067
3068 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3)
3069 ZEND_ARG_INFO(0, link_identifier)
3070 ZEND_ARG_INFO(0, base_dn)
3071 ZEND_ARG_INFO(0, filter)
3072 ZEND_ARG_INFO(0, attributes)
3073 ZEND_ARG_INFO(0, attrsonly)
3074 ZEND_ARG_INFO(0, sizelimit)
3075 ZEND_ARG_INFO(0, timelimit)
3076 ZEND_ARG_INFO(0, deref)
3077 ZEND_END_ARG_INFO()
3078
3079 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_list, 0, 0, 3)
3080 ZEND_ARG_INFO(0, link_identifier)
3081 ZEND_ARG_INFO(0, base_dn)
3082 ZEND_ARG_INFO(0, filter)
3083 ZEND_ARG_INFO(0, attributes)
3084 ZEND_ARG_INFO(0, attrsonly)
3085 ZEND_ARG_INFO(0, sizelimit)
3086 ZEND_ARG_INFO(0, timelimit)
3087 ZEND_ARG_INFO(0, deref)
3088 ZEND_END_ARG_INFO()
3089
3090 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_search, 0, 0, 3)
3091 ZEND_ARG_INFO(0, link_identifier)
3092 ZEND_ARG_INFO(0, base_dn)
3093 ZEND_ARG_INFO(0, filter)
3094 ZEND_ARG_INFO(0, attributes)
3095 ZEND_ARG_INFO(0, attrsonly)
3096 ZEND_ARG_INFO(0, sizelimit)
3097 ZEND_ARG_INFO(0, timelimit)
3098 ZEND_ARG_INFO(0, deref)
3099 ZEND_END_ARG_INFO()
3100
3101 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_count_entries, 0, 0, 2)
3102 ZEND_ARG_INFO(0, link_identifier)
3103 ZEND_ARG_INFO(0, result_identifier)
3104 ZEND_END_ARG_INFO()
3105
3106 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_entry, 0, 0, 2)
3107 ZEND_ARG_INFO(0, link_identifier)
3108 ZEND_ARG_INFO(0, result_identifier)
3109 ZEND_END_ARG_INFO()
3110
3111 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_entry, 0, 0, 2)
3112 ZEND_ARG_INFO(0, link_identifier)
3113 ZEND_ARG_INFO(0, result_identifier)
3114 ZEND_END_ARG_INFO()
3115
3116 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_entries, 0, 0, 2)
3117 ZEND_ARG_INFO(0, link_identifier)
3118 ZEND_ARG_INFO(0, result_identifier)
3119 ZEND_END_ARG_INFO()
3120
3121 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_attribute, 0, 0, 2)
3122 ZEND_ARG_INFO(0, link_identifier)
3123 ZEND_ARG_INFO(0, result_entry_identifier)
3124 ZEND_END_ARG_INFO()
3125
3126 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_attribute, 0, 0, 2)
3127 ZEND_ARG_INFO(0, link_identifier)
3128 ZEND_ARG_INFO(0, result_entry_identifier)
3129 ZEND_END_ARG_INFO()
3130
3131 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_attributes, 0, 0, 2)
3132 ZEND_ARG_INFO(0, link_identifier)
3133 ZEND_ARG_INFO(0, result_entry_identifier)
3134 ZEND_END_ARG_INFO()
3135
3136 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_values, 0, 0, 3)
3137 ZEND_ARG_INFO(0, link_identifier)
3138 ZEND_ARG_INFO(0, result_entry_identifier)
3139 ZEND_ARG_INFO(0, attribute)
3140 ZEND_END_ARG_INFO()
3141
3142 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_values_len, 0, 0, 3)
3143 ZEND_ARG_INFO(0, link_identifier)
3144 ZEND_ARG_INFO(0, result_entry_identifier)
3145 ZEND_ARG_INFO(0, attribute)
3146 ZEND_END_ARG_INFO()
3147
3148 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_dn, 0, 0, 2)
3149 ZEND_ARG_INFO(0, link_identifier)
3150 ZEND_ARG_INFO(0, result_entry_identifier)
3151 ZEND_END_ARG_INFO()
3152
3153 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_explode_dn, 0, 0, 2)
3154 ZEND_ARG_INFO(0, dn)
3155 ZEND_ARG_INFO(0, with_attrib)
3156 ZEND_END_ARG_INFO()
3157
3158 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_dn2ufn, 0, 0, 1)
3159 ZEND_ARG_INFO(0, dn)
3160 ZEND_END_ARG_INFO()
3161
3162 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_add, 0, 0, 3)
3163 ZEND_ARG_INFO(0, link_identifier)
3164 ZEND_ARG_INFO(0, dn)
3165 ZEND_ARG_INFO(0, entry)
3166 ZEND_END_ARG_INFO()
3167
3168 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_delete, 0, 0, 2)
3169 ZEND_ARG_INFO(0, link_identifier)
3170 ZEND_ARG_INFO(0, dn)
3171 ZEND_END_ARG_INFO()
3172
3173 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify, 0, 0, 3)
3174 ZEND_ARG_INFO(0, link_identifier)
3175 ZEND_ARG_INFO(0, dn)
3176 ZEND_ARG_INFO(0, entry)
3177 ZEND_END_ARG_INFO()
3178
3179 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify_batch, 0, 0, 3)
3180 ZEND_ARG_INFO(0, link_identifier)
3181 ZEND_ARG_INFO(0, dn)
3182 ZEND_ARG_ARRAY_INFO(0, modifications_info, 0)
3183 ZEND_END_ARG_INFO()
3184
3185 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_add, 0, 0, 3)
3186 ZEND_ARG_INFO(0, link_identifier)
3187 ZEND_ARG_INFO(0, dn)
3188 ZEND_ARG_INFO(0, entry)
3189 ZEND_END_ARG_INFO()
3190
3191 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_replace, 0, 0, 3)
3192 ZEND_ARG_INFO(0, link_identifier)
3193 ZEND_ARG_INFO(0, dn)
3194 ZEND_ARG_INFO(0, entry)
3195 ZEND_END_ARG_INFO()
3196
3197 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_del, 0, 0, 3)
3198 ZEND_ARG_INFO(0, link_identifier)
3199 ZEND_ARG_INFO(0, dn)
3200 ZEND_ARG_INFO(0, entry)
3201 ZEND_END_ARG_INFO()
3202
3203 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_err2str, 0, 0, 1)
3204 ZEND_ARG_INFO(0, errno)
3205 ZEND_END_ARG_INFO()
3206
3207 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_compare, 0, 0, 4)
3208 ZEND_ARG_INFO(0, link_identifier)
3209 ZEND_ARG_INFO(0, dn)
3210 ZEND_ARG_INFO(0, attribute)
3211 ZEND_ARG_INFO(0, value)
3212 ZEND_END_ARG_INFO()
3213
3214 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_sort, 0, 0, 3)
3215 ZEND_ARG_INFO(0, link)
3216 ZEND_ARG_INFO(0, result)
3217 ZEND_ARG_INFO(0, sortfilter)
3218 ZEND_END_ARG_INFO()
3219
3220 #ifdef LDAP_CONTROL_PAGEDRESULTS
3221 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_paged_result, 0, 0, 2)
3222 ZEND_ARG_INFO(0, link)
3223 ZEND_ARG_INFO(0, pagesize)
3224 ZEND_ARG_INFO(0, iscritical)
3225 ZEND_ARG_INFO(0, cookie)
3226 ZEND_END_ARG_INFO();
3227
3228 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_paged_result_response, 0, 0, 2)
3229 ZEND_ARG_INFO(0, link)
3230 ZEND_ARG_INFO(0, result)
3231 ZEND_ARG_INFO(1, cookie)
3232 ZEND_ARG_INFO(1, estimated)
3233 ZEND_END_ARG_INFO();
3234 #endif
3235
3236 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
3237 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5)
3238 ZEND_ARG_INFO(0, link_identifier)
3239 ZEND_ARG_INFO(0, dn)
3240 ZEND_ARG_INFO(0, newrdn)
3241 ZEND_ARG_INFO(0, newparent)
3242 ZEND_ARG_INFO(0, deleteoldrdn)
3243 ZEND_END_ARG_INFO()
3244
3245 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_get_option, 0, 0, 3)
3246 ZEND_ARG_INFO(0, link_identifier)
3247 ZEND_ARG_INFO(0, option)
3248 ZEND_ARG_INFO(1, retval)
3249 ZEND_END_ARG_INFO()
3250
3251 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_option, 0, 0, 3)
3252 ZEND_ARG_INFO(0, link_identifier)
3253 ZEND_ARG_INFO(0, option)
3254 ZEND_ARG_INFO(0, newval)
3255 ZEND_END_ARG_INFO()
3256
3257 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_first_reference, 0, 0, 2)
3258 ZEND_ARG_INFO(0, link)
3259 ZEND_ARG_INFO(0, result)
3260 ZEND_END_ARG_INFO()
3261
3262 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_next_reference, 0, 0, 2)
3263 ZEND_ARG_INFO(0, link)
3264 ZEND_ARG_INFO(0, entry)
3265 ZEND_END_ARG_INFO()
3266
3267 #ifdef HAVE_LDAP_PARSE_REFERENCE
3268 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_reference, 0, 0, 3)
3269 ZEND_ARG_INFO(0, link)
3270 ZEND_ARG_INFO(0, entry)
3271 ZEND_ARG_INFO(1, referrals)
3272 ZEND_END_ARG_INFO()
3273 #endif
3274
3275
3276 #ifdef HAVE_LDAP_PARSE_RESULT
3277 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_parse_result, 0, 0, 3)
3278 ZEND_ARG_INFO(0, link)
3279 ZEND_ARG_INFO(0, result)
3280 ZEND_ARG_INFO(1, errcode)
3281 ZEND_ARG_INFO(1, matcheddn)
3282 ZEND_ARG_INFO(1, errmsg)
3283 ZEND_ARG_INFO(1, referrals)
3284 ZEND_END_ARG_INFO()
3285 #endif
3286 #endif
3287
3288 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
3289 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2)
3290 ZEND_ARG_INFO(0, link)
3291 ZEND_ARG_INFO(0, callback)
3292 ZEND_END_ARG_INFO()
3293 #endif
3294
3295 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_escape, 0, 0, 1)
3296 ZEND_ARG_INFO(0, value)
3297 ZEND_ARG_INFO(0, ignore)
3298 ZEND_ARG_INFO(0, flags)
3299 ZEND_END_ARG_INFO()
3300
3301 #ifdef STR_TRANSLATION
3302 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1)
3303 ZEND_ARG_INFO(0, value)
3304 ZEND_END_ARG_INFO()
3305
3306 ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_8859_to_t61, 0, 0, 1)
3307 ZEND_ARG_INFO(0, value)
3308 ZEND_END_ARG_INFO()
3309 #endif
3310
3311
3312
3313
3314
3315
3316
3317
3318 const zend_function_entry ldap_functions[] = {
3319 PHP_FE(ldap_connect, arginfo_ldap_connect)
3320 PHP_FALIAS(ldap_close, ldap_unbind, arginfo_ldap_resource)
3321 PHP_FE(ldap_bind, arginfo_ldap_bind)
3322 #ifdef HAVE_LDAP_SASL
3323 PHP_FE(ldap_sasl_bind, arginfo_ldap_sasl_bind)
3324 #endif
3325 PHP_FE(ldap_unbind, arginfo_ldap_resource)
3326 PHP_FE(ldap_read, arginfo_ldap_read)
3327 PHP_FE(ldap_list, arginfo_ldap_list)
3328 PHP_FE(ldap_search, arginfo_ldap_search)
3329 PHP_FE(ldap_free_result, arginfo_ldap_resource)
3330 PHP_FE(ldap_count_entries, arginfo_ldap_count_entries)
3331 PHP_FE(ldap_first_entry, arginfo_ldap_first_entry)
3332 PHP_FE(ldap_next_entry, arginfo_ldap_next_entry)
3333 PHP_FE(ldap_get_entries, arginfo_ldap_get_entries)
3334 PHP_FE(ldap_first_attribute, arginfo_ldap_first_attribute)
3335 PHP_FE(ldap_next_attribute, arginfo_ldap_next_attribute)
3336 PHP_FE(ldap_get_attributes, arginfo_ldap_get_attributes)
3337 PHP_FALIAS(ldap_get_values, ldap_get_values_len, arginfo_ldap_get_values)
3338 PHP_FE(ldap_get_values_len, arginfo_ldap_get_values_len)
3339 PHP_FE(ldap_get_dn, arginfo_ldap_get_dn)
3340 PHP_FE(ldap_explode_dn, arginfo_ldap_explode_dn)
3341 PHP_FE(ldap_dn2ufn, arginfo_ldap_dn2ufn)
3342 PHP_FE(ldap_add, arginfo_ldap_add)
3343 PHP_FE(ldap_delete, arginfo_ldap_delete)
3344 PHP_FE(ldap_modify_batch, arginfo_ldap_modify_batch)
3345 PHP_FALIAS(ldap_modify, ldap_mod_replace, arginfo_ldap_modify)
3346
3347
3348 PHP_FE(ldap_mod_add, arginfo_ldap_mod_add)
3349 PHP_FE(ldap_mod_replace, arginfo_ldap_mod_replace)
3350 PHP_FE(ldap_mod_del, arginfo_ldap_mod_del)
3351
3352
3353 PHP_FE(ldap_errno, arginfo_ldap_resource)
3354 PHP_FE(ldap_err2str, arginfo_ldap_err2str)
3355 PHP_FE(ldap_error, arginfo_ldap_resource)
3356 PHP_FE(ldap_compare, arginfo_ldap_compare)
3357 PHP_DEP_FE(ldap_sort, arginfo_ldap_sort)
3358
3359 #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
3360 PHP_FE(ldap_rename, arginfo_ldap_rename)
3361 PHP_FE(ldap_get_option, arginfo_ldap_get_option)
3362 PHP_FE(ldap_set_option, arginfo_ldap_set_option)
3363 PHP_FE(ldap_first_reference, arginfo_ldap_first_reference)
3364 PHP_FE(ldap_next_reference, arginfo_ldap_next_reference)
3365 #ifdef HAVE_LDAP_PARSE_REFERENCE
3366 PHP_FE(ldap_parse_reference, arginfo_ldap_parse_reference)
3367 #endif
3368 #ifdef HAVE_LDAP_PARSE_RESULT
3369 PHP_FE(ldap_parse_result, arginfo_ldap_parse_result)
3370 #endif
3371 #ifdef HAVE_LDAP_START_TLS_S
3372 PHP_FE(ldap_start_tls, arginfo_ldap_resource)
3373 #endif
3374 #endif
3375
3376 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
3377 PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
3378 #endif
3379
3380 PHP_FE(ldap_escape, arginfo_ldap_escape)
3381
3382 #ifdef STR_TRANSLATION
3383 PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
3384 PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)
3385 #endif
3386
3387 #ifdef LDAP_CONTROL_PAGEDRESULTS
3388 PHP_FE(ldap_control_paged_result, arginfo_ldap_control_paged_result)
3389 PHP_FE(ldap_control_paged_result_response, arginfo_ldap_control_paged_result_response)
3390 #endif
3391 PHP_FE_END
3392 };
3393
3394
3395 zend_module_entry ldap_module_entry = {
3396 STANDARD_MODULE_HEADER,
3397 "ldap",
3398 ldap_functions,
3399 PHP_MINIT(ldap),
3400 PHP_MSHUTDOWN(ldap),
3401 NULL,
3402 NULL,
3403 PHP_MINFO(ldap),
3404 PHP_LDAP_VERSION,
3405 PHP_MODULE_GLOBALS(ldap),
3406 PHP_GINIT(ldap),
3407 NULL,
3408 NULL,
3409 STANDARD_MODULE_PROPERTIES_EX
3410 };
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420