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