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