1999-04-22 00:45:14 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2019-01-30 09:03:12 +00:00
| Copyright ( c ) The PHP Group |
1999-04-22 00:45:14 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 13:13:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2021-05-06 10:16:35 +00:00
| https : //www.php.net/license/3_01.txt |
1999-07-16 13:13:16 +00:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
1999-04-22 00:45:14 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Amitay Isaacs < amitay @ w - o - i . com > |
| Eric Warnke < ericw @ albany . edu > |
2002-02-28 08:29:35 +00:00
| Rasmus Lerdorf < rasmus @ php . net > |
1999-05-21 10:06:25 +00:00
| Gerrit Thomson < 334647 @ swin . edu . au > |
2000-07-25 15:34:28 +00:00
| Jani Taskinen < sniper @ iki . fi > |
2000-08-26 16:20:37 +00:00
| Stig Venaas < venaas @ uninett . no > |
2007-03-22 21:50:34 +00:00
| Doug Goldstein < cardoe @ cardoe . com > |
2017-07-20 10:17:59 +00:00
| Côme Chilliet < mcmic @ php . net > |
2018-11-01 16:30:28 +00:00
| PHP 4.0 updates : Zeev Suraski < zeev @ php . net > |
1999-04-22 00:45:14 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2015-01-03 09:22:58 +00:00
2001-05-24 10:07:29 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
1999-04-22 00:45:14 +00:00
# include "php.h"
2000-04-01 16:23:39 +00:00
# include "php_ini.h"
2022-04-12 12:34:03 +00:00
# include "Zend/zend_attributes.h"
2008-06-02 08:46:41 +00:00
2002-11-05 14:18:20 +00:00
# include <stddef.h>
1999-04-23 03:28:47 +00:00
# include "ext/standard/dl.h"
1999-12-04 19:19:57 +00:00
# include "php_ldap.h"
1999-04-22 00:45:14 +00:00
2000-02-16 09:33:19 +00:00
# ifdef PHP_WIN32
1999-04-22 00:45:14 +00:00
# include <string.h>
2010-05-17 20:09:42 +00:00
# include "config.w32.h"
1999-04-22 00:45:14 +00:00
# undef WINDOWS
# undef strcasecmp
# undef strncasecmp
# define WINSOCK 1
# define __STDC__ 1
# endif
2000-04-06 16:57:33 +00:00
# include "ext/standard/info.h"
1999-04-22 00:45:14 +00:00
2019-06-05 12:57:09 +00:00
# ifdef HAVE_LDAP_SASL
2003-06-13 13:30:46 +00:00
# include <sasl/sasl.h>
# endif
2013-09-17 15:34:30 +00:00
# define PHP_LDAP_ESCAPE_FILTER 0x01
# define PHP_LDAP_ESCAPE_DN 0x02
2022-06-06 19:30:10 +00:00
# include "ldap_arginfo.h"
2015-08-18 14:52:44 +00:00
# if defined(LDAP_CONTROL_PAGEDRESULTS) && !defined(HAVE_LDAP_CONTROL_FIND)
2015-07-06 12:54:04 +00:00
LDAPControl * ldap_control_find ( const char * oid , LDAPControl * * ctrls , LDAPControl * * * nextctrlp )
{
2015-08-18 14:52:44 +00:00
assert ( nextctrlp = = NULL ) ;
return ldap_find_control ( oid , ctrls ) ;
}
# endif
# if !defined(LDAP_API_FEATURE_X_OPENLDAP)
void ldap_memvfree ( void * * v )
{
ldap_value_free ( ( char * * ) v ) ;
2015-07-06 12:54:04 +00:00
}
# endif
2001-11-29 20:17:17 +00:00
typedef struct {
LDAP * link ;
2015-08-18 14:52:44 +00:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
2014-05-20 03:26:26 +00:00
zval rebindproc ;
2001-11-29 20:26:20 +00:00
# endif
2021-03-13 11:11:40 +00:00
zend_object std ;
2001-11-29 20:17:17 +00:00
} ldap_linkdata ;
2021-03-13 11:11:40 +00:00
typedef struct {
LDAPMessage * result ;
zend_object std ;
} ldap_resultdata ;
2002-05-04 14:27:48 +00:00
typedef struct {
LDAPMessage * data ;
2014-05-20 03:26:26 +00:00
BerElement * ber ;
zval res ;
2021-03-13 11:11:40 +00:00
zend_object std ;
} ldap_result_entry ;
2002-05-04 14:27:48 +00:00
2000-04-01 16:23:39 +00:00
ZEND_DECLARE_MODULE_GLOBALS ( ldap )
2006-06-15 18:33:09 +00:00
static PHP_GINIT_FUNCTION ( ldap ) ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
static zend_class_entry * ldap_link_ce , * ldap_result_ce , * ldap_result_entry_ce ;
static zend_object_handlers ldap_link_object_handlers , ldap_result_object_handlers , ldap_result_entry_object_handlers ;
1999-04-22 00:45:14 +00:00
2000-05-23 09:33:51 +00:00
# ifdef COMPILE_DL_LDAP
2019-03-12 11:15:47 +00:00
# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE ( )
# endif
2000-05-02 00:30:36 +00:00
ZEND_GET_MODULE ( ldap )
1999-04-22 00:45:14 +00:00
# endif
2021-03-13 11:11:40 +00:00
static inline ldap_linkdata * ldap_link_from_obj ( zend_object * obj ) {
return ( ldap_linkdata * ) ( ( char * ) ( obj ) - XtOffsetOf ( ldap_linkdata , std ) ) ;
}
# define Z_LDAP_LINK_P(zv) ldap_link_from_obj(Z_OBJ_P(zv))
static zend_object * ldap_link_create_object ( zend_class_entry * class_type ) {
ldap_linkdata * intern = zend_object_alloc ( sizeof ( ldap_linkdata ) , class_type ) ;
zend_object_std_init ( & intern - > std , class_type ) ;
object_properties_init ( & intern - > std , class_type ) ;
return & intern - > std ;
}
static zend_function * ldap_link_get_constructor ( zend_object * object ) {
2022-12-16 11:16:38 +00:00
zend_throw_error ( NULL , " Cannot directly construct LDAP \\ Connection, use ldap_connect() instead " ) ;
2021-03-13 11:11:40 +00:00
return NULL ;
}
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
static void ldap_link_free ( ldap_linkdata * ld )
{
2019-06-25 13:49:28 +00:00
/* We use ldap_destroy rather than ldap_unbind here, because ldap_unbind
* will skip the destructor entirely if a critical client control is set . */
ldap_destroy ( ld - > link ) ;
2021-03-13 11:11:40 +00:00
ld - > link = NULL ;
2019-06-25 13:49:28 +00:00
2015-08-18 14:52:44 +00:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
2014-05-20 03:26:26 +00:00
zval_ptr_dtor ( & ld - > rebindproc ) ;
2001-11-29 20:26:20 +00:00
# endif
2015-04-16 15:11:38 +00:00
2000-04-01 16:23:39 +00:00
LDAPG ( num_links ) - - ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
static void ldap_link_free_obj ( zend_object * obj )
1999-04-22 00:45:14 +00:00
{
2021-03-13 11:11:40 +00:00
ldap_linkdata * ld = ldap_link_from_obj ( obj ) ;
if ( ld - > link ) {
ldap_link_free ( ld ) ;
}
zend_object_std_dtor ( & ld - > std ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
static inline ldap_resultdata * ldap_result_from_obj ( zend_object * obj ) {
return ( ldap_resultdata * ) ( ( char * ) ( obj ) - XtOffsetOf ( ldap_resultdata , std ) ) ;
}
# define Z_LDAP_RESULT_P(zv) ldap_result_from_obj(Z_OBJ_P(zv))
static zend_object * ldap_result_create_object ( zend_class_entry * class_type ) {
ldap_resultdata * intern = zend_object_alloc ( sizeof ( ldap_resultdata ) , class_type ) ;
zend_object_std_init ( & intern - > std , class_type ) ;
object_properties_init ( & intern - > std , class_type ) ;
return & intern - > std ;
}
static zend_function * ldap_result_get_constructor ( zend_object * object ) {
2021-05-09 20:20:21 +00:00
zend_throw_error ( NULL , " Cannot directly construct LDAP \\ Result, use the dedicated functions instead " ) ;
2021-03-13 11:11:40 +00:00
return NULL ;
}
static void ldap_result_free ( ldap_resultdata * result )
2002-05-04 14:27:48 +00:00
{
2021-03-13 11:11:40 +00:00
ldap_msgfree ( result - > result ) ;
result - > result = NULL ;
}
static void ldap_result_free_obj ( zend_object * obj )
{
ldap_resultdata * result = ldap_result_from_obj ( obj ) ;
if ( result - > result ) {
ldap_result_free ( result ) ;
}
zend_object_std_dtor ( & result - > std ) ;
}
static inline ldap_result_entry * ldap_result_entry_from_obj ( zend_object * obj ) {
return ( ldap_result_entry * ) ( ( char * ) ( obj ) - XtOffsetOf ( ldap_result_entry , std ) ) ;
}
# define Z_LDAP_RESULT_ENTRY_P(zv) ldap_result_entry_from_obj(Z_OBJ_P(zv))
static zend_object * ldap_result_entry_create_object ( zend_class_entry * class_type ) {
ldap_result_entry * intern = zend_object_alloc ( sizeof ( ldap_result_entry ) , class_type ) ;
zend_object_std_init ( & intern - > std , class_type ) ;
object_properties_init ( & intern - > std , class_type ) ;
return & intern - > std ;
}
static zend_function * ldap_result_entry_get_constructor ( zend_object * obj ) {
2021-05-09 20:20:21 +00:00
zend_throw_error ( NULL , " Cannot directly construct LDAP \\ ResultEntry, use the dedicated functions instead " ) ;
2021-03-13 11:11:40 +00:00
return NULL ;
}
static void ldap_result_entry_free_obj ( zend_object * obj )
{
ldap_result_entry * entry = ldap_result_entry_from_obj ( obj ) ;
2007-07-13 01:24:16 +00:00
if ( entry - > ber ! = NULL ) {
ber_free ( entry - > ber , 0 ) ;
2009-08-18 12:44:32 +00:00
entry - > ber = NULL ;
2007-07-13 01:24:16 +00:00
}
2014-05-20 03:26:26 +00:00
zval_ptr_dtor ( & entry - > res ) ;
2021-03-13 11:11:40 +00:00
zend_object_std_dtor ( & entry - > std ) ;
}
# define VERIFY_LDAP_LINK_CONNECTED(ld) \
{ \
if ( ! ld - > link ) { \
zend_throw_error ( NULL , " LDAP connection has already been closed " ) ; \
RETURN_THROWS ( ) ; \
} \
}
# define VERIFY_LDAP_RESULT_OPEN(lr) \
{ \
if ( ! lr - > result ) { \
zend_throw_error ( NULL , " LDAP result has already been closed " ) ; \
RETURN_THROWS ( ) ; \
} \
2015-01-03 09:22:58 +00:00
}
2002-05-04 14:27:48 +00:00
2017-07-20 10:17:59 +00:00
/* {{{ Parse controls from and to arrays */
2017-09-12 10:04:17 +00:00
static void _php_ldap_control_to_array ( LDAP * ld , LDAPControl * ctrl , zval * array , int request )
2017-07-20 10:17:59 +00:00
{
array_init ( array ) ;
add_assoc_string ( array , " oid " , ctrl - > ldctl_oid ) ;
2017-09-12 10:04:17 +00:00
if ( request ) {
/* iscritical field only makes sense in request controls (which may be obtained by ldap_get_option) */
add_assoc_bool ( array , " iscritical " , ( ctrl - > ldctl_iscritical ! = 0 ) ) ;
}
2017-07-20 10:17:59 +00:00
2019-08-20 11:58:22 +00:00
/* If it is a known oid, parse to values */
2017-07-20 10:17:59 +00:00
if ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_PASSWORDPOLICYRESPONSE ) = = 0 ) {
int expire = 0 , grace = 0 , rc ;
LDAPPasswordPolicyError pperr ;
zval value ;
rc = ldap_parse_passwordpolicy_control ( ld , ctrl , & expire , & grace , & pperr ) ;
if ( rc = = LDAP_SUCCESS ) {
array_init ( & value ) ;
add_assoc_long ( & value , " expire " , expire ) ;
add_assoc_long ( & value , " grace " , grace ) ;
if ( pperr ! = PP_noError ) {
add_assoc_long ( & value , " error " , pperr ) ;
}
add_assoc_zval ( array , " value " , & value ) ;
} else {
add_assoc_null ( array , " value " ) ;
}
} else if ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_PAGEDRESULTS ) = = 0 ) {
int lestimated , rc ;
2020-07-13 04:19:34 +00:00
struct berval lcookie = { 0L , NULL } ;
2017-07-20 10:17:59 +00:00
zval value ;
if ( ctrl - > ldctl_value . bv_len ) {
2020-07-13 04:19:34 +00:00
/* ldap_parse_pageresponse_control() allocates lcookie.bv_val */
2017-07-20 10:17:59 +00:00
rc = ldap_parse_pageresponse_control ( ld , ctrl , & lestimated , & lcookie ) ;
} else {
/* ldap_parse_pageresponse_control will crash if value is empty */
rc = - 1 ;
}
2020-07-13 04:19:34 +00:00
2017-07-20 10:17:59 +00:00
if ( rc = = LDAP_SUCCESS ) {
array_init ( & value ) ;
add_assoc_long ( & value , " size " , lestimated ) ;
add_assoc_stringl ( & value , " cookie " , lcookie . bv_val , lcookie . bv_len ) ;
add_assoc_zval ( array , " value " , & value ) ;
} else {
add_assoc_null ( array , " value " ) ;
}
2020-07-13 04:19:34 +00:00
if ( lcookie . bv_val ) {
ldap_memfree ( lcookie . bv_val ) ;
}
2017-09-12 07:53:49 +00:00
} else if ( ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_PRE_READ ) = = 0 ) | | ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_POST_READ ) = = 0 ) ) {
BerElement * ber ;
struct berval bv ;
ber = ber_init ( & ctrl - > ldctl_value ) ;
if ( ber = = NULL ) {
add_assoc_null ( array , " value " ) ;
} else if ( ber_scanf ( ber , " {m{ " /*}}*/ , & bv ) = = LBER_ERROR ) {
add_assoc_null ( array , " value " ) ;
} else {
zval value ;
array_init ( & value ) ;
add_assoc_stringl ( & value , " dn " , bv . bv_val , bv . bv_len ) ;
while ( ber_scanf ( ber , " {m " /*}*/ , & bv ) ! = LBER_ERROR ) {
int i ;
BerVarray vals = NULL ;
zval tmp ;
if ( ber_scanf ( ber , " [W] " , & vals ) = = LBER_ERROR | | vals = = NULL )
{
break ;
}
array_init ( & tmp ) ;
for ( i = 0 ; vals [ i ] . bv_val ! = NULL ; i + + ) {
add_next_index_stringl ( & tmp , vals [ i ] . bv_val , vals [ i ] . bv_len ) ;
}
add_assoc_zval ( & value , bv . bv_val , & tmp ) ;
ber_bvarray_free ( vals ) ;
}
add_assoc_zval ( array , " value " , & value ) ;
}
if ( ber ! = NULL ) {
ber_free ( ber , 1 ) ;
}
2017-09-14 12:55:42 +00:00
} else if ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_SORTRESPONSE ) = = 0 ) {
zval value ;
int errcode , rc ;
char * attribute ;
if ( ctrl - > ldctl_value . bv_len ) {
rc = ldap_parse_sortresponse_control ( ld , ctrl , & errcode , & attribute ) ;
} else {
rc = - 1 ;
}
if ( rc = = LDAP_SUCCESS ) {
array_init ( & value ) ;
add_assoc_long ( & value , " errcode " , errcode ) ;
if ( attribute ) {
add_assoc_string ( & value , " attribute " , attribute ) ;
ldap_memfree ( attribute ) ;
}
add_assoc_zval ( array , " value " , & value ) ;
} else {
add_assoc_null ( array , " value " ) ;
}
2017-09-14 13:50:05 +00:00
} else if ( strcmp ( ctrl - > ldctl_oid , LDAP_CONTROL_VLVRESPONSE ) = = 0 ) {
int target , count , errcode , rc ;
struct berval * context ;
zval value ;
if ( ctrl - > ldctl_value . bv_len ) {
rc = ldap_parse_vlvresponse_control ( ld , ctrl , & target , & count , & context , & errcode ) ;
} else {
rc = - 1 ;
}
if ( rc = = LDAP_SUCCESS ) {
array_init ( & value ) ;
add_assoc_long ( & value , " target " , target ) ;
add_assoc_long ( & value , " count " , count ) ;
add_assoc_long ( & value , " errcode " , errcode ) ;
2020-02-06 12:20:15 +00:00
if ( context ) {
2019-04-15 08:16:29 +00:00
add_assoc_stringl ( & value , " context " , context - > bv_val , context - > bv_len ) ;
}
2017-09-14 13:50:05 +00:00
add_assoc_zval ( array , " value " , & value ) ;
2019-08-29 16:01:34 +00:00
ber_bvfree ( context ) ;
2017-09-14 13:50:05 +00:00
} else {
add_assoc_null ( array , " value " ) ;
}
2017-07-20 10:17:59 +00:00
} else {
if ( ctrl - > ldctl_value . bv_len ) {
add_assoc_stringl ( array , " value " , ctrl - > ldctl_value . bv_val , ctrl - > ldctl_value . bv_len ) ;
} else {
add_assoc_null ( array , " value " ) ;
}
}
}
static int _php_ldap_control_from_array ( LDAP * ld , LDAPControl * * ctrl , zval * array )
{
zval * val ;
2019-06-14 09:11:24 +00:00
zend_string * control_oid ;
2017-09-07 09:04:52 +00:00
int control_iscritical = 0 , rc = LDAP_SUCCESS ;
2017-09-12 07:53:49 +00:00
char * * ldap_attrs = NULL ;
2017-09-14 12:55:42 +00:00
LDAPSortKey * * sort_keys = NULL ;
2020-07-03 00:11:44 +00:00
zend_string * tmpstring = NULL , * * tmpstrings1 = NULL , * * tmpstrings2 = NULL ;
size_t num_tmpstrings1 = 0 , num_tmpstrings2 = 0 ;
2017-07-20 10:17:59 +00:00
if ( ( val = zend_hash_str_find ( Z_ARRVAL_P ( array ) , " oid " , sizeof ( " oid " ) - 1 ) ) = = NULL ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Control must have an \" oid \" key " , get_active_function_name ( ) ) ;
2017-07-20 10:17:59 +00:00
return - 1 ;
}
2019-06-13 18:58:45 +00:00
control_oid = zval_get_string ( val ) ;
if ( EG ( exception ) ) {
return - 1 ;
}
2017-07-20 10:17:59 +00:00
if ( ( val = zend_hash_str_find ( Z_ARRVAL_P ( array ) , " iscritical " , sizeof ( " iscritical " ) - 1 ) ) ! = NULL ) {
2019-06-13 18:58:45 +00:00
control_iscritical = zend_is_true ( val ) ;
2017-07-20 10:17:59 +00:00
} else {
control_iscritical = 0 ;
}
2020-07-13 04:19:34 +00:00
BerElement * ber = NULL ;
struct berval control_value = { 0L , NULL } ;
int control_value_alloc = 0 ;
2017-07-20 10:17:59 +00:00
if ( ( val = zend_hash_str_find ( Z_ARRVAL_P ( array ) , " value " , sizeof ( " value " ) - 1 ) ) ! = NULL ) {
if ( Z_TYPE_P ( val ) ! = IS_ARRAY ) {
2020-07-13 04:19:34 +00:00
tmpstring = zval_get_string ( val ) ;
if ( EG ( exception ) ) {
2017-09-11 09:46:47 +00:00
rc = - 1 ;
2020-07-13 04:19:34 +00:00
goto failure ;
2017-07-20 10:17:59 +00:00
}
2020-07-13 04:19:34 +00:00
control_value . bv_val = ZSTR_VAL ( tmpstring ) ;
control_value . bv_len = ZSTR_LEN ( tmpstring ) ;
2019-06-13 18:58:45 +00:00
} else if ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_PAGEDRESULTS ) = = 0 ) {
2017-07-20 10:17:59 +00:00
zval * tmp ;
int pagesize = 1 ;
2020-07-13 04:19:34 +00:00
struct berval cookie = { 0L , NULL } ;
2017-07-20 10:17:59 +00:00
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " size " , sizeof ( " size " ) - 1 ) ) ! = NULL ) {
2017-12-07 16:24:55 +00:00
pagesize = zval_get_long ( tmp ) ;
2017-07-20 10:17:59 +00:00
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " cookie " , sizeof ( " cookie " ) - 1 ) ) ! = NULL ) {
2019-06-13 18:58:45 +00:00
tmpstring = zval_get_string ( tmp ) ;
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
cookie . bv_val = ZSTR_VAL ( tmpstring ) ;
cookie . bv_len = ZSTR_LEN ( tmpstring ) ;
2017-07-20 10:17:59 +00:00
}
2020-07-13 04:19:34 +00:00
/* ldap_create_page_control_value() allocates memory for control_value.bv_val */
control_value_alloc = 1 ;
rc = ldap_create_page_control_value ( ld , pagesize , & cookie , & control_value ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Failed to create paged result control value: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2017-07-20 10:17:59 +00:00
}
2019-06-13 18:58:45 +00:00
} else if ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_ASSERT ) = = 0 ) {
2017-07-26 09:51:29 +00:00
zval * tmp ;
2019-06-13 18:58:45 +00:00
zend_string * assert ;
2017-09-11 09:46:47 +00:00
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " filter " , sizeof ( " filter " ) - 1 ) ) = = NULL ) {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Control must have a \" filter \" key " , get_active_function_name ( ) ) ;
2017-09-11 09:46:47 +00:00
} else {
2019-06-13 18:58:45 +00:00
assert = zval_get_string ( tmp ) ;
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
2020-07-13 04:19:34 +00:00
/* ldap_create_assertion_control_value does not reset ld_errno, we need to do it ourselves
See http : //www.openldap.org/its/index.cgi/Incoming?id=8674 */
int success = LDAP_SUCCESS ;
ldap_set_option ( ld , LDAP_OPT_RESULT_CODE , & success ) ;
/* ldap_create_assertion_control_value() allocates memory for control_value.bv_val */
control_value_alloc = 1 ;
rc = ldap_create_assertion_control_value ( ld , ZSTR_VAL ( assert ) , & control_value ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Failed to create assert control value: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2017-07-26 09:51:29 +00:00
}
2019-06-14 09:11:24 +00:00
zend_string_release ( assert ) ;
2017-07-26 09:51:29 +00:00
}
2019-06-13 18:58:45 +00:00
} else if ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_VALUESRETURNFILTER ) = = 0 ) {
2017-09-11 09:37:55 +00:00
zval * tmp ;
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " filter " , sizeof ( " filter " ) - 1 ) ) = = NULL ) {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Control must have a \" filter \" key " , get_active_function_name ( ) ) ;
2017-09-11 09:37:55 +00:00
} else {
2020-07-13 04:19:34 +00:00
ber = ber_alloc_t ( LBER_USE_DER ) ;
if ( ber = = NULL ) {
2017-09-11 09:37:55 +00:00
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to allocate control value " ) ;
} else {
2019-06-13 18:58:45 +00:00
tmpstring = zval_get_string ( tmp ) ;
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
2020-07-13 04:19:34 +00:00
if ( ldap_put_vrFilter ( ber , ZSTR_VAL ( tmpstring ) ) = = - 1 ) {
2017-09-11 09:37:55 +00:00
rc = - 1 ;
2019-06-13 18:58:45 +00:00
php_error_docref ( NULL , E_WARNING , " Failed to create control value: Bad ValuesReturnFilter: %s " , ZSTR_VAL ( tmpstring ) ) ;
2020-07-13 04:19:34 +00:00
} else if ( ber_flatten2 ( ber , & control_value , control_value_alloc ) = = - 1 ) {
rc = - 1 ;
2017-09-11 09:37:55 +00:00
}
}
}
2019-06-13 18:58:45 +00:00
} else if ( ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_PRE_READ ) = = 0 ) | | ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_POST_READ ) = = 0 ) ) {
2017-09-12 07:53:49 +00:00
zval * tmp ;
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " attrs " , sizeof ( " attrs " ) - 1 ) ) = = NULL ) {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Control must have an \" attrs \" key " , get_active_function_name ( ) ) ;
2017-09-12 07:53:49 +00:00
} else {
2020-07-13 04:19:34 +00:00
ber = ber_alloc_t ( LBER_USE_DER ) ;
2017-09-12 07:53:49 +00:00
2020-07-13 04:19:34 +00:00
if ( ber = = NULL ) {
2017-09-12 07:53:49 +00:00
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to allocate control value " ) ;
} else {
int num_attribs , i ;
zval * attr ;
num_attribs = zend_hash_num_elements ( Z_ARRVAL_P ( tmp ) ) ;
ldap_attrs = safe_emalloc ( ( num_attribs + 1 ) , sizeof ( char * ) , 0 ) ;
2020-07-03 00:11:44 +00:00
tmpstrings1 = safe_emalloc ( num_attribs , sizeof ( zend_string * ) , 0 ) ;
num_tmpstrings1 = 0 ;
2017-09-12 07:53:49 +00:00
for ( i = 0 ; i < num_attribs ; i + + ) {
if ( ( attr = zend_hash_index_find ( Z_ARRVAL_P ( tmp ) , i ) ) = = NULL ) {
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to encode attribute list " ) ;
goto failure ;
}
2020-07-03 00:11:44 +00:00
tmpstrings1 [ num_tmpstrings1 ] = zval_get_string ( attr ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
2020-07-03 00:11:44 +00:00
ldap_attrs [ i ] = ZSTR_VAL ( tmpstrings1 [ num_tmpstrings1 ] ) ;
+ + num_tmpstrings1 ;
2017-09-12 07:53:49 +00:00
}
ldap_attrs [ num_attribs ] = NULL ;
ber_init2 ( ber , NULL , LBER_USE_DER ) ;
if ( ber_printf ( ber , " {v} " , ldap_attrs ) = = - 1 ) {
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to encode attribute list " ) ;
} else {
int err ;
2020-07-13 04:19:34 +00:00
err = ber_flatten2 ( ber , & control_value , control_value_alloc ) ;
2017-09-12 07:53:49 +00:00
if ( err < 0 ) {
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to encode control value (%d) " , err ) ;
}
}
}
}
2019-06-13 18:58:45 +00:00
} else if ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_SORTREQUEST ) = = 0 ) {
2017-09-14 12:55:42 +00:00
int num_keys , i ;
zval * sortkey , * tmp ;
num_keys = zend_hash_num_elements ( Z_ARRVAL_P ( val ) ) ;
sort_keys = safe_emalloc ( ( num_keys + 1 ) , sizeof ( LDAPSortKey * ) , 0 ) ;
2020-07-03 00:11:44 +00:00
tmpstrings1 = safe_emalloc ( num_keys , sizeof ( zend_string * ) , 0 ) ;
tmpstrings2 = safe_emalloc ( num_keys , sizeof ( zend_string * ) , 0 ) ;
num_tmpstrings1 = 0 ;
num_tmpstrings2 = 0 ;
2017-09-14 12:55:42 +00:00
for ( i = 0 ; i < num_keys ; i + + ) {
if ( ( sortkey = zend_hash_index_find ( Z_ARRVAL_P ( val ) , i ) ) = = NULL ) {
rc = - 1 ;
php_error_docref ( NULL , E_WARNING , " Failed to encode sort keys list " ) ;
goto failure ;
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( sortkey ) , " attr " , sizeof ( " attr " ) - 1 ) ) = = NULL ) {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Sort key list must have an \" attr \" key " , get_active_function_name ( ) ) ;
2017-09-14 12:55:42 +00:00
goto failure ;
}
sort_keys [ i ] = emalloc ( sizeof ( LDAPSortKey ) ) ;
2020-07-03 00:11:44 +00:00
tmpstrings1 [ num_tmpstrings1 ] = zval_get_string ( tmp ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
2020-07-03 00:11:44 +00:00
sort_keys [ i ] - > attributeType = ZSTR_VAL ( tmpstrings1 [ num_tmpstrings1 ] ) ;
+ + num_tmpstrings1 ;
2017-09-14 12:55:42 +00:00
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( sortkey ) , " oid " , sizeof ( " oid " ) - 1 ) ) ! = NULL ) {
2020-07-03 00:11:44 +00:00
tmpstrings2 [ num_tmpstrings2 ] = zval_get_string ( tmp ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
2020-07-03 00:11:44 +00:00
sort_keys [ i ] - > orderingRule = ZSTR_VAL ( tmpstrings2 [ num_tmpstrings2 ] ) ;
+ + num_tmpstrings2 ;
2017-09-14 12:55:42 +00:00
} else {
sort_keys [ i ] - > orderingRule = NULL ;
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( sortkey ) , " reverse " , sizeof ( " reverse " ) - 1 ) ) ! = NULL ) {
2019-06-13 18:58:45 +00:00
sort_keys [ i ] - > reverseOrder = zend_is_true ( tmp ) ;
2017-09-14 12:55:42 +00:00
} else {
sort_keys [ i ] - > reverseOrder = 0 ;
}
}
sort_keys [ num_keys ] = NULL ;
2020-07-13 04:19:34 +00:00
/* ldap_create_sort_control_value() allocates memory for control_value.bv_val */
control_value_alloc = 1 ;
rc = ldap_create_sort_control_value ( ld , sort_keys , & control_value ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Failed to create sort control value: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2017-09-14 12:55:42 +00:00
}
2019-06-13 18:58:45 +00:00
} else if ( strcmp ( ZSTR_VAL ( control_oid ) , LDAP_CONTROL_VLVREQUEST ) = = 0 ) {
2017-09-14 13:50:05 +00:00
zval * tmp ;
LDAPVLVInfo vlvInfo ;
struct berval attrValue ;
struct berval context ;
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " before " , sizeof ( " before " ) - 1 ) ) ! = NULL ) {
2017-12-07 16:24:55 +00:00
vlvInfo . ldvlv_before_count = zval_get_long ( tmp ) ;
2017-09-14 13:50:05 +00:00
} else {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Array value for VLV control must have a \" before \" key " , get_active_function_name ( ) ) ;
2017-09-14 13:50:05 +00:00
goto failure ;
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " after " , sizeof ( " after " ) - 1 ) ) ! = NULL ) {
2017-12-07 16:24:55 +00:00
vlvInfo . ldvlv_after_count = zval_get_long ( tmp ) ;
2017-09-14 13:50:05 +00:00
} else {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Array value for VLV control must have an \" after \" key " , get_active_function_name ( ) ) ;
2017-09-14 13:50:05 +00:00
goto failure ;
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " attrvalue " , sizeof ( " attrvalue " ) - 1 ) ) ! = NULL ) {
2019-06-13 18:58:45 +00:00
tmpstring = zval_get_string ( tmp ) ;
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
attrValue . bv_val = ZSTR_VAL ( tmpstring ) ;
attrValue . bv_len = ZSTR_LEN ( tmpstring ) ;
2017-09-14 13:50:05 +00:00
vlvInfo . ldvlv_attrvalue = & attrValue ;
} else if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " offset " , sizeof ( " offset " ) - 1 ) ) ! = NULL ) {
vlvInfo . ldvlv_attrvalue = NULL ;
2017-12-07 16:24:55 +00:00
vlvInfo . ldvlv_offset = zval_get_long ( tmp ) ;
2017-09-14 13:50:05 +00:00
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " count " , sizeof ( " count " ) - 1 ) ) ! = NULL ) {
2017-12-07 16:24:55 +00:00
vlvInfo . ldvlv_count = zval_get_long ( tmp ) ;
2017-09-14 13:50:05 +00:00
} else {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Array value for VLV control must have a \" count \" key " , get_active_function_name ( ) ) ;
2017-09-14 13:50:05 +00:00
goto failure ;
}
} else {
rc = - 1 ;
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Array value for VLV control must have either an \" attrvalue \" or an \" offset \" key " , get_active_function_name ( ) ) ;
2017-09-14 13:50:05 +00:00
goto failure ;
}
if ( ( tmp = zend_hash_str_find ( Z_ARRVAL_P ( val ) , " context " , sizeof ( " context " ) - 1 ) ) ! = NULL ) {
2019-06-13 18:58:45 +00:00
tmpstring = zval_get_string ( tmp ) ;
if ( EG ( exception ) ) {
rc = - 1 ;
goto failure ;
}
context . bv_val = ZSTR_VAL ( tmpstring ) ;
context . bv_len = ZSTR_LEN ( tmpstring ) ;
2017-09-14 13:50:05 +00:00
vlvInfo . ldvlv_context = & context ;
} else {
vlvInfo . ldvlv_context = NULL ;
}
2020-07-13 04:19:34 +00:00
/* ldap_create_vlv_control_value() allocates memory for control_value.bv_val */
control_value_alloc = 1 ;
rc = ldap_create_vlv_control_value ( ld , & vlvInfo , & control_value ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Failed to create VLV control value: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2017-09-14 13:50:05 +00:00
}
2017-07-20 10:17:59 +00:00
} else {
2020-09-03 14:21:36 +00:00
zend_type_error ( " %s(): Control OID %s cannot be of type array " , get_active_function_name ( ) , ZSTR_VAL ( control_oid ) ) ;
2017-09-07 09:04:52 +00:00
rc = - 1 ;
2017-07-20 10:17:59 +00:00
}
}
2017-09-07 09:04:52 +00:00
if ( rc = = LDAP_SUCCESS ) {
2020-07-13 04:19:34 +00:00
rc = ldap_control_create ( ZSTR_VAL ( control_oid ) , control_iscritical , & control_value , 1 , ctrl ) ;
2017-09-07 09:04:52 +00:00
}
2017-07-20 10:17:59 +00:00
2017-09-12 07:53:49 +00:00
failure :
2019-06-14 09:11:24 +00:00
zend_string_release ( control_oid ) ;
if ( tmpstring ! = NULL ) {
zend_string_release ( tmpstring ) ;
}
2020-07-03 00:11:44 +00:00
if ( tmpstrings1 ! = NULL ) {
int i ;
for ( i = 0 ; i < num_tmpstrings1 ; + + i ) {
zend_string_release ( tmpstrings1 [ i ] ) ;
}
efree ( tmpstrings1 ) ;
}
if ( tmpstrings2 ! = NULL ) {
int i ;
for ( i = 0 ; i < num_tmpstrings2 ; + + i ) {
zend_string_release ( tmpstrings2 [ i ] ) ;
}
efree ( tmpstrings2 ) ;
}
2020-07-13 04:19:34 +00:00
if ( control_value . bv_val ! = NULL & & control_value_alloc ! = 0 ) {
ber_memfree ( control_value . bv_val ) ;
}
if ( ber ! = NULL ) {
ber_free ( ber , 1 ) ;
2017-07-20 10:17:59 +00:00
}
2017-09-12 07:53:49 +00:00
if ( ldap_attrs ! = NULL ) {
efree ( ldap_attrs ) ;
}
2017-09-14 12:55:42 +00:00
if ( sort_keys ! = NULL ) {
LDAPSortKey * * sortp = sort_keys ;
while ( * sortp ) {
efree ( * sortp ) ;
sortp + + ;
}
efree ( sort_keys ) ;
sort_keys = NULL ;
}
2017-07-20 10:17:59 +00:00
if ( rc = = LDAP_SUCCESS ) {
return LDAP_SUCCESS ;
}
2019-08-20 11:58:22 +00:00
/* Failed */
2017-07-20 10:17:59 +00:00
* ctrl = NULL ;
return - 1 ;
}
2017-09-12 10:04:17 +00:00
static void _php_ldap_controls_to_array ( LDAP * ld , LDAPControl * * ctrls , zval * array , int request )
2017-07-20 10:17:59 +00:00
{
zval tmp1 ;
LDAPControl * * ctrlp ;
2019-01-07 11:28:51 +00:00
array = zend_try_array_init ( array ) ;
if ( ! array ) {
2020-01-03 21:40:16 +00:00
return ;
2019-01-07 11:28:51 +00:00
}
2017-07-20 10:17:59 +00:00
if ( ctrls = = NULL ) {
return ;
}
ctrlp = ctrls ;
while ( * ctrlp ! = NULL ) {
2017-09-12 10:04:17 +00:00
_php_ldap_control_to_array ( ld , * ctrlp , & tmp1 , request ) ;
2017-09-12 10:58:46 +00:00
add_assoc_zval ( array , ( * ctrlp ) - > ldctl_oid , & tmp1 ) ;
2017-07-20 10:17:59 +00:00
ctrlp + + ;
}
ldap_controls_free ( ctrls ) ;
}
2020-09-03 14:21:36 +00:00
static LDAPControl * * _php_ldap_controls_from_array ( LDAP * ld , zval * array , uint32_t arg_num )
2017-07-20 10:17:59 +00:00
{
int ncontrols ;
LDAPControl * * ctrlp , * * ctrls = NULL ;
zval * ctrlarray ;
int error = 0 ;
ncontrols = zend_hash_num_elements ( Z_ARRVAL_P ( array ) ) ;
ctrls = safe_emalloc ( ( 1 + ncontrols ) , sizeof ( * ctrls ) , 0 ) ;
* ctrls = NULL ;
ctrlp = ctrls ;
ZEND_HASH_FOREACH_VAL ( Z_ARRVAL_P ( array ) , ctrlarray ) {
if ( Z_TYPE_P ( ctrlarray ) ! = IS_ARRAY ) {
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( arg_num , " must contain only arrays, where each array is a control " ) ;
2017-07-20 10:17:59 +00:00
error = 1 ;
break ;
}
if ( _php_ldap_control_from_array ( ld , ctrlp , ctrlarray ) = = LDAP_SUCCESS ) {
+ + ctrlp ;
} else {
error = 1 ;
break ;
}
* ctrlp = NULL ;
} ZEND_HASH_FOREACH_END ( ) ;
if ( error ) {
ctrlp = ctrls ;
while ( * ctrlp ) {
ldap_control_free ( * ctrlp ) ;
ctrlp + + ;
}
efree ( ctrls ) ;
ctrls = NULL ;
}
return ctrls ;
}
2017-07-26 14:41:44 +00:00
static void _php_ldap_controls_free ( LDAPControl * * * ctrls )
{
LDAPControl * * ctrlp ;
if ( * ctrls ) {
ctrlp = * ctrls ;
while ( * ctrlp ) {
ldap_control_free ( * ctrlp ) ;
ctrlp + + ;
}
efree ( * ctrls ) ;
* ctrls = NULL ;
}
}
2017-07-20 10:17:59 +00:00
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ PHP_INI_BEGIN */
2000-04-01 16:23:39 +00:00
PHP_INI_BEGIN ( )
2003-06-08 23:34:51 +00:00
STD_PHP_INI_ENTRY_EX ( " ldap.max_links " , " -1 " , PHP_INI_SYSTEM , OnUpdateLong , max_links , zend_ldap_globals , ldap_globals , display_link_numbers )
2000-04-01 16:23:39 +00:00
PHP_INI_END ( )
2001-06-05 13:12:10 +00:00
/* }}} */
1999-04-22 00:45:14 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ PHP_GINIT_FUNCTION */
2006-06-15 18:33:09 +00:00
static PHP_GINIT_FUNCTION ( ldap )
1999-04-22 00:45:14 +00:00
{
2019-03-12 11:15:47 +00:00
# if defined(COMPILE_DL_LDAP) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE ( ) ;
# endif
2000-04-01 16:23:39 +00:00
ldap_globals - > num_links = 0 ;
1999-04-22 00:45:14 +00:00
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-04-22 00:45:14 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ PHP_MINIT_FUNCTION */
1999-08-02 15:02:52 +00:00
PHP_MINIT_FUNCTION ( ldap )
1999-04-22 00:45:14 +00:00
{
2000-04-01 16:23:39 +00:00
REGISTER_INI_ENTRIES ( ) ;
1999-04-22 00:45:14 +00:00
2021-05-09 20:20:21 +00:00
ldap_link_ce = register_class_LDAP_Connection ( ) ;
2021-03-13 11:11:40 +00:00
ldap_link_ce - > create_object = ldap_link_create_object ;
2022-08-24 16:41:34 +00:00
ldap_link_ce - > default_object_handlers = & ldap_link_object_handlers ;
2021-03-13 11:11:40 +00:00
memcpy ( & ldap_link_object_handlers , & std_object_handlers , sizeof ( zend_object_handlers ) ) ;
ldap_link_object_handlers . offset = XtOffsetOf ( ldap_linkdata , std ) ;
ldap_link_object_handlers . free_obj = ldap_link_free_obj ;
ldap_link_object_handlers . get_constructor = ldap_link_get_constructor ;
ldap_link_object_handlers . clone_obj = NULL ;
ldap_link_object_handlers . compare = zend_objects_not_comparable ;
2021-05-09 20:20:21 +00:00
ldap_result_ce = register_class_LDAP_Result ( ) ;
2021-03-13 11:11:40 +00:00
ldap_result_ce - > create_object = ldap_result_create_object ;
2022-08-24 16:41:34 +00:00
ldap_result_ce - > default_object_handlers = & ldap_result_object_handlers ;
2021-03-13 11:11:40 +00:00
memcpy ( & ldap_result_object_handlers , & std_object_handlers , sizeof ( zend_object_handlers ) ) ;
ldap_result_object_handlers . offset = XtOffsetOf ( ldap_resultdata , std ) ;
ldap_result_object_handlers . free_obj = ldap_result_free_obj ;
ldap_result_object_handlers . get_constructor = ldap_result_get_constructor ;
ldap_result_object_handlers . clone_obj = NULL ;
ldap_result_object_handlers . compare = zend_objects_not_comparable ;
2021-05-09 20:20:21 +00:00
ldap_result_entry_ce = register_class_LDAP_ResultEntry ( ) ;
2021-03-13 11:11:40 +00:00
ldap_result_entry_ce - > create_object = ldap_result_entry_create_object ;
2022-08-24 16:41:34 +00:00
ldap_result_entry_ce - > default_object_handlers = & ldap_result_entry_object_handlers ;
2021-03-13 11:11:40 +00:00
memcpy ( & ldap_result_entry_object_handlers , & std_object_handlers , sizeof ( zend_object_handlers ) ) ;
ldap_result_entry_object_handlers . offset = XtOffsetOf ( ldap_result_entry , std ) ;
ldap_result_entry_object_handlers . free_obj = ldap_result_entry_free_obj ;
ldap_result_entry_object_handlers . get_constructor = ldap_result_entry_get_constructor ;
ldap_result_entry_object_handlers . clone_obj = NULL ;
ldap_result_entry_object_handlers . compare = zend_objects_not_comparable ;
2022-06-06 19:30:10 +00:00
register_ldap_symbols ( module_number ) ;
2017-07-05 12:19:09 +00:00
2014-05-20 03:26:26 +00:00
ldap_module_entry . type = type ;
1999-04-22 00:45:14 +00:00
return SUCCESS ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-04-22 00:45:14 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ PHP_MSHUTDOWN_FUNCTION */
1999-08-02 15:02:52 +00:00
PHP_MSHUTDOWN_FUNCTION ( ldap )
{
2004-05-12 10:15:48 +00:00
UNREGISTER_INI_ENTRIES ( ) ;
1999-04-22 00:45:14 +00:00
return SUCCESS ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
1999-04-22 00:45:14 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ PHP_MINFO_FUNCTION */
1999-08-02 15:02:52 +00:00
PHP_MINFO_FUNCTION ( ldap )
1999-04-22 00:45:14 +00:00
{
2000-06-05 15:17:25 +00:00
char tmp [ 32 ] ;
2000-04-03 22:00:18 +00:00
2001-12-25 14:36:06 +00:00
php_info_print_table_start ( ) ;
2003-06-08 23:34:51 +00:00
php_info_print_table_row ( 2 , " LDAP Support " , " enabled " ) ;
2000-04-03 22:00:18 +00:00
2000-04-01 16:23:39 +00:00
if ( LDAPG ( max_links ) = = - 1 ) {
2014-08-25 18:22:49 +00:00
snprintf ( tmp , 31 , ZEND_LONG_FMT " /unlimited " , LDAPG ( num_links ) ) ;
1999-04-22 00:45:14 +00:00
} else {
2014-08-25 18:22:49 +00:00
snprintf ( tmp , 31 , ZEND_LONG_FMT " / " ZEND_LONG_FMT , LDAPG ( num_links ) , LDAPG ( max_links ) ) ;
1999-04-22 00:45:14 +00:00
}
2001-12-25 14:36:06 +00:00
php_info_print_table_row ( 2 , " Total Links " , tmp ) ;
2001-05-31 21:09:30 +00:00
2000-08-07 03:18:00 +00:00
# ifdef LDAP_API_VERSION
2001-12-25 14:36:06 +00:00
snprintf ( tmp , 31 , " %d " , LDAP_API_VERSION ) ;
php_info_print_table_row ( 2 , " API Version " , tmp ) ;
# endif
# ifdef LDAP_VENDOR_NAME
php_info_print_table_row ( 2 , " Vendor Name " , LDAP_VENDOR_NAME ) ;
# endif
2008-06-02 11:23:16 +00:00
2001-12-25 14:36:06 +00:00
# ifdef LDAP_VENDOR_VERSION
snprintf ( tmp , 31 , " %d " , LDAP_VENDOR_VERSION ) ;
php_info_print_table_row ( 2 , " Vendor Version " , tmp ) ;
2000-08-07 03:18:00 +00:00
# endif
2000-04-06 21:17:50 +00:00
2003-06-13 13:30:46 +00:00
# ifdef HAVE_LDAP_SASL
php_info_print_table_row ( 2 , " SASL Support " , " Enabled " ) ;
# endif
2000-04-06 21:17:50 +00:00
php_info_print_table_end ( ) ;
2008-12-12 13:07:28 +00:00
DISPLAY_INI_ENTRIES ( ) ;
1999-04-22 00:45:14 +00:00
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-07-23 21:32:02 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Connect to an LDAP server */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_connect )
1999-04-22 00:45:14 +00:00
{
2001-11-13 18:05:47 +00:00
char * host = NULL ;
2015-06-17 12:48:19 +00:00
size_t hostlen = 0 ;
2015-06-23 13:50:14 +00:00
zend_long port = LDAP_PORT ;
2000-08-20 18:47:14 +00:00
# ifdef HAVE_ORALDAP
2007-04-30 21:40:02 +00:00
char * wallet = NULL , * walletpasswd = NULL ;
2014-08-27 13:31:48 +00:00
size_t walletlen = 0 , walletpasswdlen = 0 ;
2014-08-25 17:24:55 +00:00
zend_long authmode = GSLC_SSL_NO_AUTH ;
2000-08-20 18:47:14 +00:00
int ssl = 0 ;
# endif
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2015-04-16 15:11:38 +00:00
LDAP * ldap = NULL ;
1999-04-22 00:45:14 +00:00
2000-08-20 18:47:14 +00:00
# ifdef HAVE_ORALDAP
2002-08-05 21:14:14 +00:00
if ( ZEND_NUM_ARGS ( ) = = 3 | | ZEND_NUM_ARGS ( ) = = 4 ) {
WRONG_PARAM_COUNT ;
}
2000-08-20 18:47:14 +00:00
2020-09-17 14:03:43 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |s!lssl " , & host , & hostlen , & port , & wallet , & walletlen , & walletpasswd , & walletpasswdlen , & authmode ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2002-08-05 21:14:14 +00:00
}
1999-04-22 00:45:14 +00:00
2003-06-08 23:34:51 +00:00
if ( ZEND_NUM_ARGS ( ) = = 5 ) {
2002-08-05 21:14:14 +00:00
ssl = 1 ;
1999-04-22 00:45:14 +00:00
}
2002-08-05 21:14:14 +00:00
# else
2020-09-17 14:03:43 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |s!l " , & host , & hostlen , & port ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2002-08-05 21:14:14 +00:00
}
# endif
1999-04-22 00:45:14 +00:00
2001-05-31 21:09:30 +00:00
if ( LDAPG ( max_links ) ! = - 1 & & LDAPG ( num_links ) > = LDAPG ( max_links ) ) {
2016-06-21 13:00:37 +00:00
php_error_docref ( NULL , E_WARNING , " Too many open links ( " ZEND_LONG_FMT " ) " , LDAPG ( num_links ) ) ;
2000-04-01 16:23:39 +00:00
RETURN_FALSE ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_link_ce ) ;
ld = Z_LDAP_LINK_P ( return_value ) ;
2001-11-29 20:17:17 +00:00
2015-04-16 15:11:38 +00:00
{
2015-08-18 14:52:44 +00:00
int rc = LDAP_SUCCESS ;
2015-04-16 15:11:38 +00:00
char * url = host ;
2017-05-25 00:41:12 +00:00
if ( url & & ! ldap_is_ldap_url ( url ) ) {
2017-07-25 15:56:05 +00:00
size_t urllen = hostlen + sizeof ( " ldap://:65535 " ) ;
2015-04-16 15:11:38 +00:00
if ( port < = 0 | | port > 65535 ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 2 , " must be between 1 and 65535 " ) ;
RETURN_THROWS ( ) ;
2015-04-16 15:11:38 +00:00
}
url = emalloc ( urllen ) ;
2017-05-25 00:41:12 +00:00
snprintf ( url , urllen , " ldap://%s: " ZEND_LONG_FMT , host , port ) ;
2015-04-16 15:11:38 +00:00
}
2015-01-03 09:22:58 +00:00
2015-08-18 14:52:44 +00:00
# ifdef LDAP_API_FEATURE_X_OPENLDAP
/* ldap_init() is deprecated, use ldap_initialize() instead.
*/
2015-04-16 15:11:38 +00:00
rc = ldap_initialize ( & ldap , url ) ;
2015-08-18 14:52:44 +00:00
# else /* ! LDAP_API_FEATURE_X_OPENLDAP */
/* ldap_init does not support URLs.
* We must try the original host and port information .
*/
ldap = ldap_init ( host , port ) ;
if ( ldap = = NULL ) {
2021-03-13 11:11:40 +00:00
zval_ptr_dtor ( return_value ) ;
2015-08-18 15:26:46 +00:00
php_error_docref ( NULL , E_WARNING , " Could not create session handle " ) ;
2015-08-18 14:52:44 +00:00
RETURN_FALSE ;
}
# endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
2015-04-16 15:11:38 +00:00
if ( url ! = host ) {
efree ( url ) ;
}
2000-10-20 20:22:59 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2021-03-13 11:11:40 +00:00
zval_ptr_dtor ( return_value ) ;
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Could not create session handle: %s " , ldap_err2string ( rc ) ) ;
2000-10-20 20:22:59 +00:00
RETURN_FALSE ;
}
}
2015-01-03 09:22:58 +00:00
2003-06-08 23:34:51 +00:00
if ( ldap = = NULL ) {
2021-03-13 11:11:40 +00:00
zval_ptr_dtor ( return_value ) ;
2000-04-01 16:23:39 +00:00
RETURN_FALSE ;
1999-04-22 00:45:14 +00:00
} else {
2000-08-20 18:47:14 +00:00
# ifdef HAVE_ORALDAP
if ( ssl ) {
2001-05-31 21:09:30 +00:00
if ( ldap_init_SSL ( & ldap - > ld_sb , wallet , walletpasswd , authmode ) ) {
2021-03-13 11:11:40 +00:00
zval_ptr_dtor ( return_value ) ;
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " SSL init failed " ) ;
2000-08-20 18:47:14 +00:00
RETURN_FALSE ;
}
2015-01-03 09:22:58 +00:00
}
2000-08-20 18:47:14 +00:00
# endif
2001-05-31 21:09:30 +00:00
LDAPG ( num_links ) + + ;
2001-11-29 20:17:17 +00:00
ld - > link = ldap ;
1999-04-22 00:45:14 +00:00
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ _get_lderrno */
2000-08-26 16:20:37 +00:00
static int _get_lderrno ( LDAP * ldap )
{
2020-05-15 22:30:38 +00:00
# if LDAP_API_VERSION > 2000 || defined(HAVE_ORALDAP)
2000-08-26 16:20:37 +00:00
int lderr ;
/* New versions of OpenLDAP do it this way */
ldap_get_option ( ldap , LDAP_OPT_ERROR_NUMBER , & lderr ) ;
return lderr ;
# else
return ldap - > ld_errno ;
# endif
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-08-26 16:20:37 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ _set_lderrno */
2014-09-28 04:49:35 +00:00
static void _set_lderrno ( LDAP * ldap , int lderr )
{
2020-05-15 22:30:38 +00:00
# if LDAP_API_VERSION > 2000 || defined(HAVE_ORALDAP)
2014-09-28 04:49:35 +00:00
/* New versions of OpenLDAP do it this way */
ldap_set_option ( ldap , LDAP_OPT_ERROR_NUMBER , & lderr ) ;
# else
ldap - > ld_errno = lderr ;
# endif
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Bind to LDAP directory */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_bind )
1999-04-22 00:45:14 +00:00
{
2002-08-05 21:14:14 +00:00
zval * link ;
char * ldap_bind_dn = NULL , * ldap_bind_pw = NULL ;
2014-08-27 13:31:48 +00:00
size_t ldap_bind_dnlen , ldap_bind_pwlen ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2002-06-26 06:49:25 +00:00
int rc ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O|s!s! " , & link , ldap_link_ce , & ldap_bind_dn , & ldap_bind_dnlen , & ldap_bind_pw , & ldap_bind_pwlen ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2002-08-05 21:14:14 +00:00
}
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2014-09-28 04:49:35 +00:00
2014-04-14 03:43:46 +00:00
if ( ldap_bind_dn ! = NULL & & memchr ( ldap_bind_dn , ' \0 ' , ldap_bind_dnlen ) ! = NULL ) {
2014-09-28 04:49:35 +00:00
_set_lderrno ( ld - > link , LDAP_INVALID_CREDENTIALS ) ;
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 2 , " must not contain null bytes " ) ;
RETURN_THROWS ( ) ;
2014-04-14 03:43:46 +00:00
}
if ( ldap_bind_pw ! = NULL & & memchr ( ldap_bind_pw , ' \0 ' , ldap_bind_pwlen ) ! = NULL ) {
2014-09-28 04:49:35 +00:00
_set_lderrno ( ld - > link , LDAP_INVALID_CREDENTIALS ) ;
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 3 , " must not contain null bytes " ) ;
RETURN_THROWS ( ) ;
2014-04-14 03:43:46 +00:00
}
2015-04-16 15:11:38 +00:00
{
2015-08-18 14:52:44 +00:00
# ifdef LDAP_API_FEATURE_X_OPENLDAP
/* ldap_simple_bind_s() is deprecated, use ldap_sasl_bind_s() instead.
*/
2015-04-16 15:11:38 +00:00
struct berval cred ;
cred . bv_val = ldap_bind_pw ;
cred . bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0 ;
rc = ldap_sasl_bind_s ( ld - > link , ldap_bind_dn , LDAP_SASL_SIMPLE , & cred ,
NULL , NULL , /* no controls right now */
NULL ) ; /* we don't care about the server's credentials */
2015-08-18 14:52:44 +00:00
# else /* ! LDAP_API_FEATURE_X_OPENLDAP */
rc = ldap_simple_bind_s ( ld - > link , ldap_bind_dn , ldap_bind_pw ) ;
# endif /* ! LDAP_API_FEATURE_X_OPENLDAP */
2015-04-16 15:11:38 +00:00
}
if ( rc ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Unable to bind to server: %s " , ldap_err2string ( rc ) ) ;
1999-04-22 00:45:14 +00:00
RETURN_FALSE ;
} else {
RETURN_TRUE ;
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Bind to LDAP directory */
2017-09-11 13:38:32 +00:00
PHP_FUNCTION ( ldap_bind_ext )
{
zval * serverctrls = NULL ;
zval * link ;
char * ldap_bind_dn = NULL , * ldap_bind_pw = NULL ;
size_t ldap_bind_dnlen , ldap_bind_pwlen ;
ldap_linkdata * ld ;
LDAPControl * * lserverctrls = NULL ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2017-09-11 13:38:32 +00:00
LDAPMessage * ldap_res ;
int rc ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O|s!s!a! " , & link , ldap_link_ce , & ldap_bind_dn , & ldap_bind_dnlen , & ldap_bind_pw , & ldap_bind_pwlen , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-09-11 13:38:32 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-09-11 13:38:32 +00:00
if ( ldap_bind_dn ! = NULL & & memchr ( ldap_bind_dn , ' \0 ' , ldap_bind_dnlen ) ! = NULL ) {
_set_lderrno ( ld - > link , LDAP_INVALID_CREDENTIALS ) ;
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 2 , " must not contain null bytes " ) ;
RETURN_THROWS ( ) ;
2017-09-11 13:38:32 +00:00
}
if ( ldap_bind_pw ! = NULL & & memchr ( ldap_bind_pw , ' \0 ' , ldap_bind_pwlen ) ! = NULL ) {
_set_lderrno ( ld - > link , LDAP_INVALID_CREDENTIALS ) ;
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 3 , " must not contain null bytes " ) ;
RETURN_THROWS ( ) ;
2017-09-11 13:38:32 +00:00
}
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 4 ) ;
2017-09-11 13:38:32 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
{
/* ldap_simple_bind() is deprecated, use ldap_sasl_bind() instead */
struct berval cred ;
int msgid ;
cred . bv_val = ldap_bind_pw ;
cred . bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0 ;
/* asynchronous call */
rc = ldap_sasl_bind ( ld - > link , ldap_bind_dn , LDAP_SASL_SIMPLE , & cred ,
lserverctrls , NULL , & msgid ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Unable to bind to server: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
RETVAL_FALSE ;
goto cleanup ;
}
rc = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( rc = = - 1 ) {
php_error_docref ( NULL , E_WARNING , " Bind operation failed " ) ;
RETVAL_FALSE ;
goto cleanup ;
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2017-09-11 13:38:32 +00:00
}
cleanup :
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
return ;
}
/* }}} */
2003-06-13 13:30:46 +00:00
# ifdef HAVE_LDAP_SASL
2005-04-17 16:25:59 +00:00
typedef struct {
char * mech ;
char * realm ;
char * authcid ;
char * passwd ;
char * authzid ;
} php_ldap_bictx ;
2020-07-01 13:32:55 +00:00
/* {{{ _php_sasl_setdefs */
2007-07-12 22:08:58 +00:00
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 )
2005-04-17 16:25:59 +00:00
{
php_ldap_bictx * ctx ;
2015-01-03 09:22:58 +00:00
ctx = ber_memalloc ( sizeof ( php_ldap_bictx ) ) ;
2005-04-17 16:25:59 +00:00
ctx - > mech = ( sasl_mech ) ? ber_strdup ( sasl_mech ) : NULL ;
ctx - > realm = ( sasl_realm ) ? ber_strdup ( sasl_realm ) : NULL ;
2007-07-12 22:08:58 +00:00
ctx - > authcid = ( sasl_authc_id ) ? ber_strdup ( sasl_authc_id ) : NULL ;
ctx - > passwd = ( passwd ) ? ber_strdup ( passwd ) : NULL ;
2005-04-17 16:25:59 +00:00
ctx - > authzid = ( sasl_authz_id ) ? ber_strdup ( sasl_authz_id ) : NULL ;
if ( ctx - > mech = = NULL ) {
ldap_get_option ( ld , LDAP_OPT_X_SASL_MECH , & ctx - > mech ) ;
}
if ( ctx - > realm = = NULL ) {
ldap_get_option ( ld , LDAP_OPT_X_SASL_REALM , & ctx - > realm ) ;
}
if ( ctx - > authcid = = NULL ) {
ldap_get_option ( ld , LDAP_OPT_X_SASL_AUTHCID , & ctx - > authcid ) ;
}
if ( ctx - > authzid = = NULL ) {
ldap_get_option ( ld , LDAP_OPT_X_SASL_AUTHZID , & ctx - > authzid ) ;
}
return ctx ;
}
2005-12-11 22:38:38 +00:00
/* }}} */
2005-04-17 16:25:59 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ _php_sasl_freedefs */
2005-04-17 16:25:59 +00:00
static void _php_sasl_freedefs ( php_ldap_bictx * ctx )
{
if ( ctx - > mech ) ber_memfree ( ctx - > mech ) ;
if ( ctx - > realm ) ber_memfree ( ctx - > realm ) ;
if ( ctx - > authcid ) ber_memfree ( ctx - > authcid ) ;
if ( ctx - > passwd ) ber_memfree ( ctx - > passwd ) ;
if ( ctx - > authzid ) ber_memfree ( ctx - > authzid ) ;
ber_memfree ( ctx ) ;
}
2005-12-11 22:38:38 +00:00
/* }}} */
2005-04-17 16:25:59 +00:00
2003-06-08 23:44:01 +00:00
/* {{{ _php_sasl_interact
2005-04-17 16:25:59 +00:00
Internal interact function for SASL */
2003-06-08 23:44:01 +00:00
static int _php_sasl_interact ( LDAP * ld , unsigned flags , void * defaults , void * in )
{
sasl_interact_t * interact = in ;
2005-04-17 16:25:59 +00:00
const char * p ;
php_ldap_bictx * ctx = defaults ;
for ( ; interact - > id ! = SASL_CB_LIST_END ; interact + + ) {
p = NULL ;
switch ( interact - > id ) {
case SASL_CB_GETREALM :
p = ctx - > realm ;
break ;
case SASL_CB_AUTHNAME :
p = ctx - > authcid ;
break ;
case SASL_CB_USER :
p = ctx - > authzid ;
break ;
case SASL_CB_PASS :
p = ctx - > passwd ;
break ;
}
if ( p ) {
interact - > result = p ;
interact - > len = strlen ( interact - > result ) ;
}
}
2003-06-08 23:44:01 +00:00
return LDAP_SUCCESS ;
}
2005-12-11 22:38:38 +00:00
/* }}} */
2003-06-08 23:44:01 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Bind to LDAP directory using SASL */
2003-06-08 23:44:01 +00:00
PHP_FUNCTION ( ldap_sasl_bind )
{
zval * link ;
ldap_linkdata * ld ;
2005-04-17 16:25:59 +00:00
char * binddn = NULL ;
2007-07-12 22:08:58 +00:00
char * passwd = NULL ;
2005-04-17 16:25:59 +00:00
char * sasl_mech = NULL ;
char * sasl_realm = NULL ;
char * sasl_authz_id = NULL ;
2007-07-12 22:08:58 +00:00
char * sasl_authc_id = NULL ;
2005-04-17 16:25:59 +00:00
char * props = NULL ;
2014-08-28 07:43:14 +00:00
size_t rc , dn_len , passwd_len , mech_len , realm_len , authc_id_len , authz_id_len , props_len ;
2005-04-17 16:25:59 +00:00
php_ldap_bictx * ctx ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O|s!s!s!s!s!s!s! " , & link , ldap_link_ce , & 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 ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2003-06-08 23:44:01 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2003-06-08 23:44:01 +00:00
2007-07-12 22:08:58 +00:00
ctx = _php_sasl_setdefs ( ld - > link , sasl_mech , sasl_realm , sasl_authc_id , passwd , sasl_authz_id ) ;
2005-04-17 16:25:59 +00:00
if ( props ) {
ldap_set_option ( ld - > link , LDAP_OPT_X_SASL_SECPROPS , props ) ;
}
rc = ldap_sasl_interactive_bind_s ( ld - > link , binddn , ctx - > mech , NULL , NULL , LDAP_SASL_QUIET , _php_sasl_interact , ctx ) ;
if ( rc ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Unable to bind to server: %s " , ldap_err2string ( rc ) ) ;
2005-04-17 16:25:59 +00:00
RETVAL_FALSE ;
2003-06-08 23:44:01 +00:00
} else {
2005-04-17 16:25:59 +00:00
RETVAL_TRUE ;
2003-06-08 23:44:01 +00:00
}
2005-04-17 16:25:59 +00:00
_php_sasl_freedefs ( ctx ) ;
2003-06-08 23:44:01 +00:00
}
/* }}} */
2003-06-13 13:30:46 +00:00
# endif /* HAVE_LDAP_SASL */
2003-06-08 23:44:01 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Unbind from LDAP directory */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_unbind )
1999-04-22 00:45:14 +00:00
{
2002-08-05 21:14:14 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & link , ldap_link_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
ldap_link_free ( ld ) ;
1999-04-22 00:45:14 +00:00
RETURN_TRUE ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ php_set_opts */
2009-06-15 15:18:31 +00:00
static void php_set_opts ( LDAP * ldap , int sizelimit , int timelimit , int deref , int * old_sizelimit , int * old_timelimit , int * old_deref )
2001-01-12 22:08:26 +00:00
{
/* sizelimit */
if ( sizelimit > - 1 ) {
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION >= 2004) || defined(HAVE_ORALDAP)
2009-06-15 15:18:31 +00:00
ldap_get_option ( ldap , LDAP_OPT_SIZELIMIT , old_sizelimit ) ;
2001-01-12 22:08:26 +00:00
ldap_set_option ( ldap , LDAP_OPT_SIZELIMIT , & sizelimit ) ;
# else
2015-01-03 09:22:58 +00:00
* old_sizelimit = ldap - > ld_sizelimit ;
ldap - > ld_sizelimit = sizelimit ;
2001-01-12 22:08:26 +00:00
# endif
}
/* timelimit */
if ( timelimit > - 1 ) {
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION >= 2004) || defined(HAVE_ORALDAP)
2015-09-08 22:24:09 +00:00
ldap_get_option ( ldap , LDAP_OPT_TIMELIMIT , old_timelimit ) ;
2001-01-12 22:08:26 +00:00
ldap_set_option ( ldap , LDAP_OPT_TIMELIMIT , & timelimit ) ;
# else
2015-01-03 09:22:58 +00:00
* old_timelimit = ldap - > ld_timelimit ;
ldap - > ld_timelimit = timelimit ;
2001-01-12 22:08:26 +00:00
# endif
}
/* deref */
if ( deref > - 1 ) {
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION >= 2004) || defined(HAVE_ORALDAP)
2015-09-08 22:24:09 +00:00
ldap_get_option ( ldap , LDAP_OPT_DEREF , old_deref ) ;
2001-01-12 22:08:26 +00:00
ldap_set_option ( ldap , LDAP_OPT_DEREF , & deref ) ;
# else
2015-01-03 09:22:58 +00:00
* old_deref = ldap - > ld_deref ;
ldap - > ld_deref = deref ;
2001-01-12 22:08:26 +00:00
# endif
}
}
2001-06-05 13:12:10 +00:00
/* }}} */
2001-01-12 22:08:26 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ php_ldap_do_search */
1999-12-18 11:49:31 +00:00
static void php_ldap_do_search ( INTERNAL_FUNCTION_PARAMETERS , int scope )
1999-04-22 00:45:14 +00:00
{
2020-09-04 12:23:43 +00:00
zval * link , * attrs = NULL , * attr , * serverctrls = NULL ;
zend_string * base_dn_str , * filter_str ;
HashTable * base_dn_ht , * filter_ht ;
2014-08-25 17:24:55 +00:00
zend_long attrsonly , sizelimit , timelimit , deref ;
2019-06-14 09:11:24 +00:00
zend_string * ldap_filter = NULL , * ldap_base_dn = NULL ;
2019-06-13 20:12:34 +00:00
char * * ldap_attrs = NULL ;
2009-06-25 15:19:29 +00:00
ldap_linkdata * ld = NULL ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2020-07-13 04:19:34 +00:00
LDAPMessage * ldap_res = NULL ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2015-01-03 09:22:58 +00:00
int ldap_attrsonly = 0 , ldap_sizelimit = - 1 , ldap_timelimit = - 1 , ldap_deref = - 1 ;
int old_ldap_sizelimit = - 1 , old_ldap_timelimit = - 1 , old_ldap_deref = - 1 ;
2021-05-12 14:17:31 +00:00
int num_attribs = 0 , ret = 1 , i , ldap_errno , argcount = ZEND_NUM_ARGS ( ) ;
2009-08-15 00:52:31 +00:00
2020-09-04 12:23:43 +00:00
ZEND_PARSE_PARAMETERS_START ( 3 , 9 )
Z_PARAM_ZVAL ( link )
2020-09-10 22:23:54 +00:00
Z_PARAM_ARRAY_HT_OR_STR ( base_dn_ht , base_dn_str )
Z_PARAM_ARRAY_HT_OR_STR ( filter_ht , filter_str )
2020-09-04 12:23:43 +00:00
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY_EX ( attrs , 0 , 1 )
Z_PARAM_LONG ( attrsonly )
Z_PARAM_LONG ( sizelimit )
Z_PARAM_LONG ( timelimit )
Z_PARAM_LONG ( deref )
2020-10-15 09:46:44 +00:00
Z_PARAM_ARRAY_EX ( serverctrls , 1 , 1 )
2020-09-04 12:23:43 +00:00
ZEND_PARSE_PARAMETERS_END ( ) ;
1999-04-22 00:45:14 +00:00
2000-07-21 19:00:21 +00:00
/* Reverse -> fall through */
2009-08-15 00:52:31 +00:00
switch ( argcount ) {
2017-07-26 14:41:44 +00:00
case 9 :
2009-08-15 00:52:31 +00:00
case 8 :
ldap_deref = deref ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2009-08-15 00:52:31 +00:00
case 7 :
ldap_timelimit = timelimit ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2009-08-15 00:52:31 +00:00
case 6 :
ldap_sizelimit = sizelimit ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2009-08-15 00:52:31 +00:00
case 5 :
ldap_attrsonly = attrsonly ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2009-08-15 00:52:31 +00:00
case 4 :
num_attribs = zend_hash_num_elements ( Z_ARRVAL_P ( attrs ) ) ;
2004-06-28 22:31:28 +00:00
ldap_attrs = safe_emalloc ( ( num_attribs + 1 ) , sizeof ( char * ) , 0 ) ;
1999-04-22 00:45:14 +00:00
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < num_attribs ; i + + ) {
2014-05-20 03:26:26 +00:00
if ( ( attr = zend_hash_index_find ( Z_ARRVAL_P ( attrs ) , i ) ) = = NULL ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Array initialization wrong " ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
goto cleanup ;
1999-04-22 00:45:14 +00:00
}
2000-07-21 19:00:21 +00:00
2019-06-14 09:11:24 +00:00
convert_to_string ( attr ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
ret = 0 ;
goto cleanup ;
}
2019-06-14 09:11:24 +00:00
ldap_attrs [ i ] = Z_STRVAL_P ( attr ) ;
1999-04-22 00:45:14 +00:00
}
ldap_attrs [ num_attribs ] = NULL ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
1999-04-22 00:45:14 +00:00
default :
2009-08-15 00:52:31 +00:00
break ;
1999-04-22 00:45:14 +00:00
}
2001-01-12 22:08:26 +00:00
/* parallel search? */
2009-08-15 00:52:31 +00:00
if ( Z_TYPE_P ( link ) = = IS_ARRAY ) {
2001-01-17 13:43:39 +00:00
int i , nlinks , nbases , nfilters , * rcs ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * * lds ;
2021-03-13 11:11:40 +00:00
zval * entry , object ;
2015-01-03 09:22:58 +00:00
2009-08-15 00:52:31 +00:00
nlinks = zend_hash_num_elements ( Z_ARRVAL_P ( link ) ) ;
2001-01-12 22:08:26 +00:00
if ( nlinks = = 0 ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 1 , " cannot be empty " ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
goto cleanup ;
2001-01-12 22:08:26 +00:00
}
2020-09-04 12:23:43 +00:00
if ( base_dn_ht ) {
nbases = zend_hash_num_elements ( base_dn_ht ) ;
2001-01-12 22:08:26 +00:00
if ( nbases ! = nlinks ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 2 , " must have the same number of elements as the links array " ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
goto cleanup ;
2001-01-12 22:08:26 +00:00
}
2020-09-04 12:23:43 +00:00
zend_hash_internal_pointer_reset ( base_dn_ht ) ;
2001-01-12 22:08:26 +00:00
} else {
nbases = 0 ; /* this means string, not array */
2020-09-04 12:23:43 +00:00
ldap_base_dn = zend_string_copy ( base_dn_str ) ;
2019-06-13 20:12:34 +00:00
if ( EG ( exception ) ) {
ret = 0 ;
goto cleanup ;
2005-07-09 00:46:45 +00:00
}
2001-01-12 22:08:26 +00:00
}
2020-09-04 12:23:43 +00:00
if ( filter_ht ) {
nfilters = zend_hash_num_elements ( filter_ht ) ;
2001-01-17 13:43:39 +00:00
if ( nfilters ! = nlinks ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " must have the same number of elements as the links array " ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
goto cleanup ;
2001-01-17 13:43:39 +00:00
}
2020-09-04 12:23:43 +00:00
zend_hash_internal_pointer_reset ( filter_ht ) ;
2001-01-17 13:43:39 +00:00
} else {
nfilters = 0 ; /* this means string, not array */
2020-09-04 12:23:43 +00:00
ldap_filter = zend_string_copy ( filter_str ) ;
2001-01-17 13:43:39 +00:00
}
2003-04-30 21:53:53 +00:00
lds = safe_emalloc ( nlinks , sizeof ( ldap_linkdata ) , 0 ) ;
rcs = safe_emalloc ( nlinks , sizeof ( * rcs ) , 0 ) ;
2015-01-03 09:22:58 +00:00
2009-08-15 00:52:31 +00:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( link ) ) ;
2001-01-12 22:08:26 +00:00
for ( i = 0 ; i < nlinks ; i + + ) {
2014-05-20 03:26:26 +00:00
entry = zend_hash_get_current_data ( Z_ARRVAL_P ( link ) ) ;
2001-05-31 21:09:30 +00:00
2021-03-13 11:11:40 +00:00
if ( Z_TYPE_P ( entry ) ! = IS_OBJECT | | ! instanceof_function ( Z_OBJCE_P ( entry ) , ldap_link_ce ) ) {
zend_argument_value_error ( 1 , " must only contain objects of type LDAP " ) ;
ret = 0 ;
goto cleanup_parallel ;
}
ld = Z_LDAP_LINK_P ( entry ) ;
if ( ! ld - > link ) {
zend_throw_error ( NULL , " LDAP connection has already been closed " ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
goto cleanup_parallel ;
2001-01-12 22:08:26 +00:00
}
2021-03-13 11:11:40 +00:00
2001-01-12 22:08:26 +00:00
if ( nbases ! = 0 ) { /* base_dn an array? */
2020-09-04 12:23:43 +00:00
entry = zend_hash_get_current_data ( base_dn_ht ) ;
zend_hash_move_forward ( base_dn_ht ) ;
2019-06-13 20:12:34 +00:00
ldap_base_dn = zval_get_string ( entry ) ;
if ( EG ( exception ) ) {
ret = 0 ;
goto cleanup_parallel ;
2005-07-09 00:46:45 +00:00
}
2001-01-12 22:08:26 +00:00
}
2001-01-17 13:43:39 +00:00
if ( nfilters ! = 0 ) { /* filter an array? */
2020-09-04 12:23:43 +00:00
entry = zend_hash_get_current_data ( filter_ht ) ;
zend_hash_move_forward ( filter_ht ) ;
2019-06-13 18:58:45 +00:00
ldap_filter = zval_get_string ( entry ) ;
2019-06-13 20:12:34 +00:00
if ( EG ( exception ) ) {
ret = 0 ;
goto cleanup_parallel ;
}
2001-01-17 13:43:39 +00:00
}
2001-01-12 22:08:26 +00:00
2020-10-15 09:46:44 +00:00
if ( serverctrls ) {
2019-08-20 11:58:22 +00:00
/* We have to parse controls again for each link as they use it */
2017-07-26 14:41:44 +00:00
_php_ldap_controls_free ( & lserverctrls ) ;
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 9 ) ;
2017-07-26 14:41:44 +00:00
if ( lserverctrls = = NULL ) {
rcs [ i ] = - 1 ;
continue ;
}
}
2009-06-15 15:18:31 +00:00
php_set_opts ( ld - > link , ldap_sizelimit , ldap_timelimit , ldap_deref , & old_ldap_sizelimit , & old_ldap_timelimit , & old_ldap_deref ) ;
2001-01-12 22:08:26 +00:00
2015-01-03 09:22:58 +00:00
/* Run the actual search */
2019-06-13 20:12:34 +00:00
ldap_search_ext ( ld - > link , ZSTR_VAL ( ldap_base_dn ) , scope , ZSTR_VAL ( ldap_filter ) , ldap_attrs , ldap_attrsonly , lserverctrls , NULL , NULL , ldap_sizelimit , & rcs [ i ] ) ;
2001-11-29 20:17:17 +00:00
lds [ i ] = ld ;
2009-08-15 00:52:31 +00:00
zend_hash_move_forward ( Z_ARRVAL_P ( link ) ) ;
2001-01-12 22:08:26 +00:00
}
2015-01-03 09:22:58 +00:00
2003-01-18 20:10:23 +00:00
array_init ( return_value ) ;
2001-01-12 22:08:26 +00:00
/* Collect results from the searches */
for ( i = 0 ; i < nlinks ; i + + ) {
if ( rcs [ i ] ! = - 1 ) {
2001-11-29 20:17:17 +00:00
rcs [ i ] = ldap_result ( lds [ i ] - > link , LDAP_RES_ANY , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
2001-01-12 22:08:26 +00:00
}
if ( rcs [ i ] ! = - 1 ) {
2021-03-13 11:11:40 +00:00
object_init_ex ( & object , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( & object ) ;
result - > result = ldap_res ;
add_next_index_zval ( return_value , & object ) ;
2001-01-12 22:08:26 +00:00
} else {
add_next_index_bool ( return_value , 0 ) ;
}
2001-12-26 18:40:57 +00:00
}
2009-06-15 15:04:11 +00:00
cleanup_parallel :
2001-11-29 20:17:17 +00:00
efree ( lds ) ;
2001-01-12 22:08:26 +00:00
efree ( rcs ) ;
2021-03-13 11:11:40 +00:00
} else if ( Z_TYPE_P ( link ) = = IS_OBJECT & & instanceof_function ( Z_OBJCE_P ( link ) , ldap_link_ce ) ) {
ld = Z_LDAP_LINK_P ( link ) ;
if ( ! ld - > link ) {
zend_throw_error ( NULL , " LDAP connection has already been closed " ) ;
2019-06-13 20:12:34 +00:00
ret = 0 ;
goto cleanup ;
}
2001-01-12 22:08:26 +00:00
2020-09-04 12:23:43 +00:00
if ( ! base_dn_str ) {
2021-03-13 11:11:40 +00:00
zend_argument_type_error ( 2 , " must be of type string when argument #1 ($ldap) is an LDAP instance " ) ;
2021-03-15 22:07:05 +00:00
ret = 0 ;
goto cleanup ;
2001-01-13 10:00:27 +00:00
}
2020-09-04 12:23:43 +00:00
ldap_base_dn = zend_string_copy ( base_dn_str ) ;
2000-07-21 19:00:21 +00:00
2020-09-04 12:23:43 +00:00
if ( ! filter_str ) {
2021-03-13 11:11:40 +00:00
zend_argument_type_error ( 3 , " must be of type string when argument #1 ($ldap) is an LDAP instance " ) ;
2021-03-15 22:07:05 +00:00
ret = 0 ;
goto cleanup ;
2009-06-15 15:04:11 +00:00
}
2020-09-04 12:23:43 +00:00
ldap_filter = zend_string_copy ( filter_str ) ;
2000-07-21 19:00:21 +00:00
2020-10-15 09:46:44 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 9 ) ;
2017-07-26 14:41:44 +00:00
if ( lserverctrls = = NULL ) {
ret = 0 ;
goto cleanup ;
}
}
2009-06-15 15:18:31 +00:00
php_set_opts ( ld - > link , ldap_sizelimit , ldap_timelimit , ldap_deref , & old_ldap_sizelimit , & old_ldap_timelimit , & old_ldap_deref ) ;
2000-07-21 19:00:21 +00:00
2015-01-03 09:22:58 +00:00
/* Run the actual search */
2021-05-12 14:17:31 +00:00
ldap_errno = ldap_search_ext_s ( ld - > link , ZSTR_VAL ( ldap_base_dn ) , scope , ZSTR_VAL ( ldap_filter ) , ldap_attrs , ldap_attrsonly , lserverctrls , NULL , NULL , ldap_sizelimit , & ldap_res ) ;
2015-01-03 09:22:58 +00:00
2021-05-12 14:17:31 +00:00
if ( ldap_errno ! = LDAP_SUCCESS
& & ldap_errno ! = LDAP_SIZELIMIT_EXCEEDED
2001-01-07 13:03:11 +00:00
# ifdef LDAP_ADMINLIMIT_EXCEEDED
2021-05-12 14:17:31 +00:00
& & ldap_errno ! = LDAP_ADMINLIMIT_EXCEEDED
2001-01-07 13:03:11 +00:00
# endif
# ifdef LDAP_REFERRAL
2021-05-12 14:17:31 +00:00
& & ldap_errno ! = LDAP_REFERRAL
2001-01-07 13:03:11 +00:00
# endif
2009-06-15 15:04:11 +00:00
) {
2020-07-13 04:19:34 +00:00
/* ldap_res should be freed regardless of return value of ldap_search_ext_s()
* see : https : //linux.die.net/man/3/ldap_search_ext_s */
if ( ldap_res ! = NULL ) {
ldap_msgfree ( ldap_res ) ;
}
2021-05-12 14:17:31 +00:00
php_error_docref ( NULL , E_WARNING , " Search: %s " , ldap_err2string ( ldap_errno ) ) ;
2009-06-15 15:04:11 +00:00
ret = 0 ;
} else {
2021-05-12 14:17:31 +00:00
if ( ldap_errno = = LDAP_SIZELIMIT_EXCEEDED ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Partial search results returned: Sizelimit exceeded " ) ;
2009-06-15 15:04:11 +00:00
}
2001-01-07 13:03:11 +00:00
# ifdef LDAP_ADMINLIMIT_EXCEEDED
2021-05-12 14:17:31 +00:00
else if ( ldap_errno = = LDAP_ADMINLIMIT_EXCEEDED ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Partial search results returned: Adminlimit exceeded " ) ;
2009-06-15 15:04:11 +00:00
}
2001-01-07 13:03:11 +00:00
# endif
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2009-06-15 15:04:11 +00:00
}
2021-03-13 11:11:40 +00:00
} else {
zend_argument_type_error ( 1 , " must be of type LDAP|array, %s given " , zend_zval_type_name ( link ) ) ;
2009-06-15 15:04:11 +00:00
}
cleanup :
2009-06-25 15:19:29 +00:00
if ( ld ) {
/* Restoring previous options */
php_set_opts ( ld - > link , old_ldap_sizelimit , old_ldap_timelimit , old_ldap_deref , & ldap_sizelimit , & ldap_timelimit , & ldap_deref ) ;
}
2019-06-14 09:11:24 +00:00
if ( ldap_filter ) {
zend_string_release ( ldap_filter ) ;
}
if ( ldap_base_dn ) {
zend_string_release ( ldap_base_dn ) ;
}
2009-06-15 15:04:11 +00:00
if ( ldap_attrs ! = NULL ) {
efree ( ldap_attrs ) ;
}
if ( ! ret ) {
RETVAL_BOOL ( ret ) ;
1999-04-22 00:45:14 +00:00
}
2017-07-26 14:41:44 +00:00
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
1999-04-22 00:45:14 +00:00
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-07-21 19:00:21 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Read an entry */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_read )
1999-04-22 00:45:14 +00:00
{
1999-12-18 11:49:31 +00:00
php_ldap_do_search ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_SCOPE_BASE ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Single-level search */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_list )
1999-04-22 00:45:14 +00:00
{
1999-12-18 11:49:31 +00:00
php_ldap_do_search ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_SCOPE_ONELEVEL ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Search LDAP tree under base_dn */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_search )
1999-04-22 00:45:14 +00:00
{
1999-12-18 11:49:31 +00:00
php_ldap_do_search ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_SCOPE_SUBTREE ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Free result memory */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_free_result )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * result ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & result , ldap_result_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
ldap_result_free ( ldap_result ) ;
2001-05-31 21:09:30 +00:00
2001-11-14 22:05:33 +00:00
RETVAL_TRUE ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Count the number of entries in a search result */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_count_entries )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result , ldap_result_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
RETURN_LONG ( ldap_count_entries ( ld - > link , ldap_result - > result ) ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Return first result id */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_first_entry )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result ;
2015-01-03 09:22:58 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
ldap_resultdata * ldap_result ;
LDAPMessage * entry ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result , ldap_result_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( ( entry = ldap_first_entry ( ld - > link , ldap_result - > result ) ) = = NULL ) {
2001-05-31 21:09:30 +00:00
RETVAL_FALSE ;
1999-04-22 00:45:14 +00:00
} else {
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_entry_ce ) ;
resultentry = Z_LDAP_RESULT_ENTRY_P ( return_value ) ;
2014-05-20 03:26:26 +00:00
ZVAL_COPY ( & resultentry - > res , result ) ;
2002-05-04 14:27:48 +00:00
resultentry - > data = entry ;
2007-07-13 01:24:16 +00:00
resultentry - > ber = NULL ;
1999-04-22 00:45:14 +00:00
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get next result entry */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_next_entry )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry , * resultentry_next ;
2002-05-04 14:27:48 +00:00
LDAPMessage * entry_next ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
1999-04-22 00:45:14 +00:00
2002-05-04 14:27:48 +00:00
if ( ( entry_next = ldap_next_entry ( ld - > link , resultentry - > data ) ) = = NULL ) {
2001-05-31 21:09:30 +00:00
RETVAL_FALSE ;
1999-04-22 00:45:14 +00:00
} else {
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_entry_ce ) ;
resultentry_next = Z_LDAP_RESULT_ENTRY_P ( return_value ) ;
2014-05-20 03:26:26 +00:00
ZVAL_COPY ( & resultentry_next - > res , & resultentry - > res ) ;
2002-05-04 14:27:48 +00:00
resultentry_next - > data = entry_next ;
2007-07-13 01:24:16 +00:00
resultentry_next - > ber = NULL ;
1999-04-22 00:45:14 +00:00
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get all result entries */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_get_entries )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
LDAPMessage * ldap_result_entry ;
2014-05-20 03:26:26 +00:00
zval tmp1 , tmp2 ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
1999-07-16 18:01:55 +00:00
LDAP * ldap ;
int num_entries , num_attrib , num_values , i ;
BerElement * ber ;
char * attribute ;
1999-12-09 23:45:30 +00:00
size_t attr_len ;
2007-03-22 21:50:34 +00:00
struct berval * * ldap_value ;
1999-07-16 18:01:55 +00:00
char * dn ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result , ldap_result_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
1999-04-22 00:45:14 +00:00
2001-11-29 20:17:17 +00:00
ldap = ld - > link ;
2021-03-13 11:11:40 +00:00
num_entries = ldap_count_entries ( ldap , ldap_result - > result ) ;
1999-04-22 00:45:14 +00:00
2009-11-18 17:44:58 +00:00
array_init ( return_value ) ;
2014-08-25 17:24:55 +00:00
add_assoc_long ( return_value , " count " , num_entries ) ;
2009-11-18 17:44:58 +00:00
2008-04-16 14:21:04 +00:00
if ( num_entries = = 0 ) {
2009-11-18 17:44:58 +00:00
return ;
2008-04-16 14:21:04 +00:00
}
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
ldap_result_entry = ldap_first_entry ( ldap , ldap_result - > result ) ;
2008-04-16 14:21:04 +00:00
if ( ldap_result_entry = = NULL ) {
2018-07-04 16:22:24 +00:00
zend_array_destroy ( Z_ARR_P ( return_value ) ) ;
2008-04-16 14:21:04 +00:00
RETURN_FALSE ;
}
1999-04-22 00:45:14 +00:00
2009-11-18 17:44:58 +00:00
num_entries = 0 ;
2003-06-08 23:34:51 +00:00
while ( ldap_result_entry ! = NULL ) {
2014-05-20 03:26:26 +00:00
array_init ( & tmp1 ) ;
1999-04-22 00:45:14 +00:00
2000-07-25 15:34:28 +00:00
num_attrib = 0 ;
1999-04-22 00:45:14 +00:00
attribute = ldap_first_attribute ( ldap , ldap_result_entry , & ber ) ;
2000-07-25 15:34:28 +00:00
1999-04-22 00:45:14 +00:00
while ( attribute ! = NULL ) {
2007-03-22 21:50:34 +00:00
ldap_value = ldap_get_values_len ( ldap , ldap_result_entry , attribute ) ;
num_values = ldap_count_values_len ( ldap_value ) ;
1999-04-22 00:45:14 +00:00
2014-05-20 03:26:26 +00:00
array_init ( & tmp2 ) ;
2014-08-25 17:24:55 +00:00
add_assoc_long ( & tmp2 , " count " , num_values ) ;
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < num_values ; i + + ) {
2014-05-20 03:26:26 +00:00
add_index_stringl ( & tmp2 , i , ldap_value [ i ] - > bv_val , ldap_value [ i ] - > bv_len ) ;
2015-01-03 09:22:58 +00:00
}
2007-03-22 21:50:34 +00:00
ldap_value_free_len ( ldap_value ) ;
1999-04-22 00:45:14 +00:00
1999-12-09 23:45:30 +00:00
attr_len = strlen ( attribute ) ;
2021-09-24 01:40:27 +00:00
zend_str_tolower ( attribute , attr_len ) ;
zend_hash_str_update ( Z_ARRVAL ( tmp1 ) , attribute , attr_len , & tmp2 ) ;
2014-05-20 03:26:26 +00:00
add_index_string ( & tmp1 , num_attrib , attribute ) ;
1999-04-22 00:45:14 +00:00
2000-07-25 15:34:28 +00:00
num_attrib + + ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2001-06-20 21:12:55 +00:00
ldap_memfree ( attribute ) ;
# endif
1999-04-22 00:45:14 +00:00
attribute = ldap_next_attribute ( ldap , ldap_result_entry , ber ) ;
}
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2007-07-13 01:24:16 +00:00
if ( ber ! = NULL ) {
2001-06-20 21:12:55 +00:00
ber_free ( ber , 0 ) ;
2007-07-13 01:24:16 +00:00
}
2001-06-20 21:12:55 +00:00
# endif
1999-04-22 00:45:14 +00:00
2014-08-25 17:24:55 +00:00
add_assoc_long ( & tmp1 , " count " , num_attrib ) ;
1999-04-22 00:45:14 +00:00
dn = ldap_get_dn ( ldap , ldap_result_entry ) ;
2018-04-23 05:01:35 +00:00
if ( dn ) {
2018-04-24 04:59:50 +00:00
add_assoc_string ( & tmp1 , " dn " , dn ) ;
2018-04-23 05:01:35 +00:00
} else {
2018-04-24 04:59:50 +00:00
add_assoc_null ( & tmp1 , " dn " ) ;
2018-04-23 05:01:35 +00:00
}
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2001-06-20 21:12:55 +00:00
ldap_memfree ( dn ) ;
2001-07-15 11:12:28 +00:00
# else
free ( dn ) ;
2001-06-20 21:12:55 +00:00
# endif
1999-04-22 00:45:14 +00:00
2014-05-20 03:26:26 +00:00
zend_hash_index_update ( Z_ARRVAL_P ( return_value ) , num_entries , & tmp1 ) ;
2015-01-03 09:22:58 +00:00
2000-07-25 15:34:28 +00:00
num_entries + + ;
1999-04-22 00:45:14 +00:00
ldap_result_entry = ldap_next_entry ( ldap , ldap_result_entry ) ;
}
2014-08-25 17:24:55 +00:00
add_assoc_long ( return_value , " count " , num_entries ) ;
2000-07-25 15:34:28 +00:00
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Return first attribute */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_first_attribute )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
1999-04-22 00:45:14 +00:00
char * attribute ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
1999-04-22 00:45:14 +00:00
2007-07-13 01:24:16 +00:00
if ( ( attribute = ldap_first_attribute ( ld - > link , resultentry - > data , & resultentry - > ber ) ) = = NULL ) {
1999-04-22 00:45:14 +00:00
RETURN_FALSE ;
} else {
2014-05-20 03:26:26 +00:00
RETVAL_STRING ( attribute ) ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
1999-04-22 00:45:14 +00:00
ldap_memfree ( attribute ) ;
# endif
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get the next attribute in result */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_next_attribute )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
1999-07-16 18:01:55 +00:00
char * attribute ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
1999-04-22 00:45:14 +00:00
2007-07-13 02:00:39 +00:00
if ( resultentry - > ber = = NULL ) {
2020-01-15 10:27:29 +00:00
php_error_docref ( NULL , E_WARNING , " Called before calling ldap_first_attribute() or no attributes found in result entry " ) ;
2007-07-13 02:00:39 +00:00
RETURN_FALSE ;
}
2007-07-13 01:24:16 +00:00
if ( ( attribute = ldap_next_attribute ( ld - > link , resultentry - > data , resultentry - > ber ) ) = = NULL ) {
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2007-07-13 01:24:16 +00:00
if ( resultentry - > ber ! = NULL ) {
ber_free ( resultentry - > ber , 0 ) ;
resultentry - > ber = NULL ;
}
# endif
1999-04-22 00:45:14 +00:00
RETURN_FALSE ;
} else {
2014-05-20 03:26:26 +00:00
RETVAL_STRING ( attribute ) ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
1999-04-22 00:45:14 +00:00
ldap_memfree ( attribute ) ;
# endif
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get attributes from a search result entry */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_get_attributes )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2014-05-20 03:26:26 +00:00
zval tmp ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
1999-07-16 18:01:55 +00:00
char * attribute ;
2007-03-22 21:50:34 +00:00
struct berval * * ldap_value ;
2000-07-25 15:34:28 +00:00
int i , num_values , num_attrib ;
1999-07-16 18:01:55 +00:00
BerElement * ber ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
1999-04-22 00:45:14 +00:00
2000-07-25 15:34:28 +00:00
array_init ( return_value ) ;
1999-04-22 00:45:14 +00:00
num_attrib = 0 ;
2015-01-03 09:22:58 +00:00
2002-05-04 14:27:48 +00:00
attribute = ldap_first_attribute ( ld - > link , resultentry - > data , & ber ) ;
1999-04-22 00:45:14 +00:00
while ( attribute ! = NULL ) {
2007-03-22 21:50:34 +00:00
ldap_value = ldap_get_values_len ( ld - > link , resultentry - > data , attribute ) ;
num_values = ldap_count_values_len ( ldap_value ) ;
1999-04-22 00:45:14 +00:00
2014-05-20 03:26:26 +00:00
array_init ( & tmp ) ;
2014-08-25 17:24:55 +00:00
add_assoc_long ( & tmp , " count " , num_values ) ;
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < num_values ; i + + ) {
2014-05-20 03:26:26 +00:00
add_index_stringl ( & tmp , i , ldap_value [ i ] - > bv_val , ldap_value [ i ] - > bv_len ) ;
1999-04-22 00:45:14 +00:00
}
2007-03-22 21:50:34 +00:00
ldap_value_free_len ( ldap_value ) ;
1999-04-22 00:45:14 +00:00
2014-05-20 03:26:26 +00:00
zend_hash_str_update ( Z_ARRVAL_P ( return_value ) , attribute , strlen ( attribute ) , & tmp ) ;
2014-04-15 11:40:40 +00:00
add_index_string ( return_value , num_attrib , attribute ) ;
1999-04-22 00:45:14 +00:00
2000-07-25 15:34:28 +00:00
num_attrib + + ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2001-06-23 13:43:20 +00:00
ldap_memfree ( attribute ) ;
# endif
2002-05-04 14:27:48 +00:00
attribute = ldap_next_attribute ( ld - > link , resultentry - > data , ber ) ;
1999-04-22 00:45:14 +00:00
}
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
2007-07-13 01:24:16 +00:00
if ( ber ! = NULL ) {
ber_free ( ber , 0 ) ;
}
2001-06-23 13:43:20 +00:00
# endif
2015-01-03 09:22:58 +00:00
2014-08-25 17:24:55 +00:00
add_assoc_long ( return_value , " count " , num_attrib ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get all values with lengths from a result entry */
2000-04-07 23:20:22 +00:00
PHP_FUNCTION ( ldap_get_values_len )
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
2008-04-16 14:21:04 +00:00
char * attr ;
2000-04-07 23:20:22 +00:00
struct berval * * ldap_value_len ;
2014-08-28 07:43:14 +00:00
int i , num_values ;
size_t attr_len ;
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OOs " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce , & attr , & attr_len ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-04-07 23:20:22 +00:00
}
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
2000-07-28 22:39:22 +00:00
2008-04-16 14:21:04 +00:00
if ( ( ldap_value_len = ldap_get_values_len ( ld - > link , resultentry - > data , attr ) ) = = NULL ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Cannot get the value(s) of attribute %s " , ldap_err2string ( _get_lderrno ( ld - > link ) ) ) ;
2000-04-07 23:20:22 +00:00
RETURN_FALSE ;
}
2015-01-03 09:22:58 +00:00
2000-04-07 23:20:22 +00:00
num_values = ldap_count_values_len ( ldap_value_len ) ;
2003-01-18 20:10:23 +00:00
array_init ( return_value ) ;
2015-01-03 09:22:58 +00:00
2000-04-07 23:20:22 +00:00
for ( i = 0 ; i < num_values ; i + + ) {
2014-04-15 11:40:40 +00:00
add_next_index_stringl ( return_value , ldap_value_len [ i ] - > bv_val , ldap_value_len [ i ] - > bv_len ) ;
2000-04-07 23:20:22 +00:00
}
2015-01-03 09:22:58 +00:00
2014-08-25 17:24:55 +00:00
add_assoc_long ( return_value , " count " , num_values ) ;
2000-07-28 00:09:33 +00:00
ldap_value_free_len ( ldap_value_len ) ;
2000-04-07 23:20:22 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get the DN of a result entry */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_get_dn )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
1999-04-22 00:45:14 +00:00
char * text ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
1999-04-22 00:45:14 +00:00
2002-05-04 14:27:48 +00:00
text = ldap_get_dn ( ld - > link , resultentry - > data ) ;
2003-06-08 23:34:51 +00:00
if ( text ! = NULL ) {
2014-05-20 03:26:26 +00:00
RETVAL_STRING ( text ) ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
1999-04-22 00:45:14 +00:00
ldap_memfree ( text ) ;
2001-07-15 11:12:28 +00:00
# else
free ( text ) ;
1999-04-22 00:45:14 +00:00
# endif
} else {
RETURN_FALSE ;
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Splits DN into its component parts */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_explode_dn )
1999-04-22 00:45:14 +00:00
{
2014-08-25 17:24:55 +00:00
zend_long with_attrib ;
2008-04-16 14:21:04 +00:00
char * dn , * * ldap_value ;
2014-08-28 07:43:14 +00:00
int i , count ;
size_t dn_len ;
1999-04-22 00:45:14 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " sl " , & dn , & dn_len , & with_attrib ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2008-04-16 14:21:04 +00:00
if ( ! ( ldap_value = ldap_explode_dn ( dn , with_attrib ) ) ) {
2003-09-13 17:31:07 +00:00
/* Invalid parameters were passed to ldap_explode_dn */
RETURN_FALSE ;
}
1999-04-22 00:45:14 +00:00
i = 0 ;
2003-06-08 23:34:51 +00:00
while ( ldap_value [ i ] ! = NULL ) i + + ;
1999-04-22 00:45:14 +00:00
count = i ;
2003-01-18 20:10:23 +00:00
array_init ( return_value ) ;
1999-04-22 00:45:14 +00:00
2014-08-25 17:24:55 +00:00
add_assoc_long ( return_value , " count " , count ) ;
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < count ; i + + ) {
2014-04-15 11:40:40 +00:00
add_index_string ( return_value , i , ldap_value [ i ] ) ;
1999-04-22 00:45:14 +00:00
}
2015-06-23 14:44:48 +00:00
ldap_memvfree ( ( void * * ) ldap_value ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Convert DN to User Friendly Naming format */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_dn2ufn )
1999-04-22 00:45:14 +00:00
{
2008-04-16 14:21:04 +00:00
char * dn , * ufn ;
2014-08-27 13:31:48 +00:00
size_t dn_len ;
1999-04-22 00:45:14 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & dn , & dn_len ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2015-01-03 09:22:58 +00:00
2008-04-16 14:21:04 +00:00
ufn = ldap_dn2ufn ( dn ) ;
2015-01-03 09:22:58 +00:00
2008-04-16 14:21:04 +00:00
if ( ufn ! = NULL ) {
2014-05-20 03:26:26 +00:00
RETVAL_STRING ( ufn ) ;
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) || WINDOWS
1999-04-22 00:45:14 +00:00
ldap_memfree ( ufn ) ;
# endif
} else {
RETURN_FALSE ;
}
}
/* }}} */
1999-05-21 10:06:25 +00:00
2000-07-23 21:32:02 +00:00
2003-06-08 23:34:51 +00:00
/* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */
1999-05-21 10:06:25 +00:00
# define PHP_LD_FULL_ADD 0xff
2020-07-01 13:32:55 +00:00
/* {{{ php_ldap_do_modify */
2017-09-12 07:53:49 +00:00
static void php_ldap_do_modify ( INTERNAL_FUNCTION_PARAMETERS , int oper , int ext )
1999-04-22 00:45:14 +00:00
{
2017-09-07 15:03:45 +00:00
zval * serverctrls = NULL ;
2014-05-20 03:26:26 +00:00
zval * link , * entry , * value , * ivalue ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2008-04-16 14:21:04 +00:00
char * dn ;
1999-07-16 18:01:55 +00:00
LDAPMod * * ldap_mods ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2017-09-12 07:53:49 +00:00
LDAPMessage * ldap_res ;
int i , j , num_attribs , num_values , msgid ;
2014-08-28 07:43:14 +00:00
size_t dn_len ;
2000-07-28 21:31:02 +00:00
int * num_berval ;
2019-06-14 09:11:24 +00:00
zend_string * attribute ;
2014-08-25 17:24:55 +00:00
zend_ulong index ;
1999-07-16 18:01:55 +00:00
int is_full_add = 0 ; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Osa/|a! " , & link , ldap_link_ce , & dn , & dn_len , & entry , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2015-01-03 09:22:58 +00:00
}
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
1999-04-22 00:45:14 +00:00
2008-04-16 14:21:04 +00:00
num_attribs = zend_hash_num_elements ( Z_ARRVAL_P ( entry ) ) ;
2003-04-30 21:53:53 +00:00
ldap_mods = safe_emalloc ( ( num_attribs + 1 ) , sizeof ( LDAPMod * ) , 0 ) ;
num_berval = safe_emalloc ( num_attribs , sizeof ( int ) , 0 ) ;
2008-04-16 14:21:04 +00:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( entry ) ) ;
2000-07-28 21:31:02 +00:00
/* added by gerrit thomson to fix ldap_add using ldap_mod_add */
2003-06-08 23:34:51 +00:00
if ( oper = = PHP_LD_FULL_ADD ) {
2000-07-28 21:31:02 +00:00
oper = LDAP_MOD_ADD ;
is_full_add = 1 ;
}
1999-05-21 10:06:25 +00:00
/* end additional , gerrit thomson */
1999-04-22 00:45:14 +00:00
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < num_attribs ; i + + ) {
1999-04-22 00:45:14 +00:00
ldap_mods [ i ] = emalloc ( sizeof ( LDAPMod ) ) ;
2000-07-28 21:31:02 +00:00
ldap_mods [ i ] - > mod_op = oper | LDAP_MOD_BVALUES ;
2008-04-16 13:20:59 +00:00
ldap_mods [ i ] - > mod_type = NULL ;
1999-04-22 00:45:14 +00:00
2014-12-23 21:00:18 +00:00
if ( zend_hash_get_current_key ( Z_ARRVAL_P ( entry ) , & attribute , & index ) = = HASH_KEY_IS_STRING ) {
2015-06-30 10:59:27 +00:00
ldap_mods [ i ] - > mod_type = estrndup ( ZSTR_VAL ( attribute ) , ZSTR_LEN ( attribute ) ) ;
1999-04-22 00:45:14 +00:00
} else {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Unknown attribute in the data " ) ;
2001-01-13 10:00:27 +00:00
/* Free allocated memory */
while ( i > = 0 ) {
2008-04-16 13:20:59 +00:00
if ( ldap_mods [ i ] - > mod_type ) {
efree ( ldap_mods [ i ] - > mod_type ) ;
}
efree ( ldap_mods [ i ] ) ;
i - - ;
2001-01-13 10:00:27 +00:00
}
efree ( num_berval ) ;
2015-01-03 09:22:58 +00:00
efree ( ldap_mods ) ;
2000-11-13 02:02:40 +00:00
RETURN_FALSE ;
1999-04-22 00:45:14 +00:00
}
2014-05-20 03:26:26 +00:00
value = zend_hash_get_current_data ( Z_ARRVAL_P ( entry ) ) ;
1999-04-22 00:45:14 +00:00
2016-01-01 15:06:58 +00:00
ZVAL_DEREF ( value ) ;
2014-05-20 03:26:26 +00:00
if ( Z_TYPE_P ( value ) ! = IS_ARRAY ) {
1999-04-22 00:45:14 +00:00
num_values = 1 ;
} else {
2017-01-17 07:34:19 +00:00
SEPARATE_ARRAY ( value ) ;
2014-05-20 03:26:26 +00:00
num_values = zend_hash_num_elements ( Z_ARRVAL_P ( value ) ) ;
1999-04-22 00:45:14 +00:00
}
2015-01-03 09:22:58 +00:00
2000-07-28 21:31:02 +00:00
num_berval [ i ] = num_values ;
2003-04-30 21:53:53 +00:00
ldap_mods [ i ] - > mod_bvalues = safe_emalloc ( ( num_values + 1 ) , sizeof ( struct berval * ) , 0 ) ;
1999-05-21 10:06:25 +00:00
/* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */
2014-05-20 03:26:26 +00:00
if ( ( num_values = = 1 ) & & ( Z_TYPE_P ( value ) ! = IS_ARRAY ) ) {
2019-06-14 09:11:24 +00:00
convert_to_string ( value ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
RETVAL_FALSE ;
goto cleanup ;
}
2000-07-28 21:31:02 +00:00
ldap_mods [ i ] - > mod_bvalues [ 0 ] = ( struct berval * ) emalloc ( sizeof ( struct berval ) ) ;
2019-06-14 09:11:24 +00:00
ldap_mods [ i ] - > mod_bvalues [ 0 ] - > bv_val = Z_STRVAL_P ( value ) ;
ldap_mods [ i ] - > mod_bvalues [ 0 ] - > bv_len = Z_STRLEN_P ( value ) ;
2015-01-03 09:22:58 +00:00
} else {
2003-06-08 23:34:51 +00:00
for ( j = 0 ; j < num_values ; j + + ) {
2014-05-20 03:26:26 +00:00
if ( ( ivalue = zend_hash_index_find ( Z_ARRVAL_P ( value ) , j ) ) = = NULL ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " must contain arrays with consecutive integer indices starting from 0 " ) ;
2001-11-05 11:50:52 +00:00
num_berval [ i ] = j ;
num_attribs = i + 1 ;
RETVAL_FALSE ;
2017-09-07 09:04:52 +00:00
goto cleanup ;
2001-11-05 11:50:52 +00:00
}
2019-06-14 09:11:24 +00:00
convert_to_string ( ivalue ) ;
2019-06-13 18:58:45 +00:00
if ( EG ( exception ) ) {
RETVAL_FALSE ;
goto cleanup ;
}
2000-07-28 21:31:02 +00:00
ldap_mods [ i ] - > mod_bvalues [ j ] = ( struct berval * ) emalloc ( sizeof ( struct berval ) ) ;
2019-06-14 09:11:24 +00:00
ldap_mods [ i ] - > mod_bvalues [ j ] - > bv_val = Z_STRVAL_P ( ivalue ) ;
ldap_mods [ i ] - > mod_bvalues [ j ] - > bv_len = Z_STRLEN_P ( ivalue ) ;
1999-04-22 00:45:14 +00:00
}
}
2000-07-28 21:31:02 +00:00
ldap_mods [ i ] - > mod_bvalues [ num_values ] = NULL ;
2008-04-16 14:21:04 +00:00
zend_hash_move_forward ( Z_ARRVAL_P ( entry ) ) ;
1999-04-22 00:45:14 +00:00
}
ldap_mods [ num_attribs ] = NULL ;
2017-09-07 09:04:52 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 4 ) ;
2017-09-07 09:04:52 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
1999-05-21 10:06:25 +00:00
/* check flag to see if do_mod was called to perform full add , gerrit thomson */
2001-11-13 17:10:08 +00:00
if ( is_full_add = = 1 ) {
2017-09-12 07:53:49 +00:00
if ( ext ) {
i = ldap_add_ext ( ld - > link , dn , ldap_mods , lserverctrls , NULL , & msgid ) ;
} else {
i = ldap_add_ext_s ( ld - > link , dn , ldap_mods , lserverctrls , NULL ) ;
}
if ( i ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Add: %s " , ldap_err2string ( i ) ) ;
1999-04-22 00:45:14 +00:00
RETVAL_FALSE ;
2017-09-12 07:53:49 +00:00
} else if ( ext ) {
i = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( i = = - 1 ) {
php_error_docref ( NULL , E_WARNING , " Add operation failed " ) ;
RETVAL_FALSE ;
goto cleanup ;
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
1999-04-22 00:45:14 +00:00
} else RETVAL_TRUE ;
} else {
2017-09-12 07:53:49 +00:00
if ( ext ) {
i = ldap_modify_ext ( ld - > link , dn , ldap_mods , lserverctrls , NULL , & msgid ) ;
} else {
i = ldap_modify_ext_s ( ld - > link , dn , ldap_mods , lserverctrls , NULL ) ;
}
if ( i ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Modify: %s " , ldap_err2string ( i ) ) ;
1999-04-22 00:45:14 +00:00
RETVAL_FALSE ;
2017-09-12 07:53:49 +00:00
} else if ( ext ) {
i = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( i = = - 1 ) {
php_error_docref ( NULL , E_WARNING , " Modify operation failed " ) ;
RETVAL_FALSE ;
goto cleanup ;
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2015-01-03 09:22:58 +00:00
} else RETVAL_TRUE ;
1999-04-22 00:45:14 +00:00
}
2017-09-07 09:04:52 +00:00
cleanup :
2003-06-08 23:34:51 +00:00
for ( i = 0 ; i < num_attribs ; i + + ) {
1999-04-22 00:45:14 +00:00
efree ( ldap_mods [ i ] - > mod_type ) ;
2003-06-08 23:34:51 +00:00
for ( j = 0 ; j < num_berval [ i ] ; j + + ) {
2000-07-28 21:31:02 +00:00
efree ( ldap_mods [ i ] - > mod_bvalues [ j ] ) ;
}
efree ( ldap_mods [ i ] - > mod_bvalues ) ;
1999-04-22 00:45:14 +00:00
efree ( ldap_mods [ i ] ) ;
}
2000-07-28 21:31:02 +00:00
efree ( num_berval ) ;
2015-01-03 09:22:58 +00:00
efree ( ldap_mods ) ;
2017-09-12 07:53:49 +00:00
2017-09-07 09:04:52 +00:00
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
1999-04-22 00:45:14 +00:00
return ;
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-07-23 21:32:02 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Add entries to LDAP directory */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_add )
1999-04-22 00:45:14 +00:00
{
1999-05-21 10:06:25 +00:00
/* 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 */
2017-09-12 07:53:49 +00:00
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_LD_FULL_ADD , 0 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Add entries to LDAP directory */
2017-09-12 07:53:49 +00:00
PHP_FUNCTION ( ldap_add_ext )
{
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_LD_FULL_ADD , 1 ) ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
1999-05-21 10:06:25 +00:00
/* three functions for attribute base modifications, gerrit Thomson */
2020-07-01 13:32:55 +00:00
/* {{{ Replace attribute values with new ones */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_mod_replace )
{
2017-09-12 07:53:49 +00:00
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_REPLACE , 0 ) ;
2001-05-31 21:09:30 +00:00
}
1999-05-21 10:06:25 +00:00
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Replace attribute values with new ones */
2017-09-12 09:13:23 +00:00
PHP_FUNCTION ( ldap_mod_replace_ext )
{
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_REPLACE , 1 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Add attribute values to current */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_mod_add )
{
2017-09-12 07:53:49 +00:00
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_ADD , 0 ) ;
1999-05-21 10:06:25 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Add attribute values to current */
2017-09-12 09:13:23 +00:00
PHP_FUNCTION ( ldap_mod_add_ext )
{
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_ADD , 1 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Delete attribute values */
1999-05-21 10:06:25 +00:00
PHP_FUNCTION ( ldap_mod_del )
{
2017-09-12 07:53:49 +00:00
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_DELETE , 0 ) ;
1999-05-21 10:06:25 +00:00
}
2000-07-23 21:32:02 +00:00
/* }}} */
1999-05-21 10:06:25 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Delete attribute values */
2017-09-12 09:13:23 +00:00
PHP_FUNCTION ( ldap_mod_del_ext )
{
php_ldap_do_modify ( INTERNAL_FUNCTION_PARAM_PASSTHRU , LDAP_MOD_DELETE , 1 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ php_ldap_do_delete */
2017-09-12 09:39:00 +00:00
static void php_ldap_do_delete ( INTERNAL_FUNCTION_PARAMETERS , int ext )
1999-04-22 00:45:14 +00:00
{
2017-09-07 15:03:45 +00:00
zval * serverctrls = NULL ;
2008-04-16 14:21:04 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2017-09-12 09:39:00 +00:00
LDAPMessage * ldap_res ;
2008-04-16 14:21:04 +00:00
char * dn ;
2017-09-12 09:39:00 +00:00
int rc , msgid ;
2014-08-28 07:43:14 +00:00
size_t dn_len ;
1999-04-22 00:45:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Os|a! " , & link , ldap_link_ce , & dn , & dn_len , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
1999-04-22 00:45:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
1999-04-22 00:45:14 +00:00
2017-09-07 09:21:47 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 3 ) ;
2017-09-07 09:21:47 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
2017-09-12 09:39:00 +00:00
if ( ext ) {
rc = ldap_delete_ext ( ld - > link , dn , lserverctrls , NULL , & msgid ) ;
} else {
rc = ldap_delete_ext_s ( ld - > link , dn , lserverctrls , NULL ) ;
}
if ( rc ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Delete: %s " , ldap_err2string ( rc ) ) ;
2017-09-07 09:21:47 +00:00
RETVAL_FALSE ;
2017-09-12 09:39:00 +00:00
goto cleanup ;
} else if ( ext ) {
rc = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( rc = = - 1 ) {
php_error_docref ( NULL , E_WARNING , " Delete operation failed " ) ;
RETVAL_FALSE ;
goto cleanup ;
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2017-09-07 09:21:47 +00:00
} else {
RETVAL_TRUE ;
1999-04-22 00:45:14 +00:00
}
2017-09-07 09:21:47 +00:00
cleanup :
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
return ;
1999-04-22 00:45:14 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Delete an entry from a directory */
2017-09-12 09:39:00 +00:00
PHP_FUNCTION ( ldap_delete )
{
php_ldap_do_delete ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Delete an entry from a directory */
2017-09-12 09:39:00 +00:00
PHP_FUNCTION ( ldap_delete_ext )
{
php_ldap_do_delete ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ _ldap_str_equal_to_const */
2017-07-25 15:56:05 +00:00
static size_t _ldap_str_equal_to_const ( const char * str , size_t str_len , const char * cstr )
2014-01-22 17:54:11 +00:00
{
2017-07-25 15:56:05 +00:00
size_t i ;
2014-01-22 17:54:11 +00:00
if ( strlen ( cstr ) ! = str_len )
return 0 ;
for ( i = 0 ; i < str_len ; + + i ) {
if ( str [ i ] ! = cstr [ i ] ) {
return 0 ;
}
}
return 1 ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ _ldap_strlen_max */
2017-07-25 15:56:05 +00:00
static size_t _ldap_strlen_max ( const char * str , size_t max_len )
2014-01-22 17:54:11 +00:00
{
2017-07-25 15:56:05 +00:00
size_t i ;
2014-01-22 17:54:11 +00:00
for ( i = 0 ; i < max_len ; + + i ) {
if ( str [ i ] = = ' \0 ' ) {
return i ;
}
}
return max_len ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ _ldap_hash_fetch */
2014-01-22 17:54:11 +00:00
static void _ldap_hash_fetch ( zval * hashTbl , const char * key , zval * * out )
{
2014-05-20 03:26:26 +00:00
* out = zend_hash_str_find ( Z_ARRVAL_P ( hashTbl ) , key , strlen ( key ) ) ;
2014-01-22 17:54:11 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Perform multiple modifications as part of one operation */
2014-01-22 17:54:11 +00:00
PHP_FUNCTION ( ldap_modify_batch )
{
2017-09-07 15:03:45 +00:00
zval * serverctrls = NULL ;
2014-01-22 17:54:11 +00:00
ldap_linkdata * ld ;
2019-06-13 20:12:34 +00:00
zval * link , * mods , * mod , * modinfo ;
zend_string * modval ;
2014-01-22 17:54:11 +00:00
zval * attrib , * modtype , * vals ;
2014-05-20 03:26:26 +00:00
zval * fetched ;
2014-01-22 17:54:11 +00:00
char * dn ;
2014-08-27 13:31:48 +00:00
size_t dn_len ;
2014-01-22 17:54:11 +00:00
int i , j , k ;
int num_mods , num_modprops , num_modvals ;
LDAPMod * * ldap_mods ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2016-11-26 14:18:42 +00:00
uint32_t oper ;
2014-01-22 17:54:11 +00:00
/*
$ mods = array (
array (
" attrib " = > " unicodePwd " ,
" modtype " = > LDAP_MODIFY_BATCH_REMOVE ,
" values " = > array ( $ oldpw )
) ,
array (
" attrib " = > " unicodePwd " ,
" modtype " = > LDAP_MODIFY_BATCH_ADD ,
" values " = > array ( $ newpw )
) ,
array (
" attrib " = > " userPrincipalName " ,
" modtype " = > LDAP_MODIFY_BATCH_REPLACE ,
" values " = > array ( " janitor@corp.contoso.com " )
) ,
array (
" attrib " = > " userCert " ,
" modtype " = > LDAP_MODIFY_BATCH_REMOVE_ALL
)
) ;
*/
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Osa/|a! " , & link , ldap_link_ce , & dn , & dn_len , & mods , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2014-01-22 17:54:11 +00:00
/* perform validation */
{
2014-05-20 03:26:26 +00:00
zend_string * modkey ;
2014-08-25 17:24:55 +00:00
zend_long modtype ;
2014-01-22 17:54:11 +00:00
/* to store the wrongly-typed keys */
2014-08-25 17:24:55 +00:00
zend_ulong tmpUlong ;
2014-01-22 17:54:11 +00:00
/* make sure the DN contains no NUL bytes */
2017-07-25 15:56:05 +00:00
if ( _ldap_strlen_max ( dn , dn_len ) ! = dn_len ) {
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 2 , " must not contain null bytes " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* make sure the top level is a normal array */
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( mods ) ) ;
2014-08-25 17:24:55 +00:00
if ( zend_hash_get_current_key_type ( Z_ARRVAL_P ( mods ) ) ! = HASH_KEY_IS_LONG ) {
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 3 , " must be integer-indexed " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
num_mods = zend_hash_num_elements ( Z_ARRVAL_P ( mods ) ) ;
for ( i = 0 ; i < num_mods ; i + + ) {
/* is the numbering consecutive? */
2014-05-20 03:26:26 +00:00
if ( ( fetched = zend_hash_index_find ( Z_ARRVAL_P ( mods ) , i ) ) = = NULL ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " must have consecutive integer indices starting from 0 " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2014-05-20 03:26:26 +00:00
mod = fetched ;
2014-01-22 17:54:11 +00:00
/* is it an array? */
if ( Z_TYPE_P ( mod ) ! = IS_ARRAY ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " must only contain arrays " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2017-01-19 04:23:23 +00:00
SEPARATE_ARRAY ( mod ) ;
2014-01-22 17:54:11 +00:00
/* for the modification hashtable... */
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( mod ) ) ;
num_modprops = zend_hash_num_elements ( Z_ARRVAL_P ( mod ) ) ;
for ( j = 0 ; j < num_modprops ; j + + ) {
/* are the keys strings? */
2014-12-23 21:00:18 +00:00
if ( zend_hash_get_current_key ( Z_ARRVAL_P ( mod ) , & modkey , & tmpUlong ) ! = HASH_KEY_IS_STRING ) {
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 3 , " must only contain string-indexed arrays " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* is this a valid entry? */
if (
2015-06-30 10:59:27 +00:00
! _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_ATTRIB ) & &
! _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_MODTYPE ) & &
! _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_VALUES )
2014-01-22 17:54:11 +00:00
) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " must contain arrays only containing the \" " LDAP_MODIFY_BATCH_ATTRIB " \" , \" " LDAP_MODIFY_BATCH_MODTYPE " \" and \" " LDAP_MODIFY_BATCH_VALUES " \" keys " ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2014-05-20 03:26:26 +00:00
fetched = zend_hash_get_current_data ( Z_ARRVAL_P ( mod ) ) ;
modinfo = fetched ;
2014-01-22 17:54:11 +00:00
/* does the value type match the key? */
2015-06-30 10:59:27 +00:00
if ( _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_ATTRIB ) ) {
2014-01-22 17:54:11 +00:00
if ( Z_TYPE_P ( modinfo ) ! = IS_STRING ) {
2020-09-03 14:21:36 +00:00
zend_type_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_ATTRIB " \" must be of type string, %s given " , get_active_function_name ( ) , zend_zval_type_name ( modinfo ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2017-07-25 15:56:05 +00:00
if ( Z_STRLEN_P ( modinfo ) ! = _ldap_strlen_max ( Z_STRVAL_P ( modinfo ) , Z_STRLEN_P ( modinfo ) ) ) {
2020-09-03 14:21:36 +00:00
zend_type_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_ATTRIB " \" cannot contain null-bytes " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
}
2015-06-30 10:59:27 +00:00
else if ( _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_MODTYPE ) ) {
2014-08-25 17:24:55 +00:00
if ( Z_TYPE_P ( modinfo ) ! = IS_LONG ) {
2020-09-03 14:21:36 +00:00
zend_type_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_MODTYPE " \" must be of type int, %s given " , get_active_function_name ( ) , zend_zval_type_name ( modinfo ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* is the value in range? */
2014-08-25 17:24:55 +00:00
modtype = Z_LVAL_P ( modinfo ) ;
2014-01-22 17:54:11 +00:00
if (
modtype ! = LDAP_MODIFY_BATCH_ADD & &
modtype ! = LDAP_MODIFY_BATCH_REMOVE & &
modtype ! = LDAP_MODIFY_BATCH_REPLACE & &
modtype ! = LDAP_MODIFY_BATCH_REMOVE_ALL
) {
2020-09-20 08:41:10 +00:00
zend_value_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_MODTYPE " \" must be one of the LDAP_MODIFY_BATCH_* constants " , get_active_function_name ( ) ) ;
2020-09-03 14:21:36 +00:00
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* if it's REMOVE_ALL, there must not be a values array; otherwise, there must */
if ( modtype = = LDAP_MODIFY_BATCH_REMOVE_ALL ) {
2014-05-20 03:26:26 +00:00
if ( zend_hash_str_exists ( Z_ARRVAL_P ( mod ) , LDAP_MODIFY_BATCH_VALUES , strlen ( LDAP_MODIFY_BATCH_VALUES ) ) ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): If option \" " LDAP_MODIFY_BATCH_MODTYPE " \" is LDAP_MODIFY_BATCH_REMOVE_ALL, option \" " LDAP_MODIFY_BATCH_VALUES " \" cannot be provided " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
}
else {
2014-05-20 03:26:26 +00:00
if ( ! zend_hash_str_exists ( Z_ARRVAL_P ( mod ) , LDAP_MODIFY_BATCH_VALUES , strlen ( LDAP_MODIFY_BATCH_VALUES ) ) ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): If option \" " LDAP_MODIFY_BATCH_MODTYPE " \" is not LDAP_MODIFY_BATCH_REMOVE_ALL, option \" " LDAP_MODIFY_BATCH_VALUES " \" must be provided " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
}
}
2015-06-30 10:59:27 +00:00
else if ( _ldap_str_equal_to_const ( ZSTR_VAL ( modkey ) , ZSTR_LEN ( modkey ) , LDAP_MODIFY_BATCH_VALUES ) ) {
2014-01-22 17:54:11 +00:00
if ( Z_TYPE_P ( modinfo ) ! = IS_ARRAY ) {
2020-09-03 14:21:36 +00:00
zend_type_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_VALUES " \" must be of type array, %s given " , get_active_function_name ( ) , zend_zval_type_name ( modinfo ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
2017-01-19 04:23:23 +00:00
SEPARATE_ARRAY ( modinfo ) ;
2014-01-22 17:54:11 +00:00
/* is the array not empty? */
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( modinfo ) ) ;
num_modvals = zend_hash_num_elements ( Z_ARRVAL_P ( modinfo ) ) ;
if ( num_modvals = = 0 ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_VALUES " \" cannot be empty " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* are its keys integers? */
2014-08-25 17:24:55 +00:00
if ( zend_hash_get_current_key_type ( Z_ARRVAL_P ( modinfo ) ) ! = HASH_KEY_IS_LONG ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_VALUES " \" must be integer-indexed " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
/* are the keys consecutive? */
for ( k = 0 ; k < num_modvals ; k + + ) {
2014-05-20 03:26:26 +00:00
if ( ( fetched = zend_hash_index_find ( Z_ARRVAL_P ( modinfo ) , k ) ) = = NULL ) {
2020-09-03 14:21:36 +00:00
zend_value_error ( " %s(): Option \" " LDAP_MODIFY_BATCH_VALUES " \" must have consecutive integer indices starting from 0 " , get_active_function_name ( ) ) ;
RETURN_THROWS ( ) ;
2014-01-22 17:54:11 +00:00
}
}
}
zend_hash_move_forward ( Z_ARRVAL_P ( mod ) ) ;
}
}
}
/* validation was successful */
/* allocate array of modifications */
ldap_mods = safe_emalloc ( ( num_mods + 1 ) , sizeof ( LDAPMod * ) , 0 ) ;
/* for each modification */
for ( i = 0 ; i < num_mods ; i + + ) {
/* allocate the modification struct */
ldap_mods [ i ] = safe_emalloc ( 1 , sizeof ( LDAPMod ) , 0 ) ;
/* fetch the relevant data */
2014-05-20 03:26:26 +00:00
fetched = zend_hash_index_find ( Z_ARRVAL_P ( mods ) , i ) ;
mod = fetched ;
2014-01-22 17:54:11 +00:00
_ldap_hash_fetch ( mod , LDAP_MODIFY_BATCH_ATTRIB , & attrib ) ;
_ldap_hash_fetch ( mod , LDAP_MODIFY_BATCH_MODTYPE , & modtype ) ;
_ldap_hash_fetch ( mod , LDAP_MODIFY_BATCH_VALUES , & vals ) ;
/* map the modification type */
2014-08-25 17:24:55 +00:00
switch ( Z_LVAL_P ( modtype ) ) {
2014-01-22 17:54:11 +00:00
case LDAP_MODIFY_BATCH_ADD :
oper = LDAP_MOD_ADD ;
break ;
case LDAP_MODIFY_BATCH_REMOVE :
case LDAP_MODIFY_BATCH_REMOVE_ALL :
oper = LDAP_MOD_DELETE ;
break ;
case LDAP_MODIFY_BATCH_REPLACE :
oper = LDAP_MOD_REPLACE ;
break ;
default :
2016-06-11 17:07:28 +00:00
zend_throw_error ( NULL , " Unknown and uncaught modification type. " ) ;
2015-07-05 07:37:49 +00:00
RETVAL_FALSE ;
2015-07-06 04:25:53 +00:00
efree ( ldap_mods [ i ] ) ;
num_mods = i ;
2015-07-05 07:37:49 +00:00
goto cleanup ;
2014-01-22 17:54:11 +00:00
}
/* fill in the basic info */
ldap_mods [ i ] - > mod_op = oper | LDAP_MOD_BVALUES ;
2014-08-25 17:24:55 +00:00
ldap_mods [ i ] - > mod_type = estrndup ( Z_STRVAL_P ( attrib ) , Z_STRLEN_P ( attrib ) ) ;
2014-01-22 17:54:11 +00:00
2014-08-25 17:24:55 +00:00
if ( Z_LVAL_P ( modtype ) = = LDAP_MODIFY_BATCH_REMOVE_ALL ) {
2014-01-22 17:54:11 +00:00
/* no values */
ldap_mods [ i ] - > mod_bvalues = NULL ;
}
else {
/* allocate space for the values as part of this modification */
num_modvals = zend_hash_num_elements ( Z_ARRVAL_P ( vals ) ) ;
ldap_mods [ i ] - > mod_bvalues = safe_emalloc ( ( num_modvals + 1 ) , sizeof ( struct berval * ) , 0 ) ;
/* for each value */
for ( j = 0 ; j < num_modvals ; j + + ) {
/* fetch it */
2014-05-20 03:26:26 +00:00
fetched = zend_hash_index_find ( Z_ARRVAL_P ( vals ) , j ) ;
2019-06-13 20:12:34 +00:00
modval = zval_get_string ( fetched ) ;
if ( EG ( exception ) ) {
RETVAL_FALSE ;
ldap_mods [ i ] - > mod_bvalues [ j ] = NULL ;
num_mods = i + 1 ;
goto cleanup ;
}
2014-01-22 17:54:11 +00:00
/* allocate the data struct */
ldap_mods [ i ] - > mod_bvalues [ j ] = safe_emalloc ( 1 , sizeof ( struct berval ) , 0 ) ;
/* fill it */
2019-06-13 20:12:34 +00:00
ldap_mods [ i ] - > mod_bvalues [ j ] - > bv_len = ZSTR_LEN ( modval ) ;
ldap_mods [ i ] - > mod_bvalues [ j ] - > bv_val = estrndup ( ZSTR_VAL ( modval ) , ZSTR_LEN ( modval ) ) ;
2019-06-14 09:11:24 +00:00
zend_string_release ( modval ) ;
2014-01-22 17:54:11 +00:00
}
/* NULL-terminate values */
ldap_mods [ i ] - > mod_bvalues [ num_modvals ] = NULL ;
}
}
/* NULL-terminate modifications */
ldap_mods [ num_mods ] = NULL ;
2017-09-07 12:42:34 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 4 ) ;
2017-09-07 12:42:34 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
2014-01-22 17:54:11 +00:00
/* perform (finally) */
2017-09-07 15:03:45 +00:00
if ( ( i = ldap_modify_ext_s ( ld - > link , dn , ldap_mods , lserverctrls , NULL ) ) ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Batch Modify: %s " , ldap_err2string ( i ) ) ;
2014-01-22 17:54:11 +00:00
RETVAL_FALSE ;
} else RETVAL_TRUE ;
/* clean up */
2015-07-05 07:37:49 +00:00
cleanup : {
2014-01-22 17:54:11 +00:00
for ( i = 0 ; i < num_mods ; i + + ) {
/* attribute */
efree ( ldap_mods [ i ] - > mod_type ) ;
if ( ldap_mods [ i ] - > mod_bvalues ! = NULL ) {
/* each BER value */
for ( j = 0 ; ldap_mods [ i ] - > mod_bvalues [ j ] ! = NULL ; j + + ) {
/* free the data bytes */
efree ( ldap_mods [ i ] - > mod_bvalues [ j ] - > bv_val ) ;
/* free the bvalue struct */
efree ( ldap_mods [ i ] - > mod_bvalues [ j ] ) ;
}
/* the BER value array */
efree ( ldap_mods [ i ] - > mod_bvalues ) ;
}
/* the modification */
efree ( ldap_mods [ i ] ) ;
}
/* the modifications array */
efree ( ldap_mods ) ;
2017-09-07 12:42:34 +00:00
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
2014-01-22 17:54:11 +00:00
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get the current ldap error number */
2001-05-31 21:09:30 +00:00
PHP_FUNCTION ( ldap_errno )
{
2008-04-16 14:21:04 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2000-04-06 12:36:47 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & link , ldap_link_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-04-06 12:36:47 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2001-05-31 21:09:30 +00:00
2014-08-25 17:24:55 +00:00
RETURN_LONG ( _get_lderrno ( ld - > link ) ) ;
2000-04-06 12:36:47 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Convert error number to error string */
2001-05-31 21:09:30 +00:00
PHP_FUNCTION ( ldap_err2str )
{
2014-08-25 17:24:55 +00:00
zend_long perrno ;
2000-04-06 12:36:47 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l " , & perrno ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-04-06 12:36:47 +00:00
}
2001-05-31 21:09:30 +00:00
2014-05-20 03:26:26 +00:00
RETURN_STRING ( ldap_err2string ( perrno ) ) ;
2000-04-06 12:36:47 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get the current ldap error string */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_error )
2001-05-31 21:09:30 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2000-04-06 12:36:47 +00:00
int ld_errno ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & link , ldap_link_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-04-06 12:36:47 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2000-04-06 12:36:47 +00:00
2001-11-29 20:17:17 +00:00
ld_errno = _get_lderrno ( ld - > link ) ;
2000-04-06 12:36:47 +00:00
2014-05-20 03:26:26 +00:00
RETURN_STRING ( ldap_err2string ( ld_errno ) ) ;
2000-04-06 12:36:47 +00:00
}
2000-04-06 16:57:33 +00:00
/* }}} */
2000-07-26 11:01:44 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Determine if an entry has a specific value for one of its attributes */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_compare )
2001-05-31 21:09:30 +00:00
{
2017-09-07 15:03:45 +00:00
zval * serverctrls = NULL ;
2008-04-16 14:21:04 +00:00
zval * link ;
char * dn , * attr , * value ;
2014-08-28 07:43:14 +00:00
size_t dn_len , attr_len , value_len ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2021-05-12 14:17:31 +00:00
int ldap_errno ;
2015-06-29 15:14:14 +00:00
struct berval lvalue ;
2000-07-26 11:01:44 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Osss|a! " , & link , ldap_link_ce , & dn , & dn_len , & attr , & attr_len , & value , & value_len , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-07-26 11:01:44 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2000-07-26 11:01:44 +00:00
2017-09-07 10:19:36 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 5 ) ;
2017-09-07 10:19:36 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
2015-06-23 14:44:48 +00:00
lvalue . bv_val = value ;
lvalue . bv_len = value_len ;
2021-05-12 14:17:31 +00:00
ldap_errno = ldap_compare_ext_s ( ld - > link , dn , attr , & lvalue , lserverctrls , NULL ) ;
2000-07-26 11:01:44 +00:00
2021-05-12 14:17:31 +00:00
switch ( ldap_errno ) {
2003-06-08 23:34:51 +00:00
case LDAP_COMPARE_TRUE :
2017-09-07 10:19:36 +00:00
RETVAL_TRUE ;
2003-06-08 23:34:51 +00:00
break ;
2000-07-26 11:01:44 +00:00
2003-06-08 23:34:51 +00:00
case LDAP_COMPARE_FALSE :
2017-09-07 10:19:36 +00:00
RETVAL_FALSE ;
2003-06-08 23:34:51 +00:00
break ;
2017-09-07 10:19:36 +00:00
default :
2021-05-12 14:17:31 +00:00
php_error_docref ( NULL , E_WARNING , " Compare: %s " , ldap_err2string ( ldap_errno ) ) ;
2017-09-07 10:19:36 +00:00
RETVAL_LONG ( - 1 ) ;
}
cleanup :
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
2015-01-03 09:22:58 +00:00
2017-09-07 10:19:36 +00:00
return ;
2000-07-26 11:01:44 +00:00
}
/* }}} */
2000-10-17 15:51:04 +00:00
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP)
2020-07-01 13:32:55 +00:00
/* {{{ Get the current value of various session-wide parameters */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_get_option )
2001-05-31 21:09:30 +00:00
{
2008-04-16 14:21:04 +00:00
zval * link , * retval ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2014-08-25 17:24:55 +00:00
zend_long option ;
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Olz " , & link , ldap_link_ce , & option , & retval ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-10-17 16:06:04 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2000-10-17 16:06:04 +00:00
2008-04-16 14:21:04 +00:00
switch ( option ) {
2003-06-08 23:34:51 +00:00
/* options with int value */
2000-10-17 16:06:04 +00:00
case LDAP_OPT_DEREF :
case LDAP_OPT_SIZELIMIT :
case LDAP_OPT_TIMELIMIT :
case LDAP_OPT_PROTOCOL_VERSION :
case LDAP_OPT_ERROR_NUMBER :
case LDAP_OPT_REFERRALS :
2002-07-09 20:54:49 +00:00
# ifdef LDAP_OPT_RESTART
2000-10-17 16:06:04 +00:00
case LDAP_OPT_RESTART :
2016-02-16 08:39:58 +00:00
# endif
2016-06-17 02:00:32 +00:00
# ifdef LDAP_OPT_X_SASL_NOCANON
case LDAP_OPT_X_SASL_NOCANON :
# endif
2016-02-16 08:39:58 +00:00
# ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
case LDAP_OPT_X_TLS_REQUIRE_CERT :
2016-06-15 04:32:59 +00:00
# endif
# ifdef LDAP_OPT_X_TLS_CRLCHECK
case LDAP_OPT_X_TLS_CRLCHECK :
# endif
# ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
case LDAP_OPT_X_TLS_PROTOCOL_MIN :
# endif
# ifdef LDAP_OPT_X_KEEPALIVE_IDLE
case LDAP_OPT_X_KEEPALIVE_IDLE :
case LDAP_OPT_X_KEEPALIVE_PROBES :
case LDAP_OPT_X_KEEPALIVE_INTERVAL :
2002-07-09 20:54:49 +00:00
# endif
2000-10-17 16:06:04 +00:00
{
int val ;
2007-10-06 01:43:26 +00:00
2008-04-16 14:21:04 +00:00
if ( ldap_get_option ( ld - > link , option , & val ) ) {
2000-10-17 16:06:04 +00:00
RETURN_FALSE ;
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_LONG ( retval , val ) ;
2000-10-17 16:06:04 +00:00
} break ;
2008-02-09 21:59:17 +00:00
# ifdef LDAP_OPT_NETWORK_TIMEOUT
2007-10-06 01:43:26 +00:00
case LDAP_OPT_NETWORK_TIMEOUT :
{
2009-11-18 13:37:45 +00:00
struct timeval * timeout = NULL ;
2007-10-06 02:13:50 +00:00
if ( ldap_get_option ( ld - > link , LDAP_OPT_NETWORK_TIMEOUT , ( void * ) & timeout ) ) {
2007-10-06 01:43:26 +00:00
if ( timeout ) {
ldap_memfree ( timeout ) ;
}
RETURN_FALSE ;
2015-01-03 09:22:58 +00:00
}
2009-11-18 13:37:45 +00:00
if ( ! timeout ) {
RETURN_FALSE ;
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_LONG ( retval , timeout - > tv_sec ) ;
2007-10-06 01:43:26 +00:00
ldap_memfree ( timeout ) ;
2008-02-09 21:59:17 +00:00
} break ;
# elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
case LDAP_X_OPT_CONNECT_TIMEOUT :
{
2007-10-06 02:13:50 +00:00
int timeout ;
if ( ldap_get_option ( ld - > link , LDAP_X_OPT_CONNECT_TIMEOUT , & timeout ) ) {
RETURN_FALSE ;
2015-01-03 09:22:58 +00:00
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_LONG ( retval , ( timeout / 1000 ) ) ;
2007-10-06 01:43:26 +00:00
} break ;
2015-09-09 16:02:10 +00:00
# endif
# ifdef LDAP_OPT_TIMEOUT
case LDAP_OPT_TIMEOUT :
{
struct timeval * timeout = NULL ;
if ( ldap_get_option ( ld - > link , LDAP_OPT_TIMEOUT , ( void * ) & timeout ) ) {
if ( timeout ) {
ldap_memfree ( timeout ) ;
}
RETURN_FALSE ;
}
if ( ! timeout ) {
RETURN_FALSE ;
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_LONG ( retval , timeout - > tv_sec ) ;
2015-09-09 16:02:10 +00:00
ldap_memfree ( timeout ) ;
} break ;
2007-10-06 01:43:26 +00:00
# endif
2003-06-08 23:34:51 +00:00
/* options with string value */
2000-10-17 16:06:04 +00:00
case LDAP_OPT_ERROR_STRING :
2005-05-08 15:43:22 +00:00
# ifdef LDAP_OPT_HOST_NAME
case LDAP_OPT_HOST_NAME :
# endif
2005-04-17 16:25:59 +00:00
# ifdef HAVE_LDAP_SASL
2015-01-03 09:22:58 +00:00
case LDAP_OPT_X_SASL_MECH :
2005-04-17 16:25:59 +00:00
case LDAP_OPT_X_SASL_REALM :
case LDAP_OPT_X_SASL_AUTHCID :
case LDAP_OPT_X_SASL_AUTHZID :
# endif
2016-06-17 02:00:32 +00:00
# ifdef LDAP_OPT_X_SASL_USERNAME
case LDAP_OPT_X_SASL_USERNAME :
# endif
2016-06-15 04:32:59 +00:00
# if (LDAP_API_VERSION > 2000)
case LDAP_OPT_X_TLS_CACERTDIR :
case LDAP_OPT_X_TLS_CACERTFILE :
case LDAP_OPT_X_TLS_CERTFILE :
case LDAP_OPT_X_TLS_CIPHER_SUITE :
case LDAP_OPT_X_TLS_KEYFILE :
case LDAP_OPT_X_TLS_RANDOM_FILE :
# endif
# ifdef LDAP_OPT_X_TLS_PACKAGE
case LDAP_OPT_X_TLS_PACKAGE :
# endif
# ifdef LDAP_OPT_X_TLS_CRLFILE
case LDAP_OPT_X_TLS_CRLFILE :
# endif
# ifdef LDAP_OPT_X_TLS_DHFILE
case LDAP_OPT_X_TLS_DHFILE :
# endif
2001-01-07 21:18:02 +00:00
# ifdef LDAP_OPT_MATCHED_DN
2000-10-17 16:06:04 +00:00
case LDAP_OPT_MATCHED_DN :
2000-11-03 22:53:49 +00:00
# endif
2003-06-08 23:34:51 +00:00
{
2003-10-06 23:33:00 +00:00
char * val = NULL ;
2008-04-16 14:21:04 +00:00
if ( ldap_get_option ( ld - > link , option , & val ) | | val = = NULL | | * val = = ' \0 ' ) {
2003-10-07 00:36:31 +00:00
if ( val ) {
ldap_memfree ( val ) ;
2003-10-06 23:33:00 +00:00
}
RETURN_FALSE ;
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRING ( retval , val ) ;
2003-10-07 00:36:31 +00:00
ldap_memfree ( val ) ;
2000-10-17 16:06:04 +00:00
} break ;
case LDAP_OPT_SERVER_CONTROLS :
case LDAP_OPT_CLIENT_CONTROLS :
2017-07-04 15:08:57 +00:00
{
2017-07-20 10:17:59 +00:00
LDAPControl * * ctrls = NULL ;
2017-07-04 15:08:57 +00:00
if ( ldap_get_option ( ld - > link , option , & ctrls ) | | ctrls = = NULL ) {
if ( ctrls ) {
ldap_memfree ( ctrls ) ;
}
RETURN_FALSE ;
}
2017-09-12 10:04:17 +00:00
_php_ldap_controls_to_array ( ld - > link , ctrls , retval , 1 ) ;
2017-07-04 15:08:57 +00:00
} break ;
/* options not implemented
2000-10-17 16:06:04 +00:00
case LDAP_OPT_API_INFO :
case LDAP_OPT_API_FEATURE_INFO :
2000-10-28 19:22:46 +00:00
*/
2000-10-17 16:06:04 +00:00
default :
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Set the value of various session-wide parameters */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_set_option )
2001-05-31 21:09:30 +00:00
{
2021-03-13 11:11:40 +00:00
zval * link = NULL , * newval ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2001-12-23 16:32:06 +00:00
LDAP * ldap ;
2014-08-25 17:24:55 +00:00
zend_long option ;
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O!lz " , & link , ldap_link_ce , & option , & newval ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-10-17 16:06:04 +00:00
}
2021-03-13 11:11:40 +00:00
if ( ! link ) {
2001-12-23 16:32:06 +00:00
ldap = NULL ;
} else {
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2001-12-23 16:32:06 +00:00
ldap = ld - > link ;
}
2001-05-31 21:09:30 +00:00
2008-04-16 14:21:04 +00:00
switch ( option ) {
2005-04-17 16:25:59 +00:00
/* options with int value */
2000-10-17 16:06:04 +00:00
case LDAP_OPT_DEREF :
case LDAP_OPT_SIZELIMIT :
case LDAP_OPT_TIMELIMIT :
case LDAP_OPT_PROTOCOL_VERSION :
case LDAP_OPT_ERROR_NUMBER :
2001-12-23 16:32:06 +00:00
# ifdef LDAP_OPT_DEBUG_LEVEL
case LDAP_OPT_DEBUG_LEVEL :
2016-02-16 08:39:58 +00:00
# endif
# ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
case LDAP_OPT_X_TLS_REQUIRE_CERT :
2016-06-15 04:32:59 +00:00
# endif
# ifdef LDAP_OPT_X_TLS_CRLCHECK
case LDAP_OPT_X_TLS_CRLCHECK :
# endif
# ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
case LDAP_OPT_X_TLS_PROTOCOL_MIN :
# endif
# ifdef LDAP_OPT_X_KEEPALIVE_IDLE
case LDAP_OPT_X_KEEPALIVE_IDLE :
case LDAP_OPT_X_KEEPALIVE_PROBES :
case LDAP_OPT_X_KEEPALIVE_INTERVAL :
2001-12-23 16:32:06 +00:00
# endif
2000-10-17 16:06:04 +00:00
{
int val ;
2007-10-06 01:43:26 +00:00
2021-01-14 11:06:07 +00:00
convert_to_long ( newval ) ;
2017-07-25 15:56:05 +00:00
if ( ZEND_LONG_EXCEEDS_INT ( Z_LVAL_P ( newval ) ) ) {
2020-09-03 14:21:36 +00:00
zend_argument_value_error ( 3 , " is too large " ) ;
RETURN_THROWS ( ) ;
2017-07-25 15:56:05 +00:00
}
val = ( int ) Z_LVAL_P ( newval ) ;
2008-04-16 14:21:04 +00:00
if ( ldap_set_option ( ldap , option , & val ) ) {
2000-10-17 16:06:04 +00:00
RETURN_FALSE ;
}
} break ;
2008-02-09 21:59:17 +00:00
# ifdef LDAP_OPT_NETWORK_TIMEOUT
2007-10-06 01:43:26 +00:00
case LDAP_OPT_NETWORK_TIMEOUT :
{
struct timeval timeout ;
2007-10-06 02:13:50 +00:00
2021-01-14 11:06:07 +00:00
convert_to_long ( newval ) ;
2014-08-25 17:24:55 +00:00
timeout . tv_sec = Z_LVAL_P ( newval ) ;
2007-10-06 01:43:26 +00:00
timeout . tv_usec = 0 ;
2007-10-06 02:13:50 +00:00
if ( ldap_set_option ( ldap , LDAP_OPT_NETWORK_TIMEOUT , ( void * ) & timeout ) ) {
2007-10-06 01:43:26 +00:00
RETURN_FALSE ;
2015-01-03 09:22:58 +00:00
}
2008-02-09 21:59:17 +00:00
} break ;
# elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
case LDAP_X_OPT_CONNECT_TIMEOUT :
{
2007-10-06 02:13:50 +00:00
int timeout ;
2021-01-14 11:06:07 +00:00
convert_to_long ( newval ) ;
2014-08-25 17:24:55 +00:00
timeout = 1000 * Z_LVAL_P ( newval ) ; /* Convert to milliseconds */
2007-10-06 02:13:50 +00:00
if ( ldap_set_option ( ldap , LDAP_X_OPT_CONNECT_TIMEOUT , & timeout ) ) {
RETURN_FALSE ;
2015-01-03 09:22:58 +00:00
}
2007-10-06 01:43:26 +00:00
} break ;
2015-09-09 16:02:10 +00:00
# endif
# ifdef LDAP_OPT_TIMEOUT
case LDAP_OPT_TIMEOUT :
{
struct timeval timeout ;
2021-01-14 11:06:07 +00:00
convert_to_long ( newval ) ;
2015-09-10 17:24:11 +00:00
timeout . tv_sec = Z_LVAL_P ( newval ) ;
2015-09-09 16:02:10 +00:00
timeout . tv_usec = 0 ;
if ( ldap_set_option ( ldap , LDAP_OPT_TIMEOUT , ( void * ) & timeout ) ) {
RETURN_FALSE ;
}
} break ;
2007-10-06 01:43:26 +00:00
# endif
2000-10-17 16:06:04 +00:00
/* options with string value */
case LDAP_OPT_ERROR_STRING :
2005-05-08 15:43:22 +00:00
# ifdef LDAP_OPT_HOST_NAME
case LDAP_OPT_HOST_NAME :
# endif
2005-04-17 16:25:59 +00:00
# ifdef HAVE_LDAP_SASL
2015-01-03 09:22:58 +00:00
case LDAP_OPT_X_SASL_MECH :
2005-04-17 16:25:59 +00:00
case LDAP_OPT_X_SASL_REALM :
case LDAP_OPT_X_SASL_AUTHCID :
case LDAP_OPT_X_SASL_AUTHZID :
# endif
2016-06-15 04:32:59 +00:00
# if (LDAP_API_VERSION > 2000)
case LDAP_OPT_X_TLS_CACERTDIR :
case LDAP_OPT_X_TLS_CACERTFILE :
case LDAP_OPT_X_TLS_CERTFILE :
case LDAP_OPT_X_TLS_CIPHER_SUITE :
case LDAP_OPT_X_TLS_KEYFILE :
case LDAP_OPT_X_TLS_RANDOM_FILE :
# endif
# ifdef LDAP_OPT_X_TLS_CRLFILE
case LDAP_OPT_X_TLS_CRLFILE :
# endif
# ifdef LDAP_OPT_X_TLS_DHFILE
case LDAP_OPT_X_TLS_DHFILE :
# endif
2001-01-08 18:13:08 +00:00
# ifdef LDAP_OPT_MATCHED_DN
2000-10-17 16:06:04 +00:00
case LDAP_OPT_MATCHED_DN :
2000-11-03 22:53:49 +00:00
# endif
2000-10-17 16:06:04 +00:00
{
2019-06-13 18:58:45 +00:00
zend_string * val ;
val = zval_get_string ( newval ) ;
if ( EG ( exception ) ) {
2020-01-03 19:44:29 +00:00
RETURN_THROWS ( ) ;
2019-06-13 18:58:45 +00:00
}
if ( ldap_set_option ( ldap , option , ZSTR_VAL ( val ) ) ) {
2019-06-14 09:11:24 +00:00
zend_string_release ( val ) ;
2000-10-17 16:06:04 +00:00
RETURN_FALSE ;
}
2019-06-14 09:11:24 +00:00
zend_string_release ( val ) ;
2000-10-17 16:06:04 +00:00
} break ;
/* options with boolean value */
case LDAP_OPT_REFERRALS :
2002-07-09 20:54:49 +00:00
# ifdef LDAP_OPT_RESTART
2000-10-17 16:06:04 +00:00
case LDAP_OPT_RESTART :
2016-06-17 02:00:32 +00:00
# endif
# ifdef LDAP_OPT_X_SASL_NOCANON
case LDAP_OPT_X_SASL_NOCANON :
2002-07-09 20:54:49 +00:00
# endif
2000-10-17 16:06:04 +00:00
{
void * val ;
2019-06-13 18:58:45 +00:00
val = zend_is_true ( newval ) ? LDAP_OPT_ON : LDAP_OPT_OFF ;
2008-04-16 14:21:04 +00:00
if ( ldap_set_option ( ldap , option , val ) ) {
2000-10-17 16:06:04 +00:00
RETURN_FALSE ;
}
} break ;
2001-01-07 21:18:02 +00:00
/* options with control list value */
2000-10-17 16:06:04 +00:00
case LDAP_OPT_SERVER_CONTROLS :
case LDAP_OPT_CLIENT_CONTROLS :
2001-01-07 21:18:02 +00:00
{
2017-07-26 14:41:44 +00:00
LDAPControl * * ctrls ;
2017-07-20 10:17:59 +00:00
int rc ;
2001-01-07 21:18:02 +00:00
2017-07-11 14:12:40 +00:00
if ( Z_TYPE_P ( newval ) ! = IS_ARRAY ) {
2020-09-03 14:21:36 +00:00
zend_argument_type_error ( 3 , " must be of type array for the LDAP_OPT_CLIENT_CONTROLS option, %s given " , zend_zval_type_name ( newval ) ) ;
RETURN_THROWS ( ) ;
2003-06-08 23:34:51 +00:00
}
2015-01-03 09:22:58 +00:00
2020-09-03 14:21:36 +00:00
ctrls = _php_ldap_controls_from_array ( ldap , newval , 3 ) ;
2017-07-20 10:17:59 +00:00
if ( ctrls = = NULL ) {
2001-01-07 21:18:02 +00:00
RETURN_FALSE ;
2017-07-20 10:17:59 +00:00
} else {
rc = ldap_set_option ( ldap , option , ctrls ) ;
2017-07-26 14:41:44 +00:00
_php_ldap_controls_free ( & ctrls ) ;
2017-07-20 10:17:59 +00:00
if ( rc ! = LDAP_SUCCESS ) {
RETURN_FALSE ;
}
2001-01-07 21:18:02 +00:00
}
} break ;
2000-10-17 16:06:04 +00:00
default :
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2001-01-07 13:03:11 +00:00
2005-05-08 15:43:22 +00:00
# ifdef HAVE_LDAP_PARSE_RESULT
2020-07-01 13:32:55 +00:00
/* {{{ Extract information from result */
2015-01-03 09:22:58 +00:00
PHP_FUNCTION ( ldap_parse_result )
2001-05-31 21:09:30 +00:00
{
2017-07-20 10:17:59 +00:00
zval * link , * result , * errcode , * matcheddn , * errmsg , * referrals , * serverctrls ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
2018-02-17 15:51:37 +00:00
LDAPControl * * lserverctrls = NULL ;
2001-01-07 13:03:11 +00:00
char * * lreferrals , * * refp ;
char * lmatcheddn , * lerrmsg ;
2018-02-10 11:39:12 +00:00
int rc , lerrcode , myargcount = ZEND_NUM_ARGS ( ) ;
2003-06-08 23:34:51 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( myargcount , " OOz|zzzz " , & link , ldap_link_ce , & result , ldap_result_ce , & errcode , & matcheddn , & errmsg , & referrals , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-01-07 13:03:11 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
2001-01-07 13:03:11 +00:00
2021-03-13 11:11:40 +00:00
rc = ldap_parse_result ( ld - > link , ldap_result - > result , & lerrcode ,
2001-01-07 13:03:11 +00:00
myargcount > 3 ? & lmatcheddn : NULL ,
myargcount > 4 ? & lerrmsg : NULL ,
myargcount > 5 ? & lreferrals : NULL ,
2017-07-20 10:17:59 +00:00
myargcount > 6 ? & lserverctrls : NULL ,
2003-06-08 23:34:51 +00:00
0 ) ;
if ( rc ! = LDAP_SUCCESS ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Unable to parse result: %s " , ldap_err2string ( rc ) ) ;
2001-01-07 13:03:11 +00:00
RETURN_FALSE ;
}
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_LONG ( errcode , lerrcode ) ;
2001-01-07 13:03:11 +00:00
/* Reverse -> fall through */
2003-06-08 23:34:51 +00:00
switch ( myargcount ) {
2017-07-20 10:17:59 +00:00
case 7 :
2017-09-12 10:04:17 +00:00
_php_ldap_controls_to_array ( ld - > link , lserverctrls , serverctrls , 0 ) ;
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2003-06-08 23:34:51 +00:00
case 6 :
2019-01-07 11:28:51 +00:00
referrals = zend_try_array_init ( referrals ) ;
if ( ! referrals ) {
2020-01-03 19:44:29 +00:00
RETURN_THROWS ( ) ;
2019-01-07 11:28:51 +00:00
}
2001-01-07 13:03:11 +00:00
if ( lreferrals ! = NULL ) {
refp = lreferrals ;
while ( * refp ) {
2014-04-15 11:40:40 +00:00
add_next_index_string ( referrals , * refp ) ;
2001-01-07 13:03:11 +00:00
refp + + ;
}
2015-06-23 14:44:48 +00:00
ldap_memvfree ( ( void * * ) lreferrals ) ;
2001-01-07 13:03:11 +00:00
}
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2003-06-08 23:34:51 +00:00
case 5 :
2001-01-07 13:03:11 +00:00
if ( lerrmsg = = NULL ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( errmsg ) ;
2001-01-07 13:03:11 +00:00
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRING ( errmsg , lerrmsg ) ;
2001-01-07 13:03:11 +00:00
ldap_memfree ( lerrmsg ) ;
}
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2015-01-03 09:22:58 +00:00
case 4 :
2001-01-07 13:03:11 +00:00
if ( lmatcheddn = = NULL ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( matcheddn ) ;
2001-01-07 13:03:11 +00:00
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRING ( matcheddn , lmatcheddn ) ;
2001-01-07 13:03:11 +00:00
ldap_memfree ( lmatcheddn ) ;
}
}
RETURN_TRUE ;
}
/* }}} */
2005-05-08 15:43:22 +00:00
# endif
2001-01-07 13:03:11 +00:00
2017-06-20 09:26:34 +00:00
/* {{{ Extended operation response parsing, Pierangelo Masarati */
# ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
2020-07-01 13:32:55 +00:00
/* {{{ Extract information from extended operation result */
2017-06-20 09:26:34 +00:00
PHP_FUNCTION ( ldap_parse_exop )
{
2017-06-29 15:19:38 +00:00
zval * link , * result , * retdata , * retoid ;
2017-06-20 09:26:34 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
2017-06-20 09:26:34 +00:00
char * lretoid ;
struct berval * lretdata ;
int rc , myargcount = ZEND_NUM_ARGS ( ) ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( myargcount , " OO|zz " , & link , ldap_link_ce , & result , ldap_result_ce , & retdata , & retoid ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-06-20 09:26:34 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-06-20 10:36:02 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
2017-06-20 09:26:34 +00:00
2021-03-13 11:11:40 +00:00
rc = ldap_parse_extended_result ( ld - > link , ldap_result - > result ,
2017-06-29 15:19:38 +00:00
myargcount > 3 ? & lretoid : NULL ,
myargcount > 2 ? & lretdata : NULL ,
2017-06-20 09:26:34 +00:00
0 ) ;
if ( rc ! = LDAP_SUCCESS ) {
2017-07-03 10:07:41 +00:00
php_error_docref ( NULL , E_WARNING , " Unable to parse extended operation result: %s " , ldap_err2string ( rc ) ) ;
2017-06-20 09:26:34 +00:00
RETURN_FALSE ;
}
/* Reverse -> fall through */
switch ( myargcount ) {
case 4 :
2017-06-29 15:19:38 +00:00
if ( lretoid = = NULL ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( retoid ) ;
2017-06-29 15:19:38 +00:00
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRING ( retoid , lretoid ) ;
2017-06-29 15:19:38 +00:00
ldap_memfree ( lretoid ) ;
}
2020-09-29 22:25:49 +00:00
ZEND_FALLTHROUGH ;
2017-06-29 15:19:38 +00:00
case 3 :
/* use arg #3 as the data returned by the server */
2017-06-20 09:26:34 +00:00
if ( lretdata = = NULL ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( retdata ) ;
2017-06-20 09:26:34 +00:00
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRINGL ( retdata , lretdata - > bv_val , lretdata - > bv_len ) ;
2017-06-20 09:26:34 +00:00
ldap_memfree ( lretdata - > bv_val ) ;
ldap_memfree ( lretdata ) ;
}
}
RETURN_TRUE ;
}
/* }}} */
2017-06-26 13:58:02 +00:00
# endif
2017-06-20 09:26:34 +00:00
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Count the number of references in a search result */
2020-06-30 14:12:12 +00:00
PHP_FUNCTION ( ldap_count_references )
{
zval * link , * result ;
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * ldap_result ;
2020-06-30 14:12:12 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result , ldap_result_ce ) ! = SUCCESS ) {
2020-06-30 14:12:12 +00:00
RETURN_THROWS ( ) ;
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2020-06-30 14:12:12 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
2020-06-30 14:12:12 +00:00
2021-03-13 11:11:40 +00:00
RETURN_LONG ( ldap_count_references ( ld - > link , ldap_result - > result ) ) ;
2020-06-30 14:12:12 +00:00
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Return first reference */
2001-01-07 13:03:11 +00:00
PHP_FUNCTION ( ldap_first_reference )
{
2008-04-16 14:21:04 +00:00
zval * link , * result ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
ldap_resultdata * ldap_result ;
LDAPMessage * entry ;
2001-01-07 13:03:11 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result , ldap_result_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-01-07 13:03:11 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
ldap_result = Z_LDAP_RESULT_P ( result ) ;
VERIFY_LDAP_RESULT_OPEN ( ldap_result ) ;
2001-01-07 13:03:11 +00:00
2021-03-13 11:11:40 +00:00
if ( ( entry = ldap_first_reference ( ld - > link , ldap_result - > result ) ) = = NULL ) {
2001-05-31 21:09:30 +00:00
RETVAL_FALSE ;
2001-01-07 13:03:11 +00:00
} else {
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_entry_ce ) ;
resultentry = Z_LDAP_RESULT_ENTRY_P ( return_value ) ;
2014-05-20 03:26:26 +00:00
ZVAL_COPY ( & resultentry - > res , result ) ;
2002-05-04 14:27:48 +00:00
resultentry - > data = entry ;
2009-12-21 20:39:48 +00:00
resultentry - > ber = NULL ;
2001-01-07 13:03:11 +00:00
}
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Get next reference */
2001-01-07 13:03:11 +00:00
PHP_FUNCTION ( ldap_next_reference )
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry , * resultentry_next ;
2002-05-04 14:27:48 +00:00
LDAPMessage * entry_next ;
2001-01-07 13:03:11 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OO " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-01-07 13:03:11 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
2001-01-07 13:03:11 +00:00
2002-05-04 14:27:48 +00:00
if ( ( entry_next = ldap_next_reference ( ld - > link , resultentry - > data ) ) = = NULL ) {
2001-05-31 21:09:30 +00:00
RETVAL_FALSE ;
2001-01-07 13:03:11 +00:00
} else {
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_entry_ce ) ;
resultentry_next = Z_LDAP_RESULT_ENTRY_P ( return_value ) ;
2014-05-20 03:26:26 +00:00
ZVAL_COPY ( & resultentry_next - > res , & resultentry - > res ) ;
2002-05-04 14:27:48 +00:00
resultentry_next - > data = entry_next ;
2009-12-21 20:39:48 +00:00
resultentry_next - > ber = NULL ;
2001-01-07 13:03:11 +00:00
}
}
/* }}} */
2002-06-22 15:41:39 +00:00
# ifdef HAVE_LDAP_PARSE_REFERENCE
2020-07-01 13:32:55 +00:00
/* {{{ Extract information from reference entry */
2001-01-07 13:03:11 +00:00
PHP_FUNCTION ( ldap_parse_reference )
{
2008-04-16 14:21:04 +00:00
zval * link , * result_entry , * referrals ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_result_entry * resultentry ;
2001-01-07 13:03:11 +00:00
char * * lreferrals , * * refp ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OOz " , & link , ldap_link_ce , & result_entry , ldap_result_entry_ce , & referrals ) ! = SUCCESS ) {
2019-12-31 11:22:43 +00:00
RETURN_THROWS ( ) ;
2001-01-07 13:03:11 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2015-02-02 07:05:20 +00:00
2021-03-13 11:11:40 +00:00
resultentry = Z_LDAP_RESULT_ENTRY_P ( result_entry ) ;
2001-01-07 13:03:11 +00:00
2002-05-04 14:27:48 +00:00
if ( ldap_parse_reference ( ld - > link , resultentry - > data , & lreferrals , NULL /* &serverctrls */ , 0 ) ! = LDAP_SUCCESS ) {
2001-01-07 13:03:11 +00:00
RETURN_FALSE ;
}
2019-01-07 11:28:51 +00:00
referrals = zend_try_array_init ( referrals ) ;
if ( ! referrals ) {
2020-01-03 19:44:29 +00:00
RETURN_THROWS ( ) ;
2019-01-07 11:28:51 +00:00
}
2001-01-07 13:03:11 +00:00
if ( lreferrals ! = NULL ) {
refp = lreferrals ;
while ( * refp ) {
2014-04-15 11:40:40 +00:00
add_next_index_string ( referrals , * refp ) ;
2001-01-07 13:03:11 +00:00
refp + + ;
}
2015-06-23 14:44:48 +00:00
ldap_memvfree ( ( void * * ) lreferrals ) ;
2001-01-07 13:03:11 +00:00
}
RETURN_TRUE ;
}
/* }}} */
2002-06-22 15:41:39 +00:00
# endif
2001-01-08 18:13:08 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ php_ldap_do_rename */
2017-09-12 12:56:31 +00:00
static void php_ldap_do_rename ( INTERNAL_FUNCTION_PARAMETERS , int ext )
2001-01-08 18:13:08 +00:00
{
2017-09-07 15:03:45 +00:00
zval * serverctrls = NULL ;
2008-04-16 14:21:04 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2017-09-07 15:03:45 +00:00
LDAPControl * * lserverctrls = NULL ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2017-09-12 12:56:31 +00:00
LDAPMessage * ldap_res ;
int rc , msgid ;
2008-04-16 14:21:04 +00:00
char * dn , * newrdn , * newparent ;
2014-08-28 07:43:14 +00:00
size_t dn_len , newrdn_len , newparent_len ;
2021-01-15 11:30:54 +00:00
bool deleteoldrdn ;
2015-01-03 09:22:58 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Osssb|a! " , & link , ldap_link_ce , & dn , & dn_len , & newrdn , & newrdn_len , & newparent , & newparent_len , & deleteoldrdn , & serverctrls ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-01-08 18:13:08 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2001-01-08 18:13:08 +00:00
2008-04-16 14:21:04 +00:00
if ( newparent_len = = 0 ) {
newparent = NULL ;
}
2007-07-17 08:40:24 +00:00
2020-05-15 22:30:38 +00:00
# if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP)
2017-09-07 09:57:13 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 6 ) ;
2017-09-07 09:57:13 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
2017-09-12 12:56:31 +00:00
if ( ext ) {
rc = ldap_rename ( ld - > link , dn , newrdn , newparent , deleteoldrdn , lserverctrls , NULL , & msgid ) ;
} else {
rc = ldap_rename_s ( ld - > link , dn , newrdn , newparent , deleteoldrdn , lserverctrls , NULL ) ;
}
2001-01-08 18:13:08 +00:00
# else
2008-04-16 14:21:04 +00:00
if ( newparent_len ! = 0 ) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " You are using old LDAP API, newparent must be the empty string, can only modify RDN " ) ;
2001-01-08 18:13:08 +00:00
RETURN_FALSE ;
}
2017-09-07 15:03:45 +00:00
if ( serverctrls ) {
2017-09-07 09:57:13 +00:00
php_error_docref ( NULL , E_WARNING , " You are using old LDAP API, controls are not supported " ) ;
RETURN_FALSE ;
}
2017-09-12 12:56:31 +00:00
if ( ext ) {
php_error_docref ( NULL , E_WARNING , " You are using old LDAP API, ldap_rename_ext is not supported " ) ;
RETURN_FALSE ;
}
2001-01-08 18:13:08 +00:00
/* could support old APIs but need check for ldap_modrdn2()/ldap_modrdn() */
2008-04-16 14:21:04 +00:00
rc = ldap_modrdn2_s ( ld - > link , dn , newrdn , deleteoldrdn ) ;
2001-01-08 18:13:08 +00:00
# endif
2017-09-12 12:56:31 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2017-09-07 09:57:13 +00:00
RETVAL_FALSE ;
2017-09-12 12:56:31 +00:00
} else if ( ext ) {
rc = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( rc = = - 1 ) {
php_error_docref ( NULL , E_WARNING , " Rename operation failed " ) ;
RETVAL_FALSE ;
goto cleanup ;
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2017-09-12 12:56:31 +00:00
} else {
RETVAL_TRUE ;
2001-01-08 18:13:08 +00:00
}
2017-09-07 09:57:13 +00:00
cleanup :
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
return ;
2001-01-08 18:13:08 +00:00
}
/* }}} */
2000-10-17 16:06:04 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Modify the name of an entry */
2017-09-12 12:56:31 +00:00
PHP_FUNCTION ( ldap_rename )
{
php_ldap_do_rename ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Modify the name of an entry */
2017-09-12 12:56:31 +00:00
PHP_FUNCTION ( ldap_rename_ext )
{
php_ldap_do_rename ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
2002-06-22 15:41:39 +00:00
# ifdef HAVE_LDAP_START_TLS_S
2020-07-01 13:32:55 +00:00
/* {{{ Start TLS */
2001-10-09 21:14:14 +00:00
PHP_FUNCTION ( ldap_start_tls )
{
2008-04-16 14:21:04 +00:00
zval * link ;
2001-11-29 20:17:17 +00:00
ldap_linkdata * ld ;
2005-01-19 00:27:21 +00:00
int rc , protocol = LDAP_VERSION3 ;
2001-10-09 21:14:14 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & link , ldap_link_ce ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-10-09 21:14:14 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2001-10-09 21:14:14 +00:00
2005-01-19 00:27:21 +00:00
if ( ( ( rc = ldap_set_option ( ld - > link , LDAP_OPT_PROTOCOL_VERSION , & protocol ) ) ! = LDAP_SUCCESS ) | |
( ( rc = ldap_start_tls_s ( ld - > link , NULL , NULL ) ) ! = LDAP_SUCCESS )
) {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " Unable to start TLS: %s " , ldap_err2string ( rc ) ) ;
2001-10-09 21:14:14 +00:00
RETURN_FALSE ;
} else {
RETURN_TRUE ;
}
}
/* }}} */
# endif
2020-05-15 22:30:38 +00:00
# endif /* (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) */
2001-10-09 21:14:14 +00:00
2015-08-18 14:52:44 +00:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
2020-07-01 13:32:55 +00:00
/* {{{ _ldap_rebind_proc() */
2003-06-08 23:34:51 +00:00
int _ldap_rebind_proc ( LDAP * ldap , const char * url , ber_tag_t req , ber_int_t msgid , void * params )
{
2021-03-13 11:11:40 +00:00
ldap_linkdata * ld = NULL ;
2001-11-29 20:26:20 +00:00
int retval ;
2014-05-20 03:26:26 +00:00
zval cb_args [ 2 ] ;
zval cb_retval ;
2001-11-29 20:26:20 +00:00
zval * cb_link = ( zval * ) params ;
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( cb_link ) ;
if ( ! ld - > link ) {
zend_throw_error ( NULL , " LDAP connection has already been closed " ) ;
return LDAP_OTHER ;
}
2001-11-29 20:26:20 +00:00
/* link exists and callback set? */
2021-03-13 11:11:40 +00:00
if ( Z_ISUNDEF ( ld - > rebindproc ) ) {
php_error_docref ( NULL , E_WARNING , " No callback set " ) ;
2001-11-29 20:26:20 +00:00
return LDAP_OTHER ;
}
/* callback */
2014-05-20 03:26:26 +00:00
ZVAL_COPY_VALUE ( & cb_args [ 0 ] , cb_link ) ;
ZVAL_STRING ( & cb_args [ 1 ] , url ) ;
2020-07-06 16:57:41 +00:00
if ( call_user_function ( EG ( function_table ) , NULL , & ld - > rebindproc , & cb_retval , 2 , cb_args ) = = SUCCESS & & ! Z_ISUNDEF ( cb_retval ) ) {
2017-12-07 16:24:55 +00:00
retval = zval_get_long ( & cb_retval ) ;
2001-11-29 20:26:20 +00:00
zval_ptr_dtor ( & cb_retval ) ;
} else {
2014-12-13 22:06:14 +00:00
php_error_docref ( NULL , E_WARNING , " rebind_proc PHP callback failed " ) ;
2001-11-29 20:26:20 +00:00
retval = LDAP_OTHER ;
}
2014-05-20 03:26:26 +00:00
zval_ptr_dtor ( & cb_args [ 1 ] ) ;
2001-11-29 20:26:20 +00:00
return retval ;
}
2003-06-08 23:34:51 +00:00
/* }}} */
2001-11-29 20:26:20 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Set a callback function to do re-binds on referral chasing. */
2001-11-29 20:26:20 +00:00
PHP_FUNCTION ( ldap_set_rebind_proc )
{
2020-07-08 16:44:34 +00:00
zval * link ;
zend_fcall_info fci ;
zend_fcall_info_cache fcc ;
2001-11-29 20:26:20 +00:00
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Of! " , & link , ldap_link_ce , & fci , & fcc ) = = FAILURE ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2001-11-29 20:26:20 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2001-11-29 20:26:20 +00:00
2020-07-08 16:44:34 +00:00
if ( ! ZEND_FCI_INITIALIZED ( fci ) ) {
2001-11-29 20:26:20 +00:00
/* unregister rebind procedure */
2014-05-20 03:26:26 +00:00
if ( ! Z_ISUNDEF ( ld - > rebindproc ) ) {
zval_ptr_dtor ( & ld - > rebindproc ) ;
ZVAL_UNDEF ( & ld - > rebindproc ) ;
2001-11-29 20:26:20 +00:00
ldap_set_rebind_proc ( ld - > link , NULL , NULL ) ;
}
RETURN_TRUE ;
}
/* register rebind procedure */
2014-05-20 03:26:26 +00:00
if ( Z_ISUNDEF ( ld - > rebindproc ) ) {
2001-11-29 20:26:20 +00:00
ldap_set_rebind_proc ( ld - > link , _ldap_rebind_proc , ( void * ) link ) ;
} else {
2014-05-20 03:26:26 +00:00
zval_ptr_dtor ( & ld - > rebindproc ) ;
2001-11-29 20:26:20 +00:00
}
2020-07-08 16:44:34 +00:00
ZVAL_COPY ( & ld - > rebindproc , & fci . function_name ) ;
2001-11-29 20:26:20 +00:00
RETURN_TRUE ;
}
2003-06-08 23:34:51 +00:00
/* }}} */
2001-11-29 20:26:20 +00:00
# endif
2021-01-15 11:30:54 +00:00
static zend_string * php_ldap_do_escape ( const bool * map , const char * value , size_t valuelen , zend_long flags )
2013-09-17 15:34:30 +00:00
{
char hex [ ] = " 0123456789abcdef " ;
2016-06-21 21:40:50 +00:00
size_t i , p = 0 ;
2013-09-17 15:34:30 +00:00
size_t len = 0 ;
2015-07-01 10:49:57 +00:00
zend_string * ret ;
2013-09-17 15:34:30 +00:00
for ( i = 0 ; i < valuelen ; i + + ) {
2013-10-18 09:34:24 +00:00
len + = ( map [ ( unsigned char ) value [ i ] ] ) ? 3 : 1 ;
2013-09-17 15:34:30 +00:00
}
2016-06-26 02:16:45 +00:00
/* Per RFC 4514, a leading and trailing space must be escaped */
2016-06-29 12:37:48 +00:00
if ( ( flags & PHP_LDAP_ESCAPE_DN ) & & ( value [ 0 ] = = ' ' ) ) {
2016-06-26 02:16:45 +00:00
len + = 2 ;
}
2016-06-29 12:37:48 +00:00
if ( ( flags & PHP_LDAP_ESCAPE_DN ) & & ( ( valuelen > 1 ) & & ( value [ valuelen - 1 ] = = ' ' ) ) ) {
2016-06-26 02:16:45 +00:00
len + = 2 ;
}
2013-09-17 15:34:30 +00:00
2015-07-01 10:49:57 +00:00
ret = zend_string_alloc ( len , 0 ) ;
2013-09-17 15:34:30 +00:00
for ( i = 0 ; i < valuelen ; i + + ) {
2013-10-18 09:34:24 +00:00
unsigned char v = ( unsigned char ) value [ i ] ;
2016-06-29 12:37:48 +00:00
if ( map [ v ] | | ( ( flags & PHP_LDAP_ESCAPE_DN ) & & ( ( i = = 0 ) | | ( i + 1 = = valuelen ) ) & & ( v = = ' ' ) ) ) {
2015-07-01 10:49:57 +00:00
ZSTR_VAL ( ret ) [ p + + ] = ' \\ ' ;
ZSTR_VAL ( ret ) [ p + + ] = hex [ v > > 4 ] ;
ZSTR_VAL ( ret ) [ p + + ] = hex [ v & 0x0f ] ;
2013-09-17 15:34:30 +00:00
} else {
2015-07-01 10:49:57 +00:00
ZSTR_VAL ( ret ) [ p + + ] = v ;
2013-09-17 15:34:30 +00:00
}
}
2015-07-01 10:49:57 +00:00
ZSTR_VAL ( ret ) [ p ] = ' \0 ' ;
ZSTR_LEN ( ret ) = p ;
2015-07-06 08:25:19 +00:00
return ret ;
2013-09-17 15:34:30 +00:00
}
2021-01-15 11:30:54 +00:00
static void php_ldap_escape_map_set_chars ( bool * map , const char * chars , const size_t charslen , char escape )
2013-09-17 15:34:30 +00:00
{
2017-07-25 15:56:05 +00:00
size_t i = 0 ;
2013-09-17 15:34:30 +00:00
while ( i < charslen ) {
2013-10-18 09:34:24 +00:00
map [ ( unsigned char ) chars [ i + + ] ] = escape ;
2013-09-17 15:34:30 +00:00
}
}
PHP_FUNCTION ( ldap_escape )
{
2015-07-01 10:49:57 +00:00
char * value , * ignores ;
2014-08-27 13:31:48 +00:00
size_t valuelen = 0 , ignoreslen = 0 ;
int i ;
2014-08-25 17:24:55 +00:00
zend_long flags = 0 ;
2021-01-15 11:30:54 +00:00
bool map [ 256 ] = { 0 } , havecharlist = 0 ;
2013-09-17 15:34:30 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|sl " , & value , & valuelen , & ignores , & ignoreslen , & flags ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2013-09-17 15:34:30 +00:00
}
if ( ! valuelen ) {
RETURN_EMPTY_STRING ( ) ;
}
if ( flags & PHP_LDAP_ESCAPE_FILTER ) {
havecharlist = 1 ;
php_ldap_escape_map_set_chars ( map , " \\ *() \0 " , sizeof ( " \\ *() \0 " ) - 1 , 1 ) ;
}
if ( flags & PHP_LDAP_ESCAPE_DN ) {
havecharlist = 1 ;
2016-06-26 02:16:45 +00:00
php_ldap_escape_map_set_chars ( map , " \\ ,=+<>; \" # \r " , sizeof ( " \\ ,=+<>; \" # \r " ) - 1 , 1 ) ;
2013-09-17 15:34:30 +00:00
}
if ( ! havecharlist ) {
for ( i = 0 ; i < 256 ; i + + ) {
map [ i ] = 1 ;
}
}
if ( ignoreslen ) {
php_ldap_escape_map_set_chars ( map , ignores , ignoreslen , 0 ) ;
}
2016-06-26 02:16:45 +00:00
RETURN_NEW_STR ( php_ldap_do_escape ( map , value , valuelen , flags ) ) ;
2013-09-17 15:34:30 +00:00
}
2000-08-02 13:11:46 +00:00
# ifdef STR_TRANSLATION
2020-07-01 13:32:55 +00:00
/* {{{ php_ldap_do_translate */
2015-01-03 09:22:58 +00:00
static void php_ldap_do_translate ( INTERNAL_FUNCTION_PARAMETERS , int way )
2001-05-31 21:09:30 +00:00
{
2008-04-16 14:21:04 +00:00
char * value ;
2015-01-21 07:00:40 +00:00
size_t value_len ;
int result ;
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & value , & value_len ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2000-08-02 13:11:46 +00:00
}
2008-04-16 14:21:04 +00:00
if ( value_len = = 0 ) {
2000-08-02 13:11:46 +00:00
RETURN_FALSE ;
}
2003-06-08 23:34:51 +00:00
if ( way = = 1 ) {
2008-04-16 14:21:04 +00:00
result = ldap_8859_to_t61 ( & value , & value_len , 0 ) ;
2000-08-02 13:11:46 +00:00
} else {
2008-04-16 14:21:04 +00:00
result = ldap_t61_to_8859 ( & value , & value_len , 0 ) ;
2000-08-02 13:11:46 +00:00
}
if ( result = = LDAP_SUCCESS ) {
2014-05-20 03:26:26 +00:00
RETVAL_STRINGL ( value , value_len ) ;
2008-04-16 14:21:04 +00:00
free ( value ) ;
2000-08-02 13:11:46 +00:00
} else {
2020-01-15 10:27:29 +00:00
php_error_docref ( NULL , E_WARNING , " Conversion from ISO-8859-1 to t61 failed: %s " , ldap_err2string ( result ) ) ;
2000-08-02 13:11:46 +00:00
RETVAL_FALSE ;
}
}
2001-06-05 13:12:10 +00:00
/* }}} */
2000-08-02 13:11:46 +00:00
2020-07-01 13:32:55 +00:00
/* {{{ Translate t61 characters to 8859 characters */
2001-08-05 01:43:02 +00:00
PHP_FUNCTION ( ldap_t61_to_8859 )
{
2000-08-02 13:11:46 +00:00
php_ldap_do_translate ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
2020-07-01 13:32:55 +00:00
/* {{{ Translate 8859 characters to t61 characters */
2001-08-05 01:43:02 +00:00
PHP_FUNCTION ( ldap_8859_to_t61 )
{
2000-08-02 13:11:46 +00:00
php_ldap_do_translate ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
# endif
2001-06-05 13:12:10 +00:00
2017-06-20 09:26:34 +00:00
/* {{{ Extended operations, Pierangelo Masarati */
# ifdef HAVE_LDAP_EXTENDED_OPERATION_S
2020-07-01 13:32:55 +00:00
/* {{{ Extended operation */
2017-06-20 09:26:34 +00:00
PHP_FUNCTION ( ldap_exop )
{
2017-09-06 14:39:21 +00:00
zval * serverctrls = NULL ;
2017-09-06 10:52:47 +00:00
zval * link , * retdata = NULL , * retoid = NULL ;
char * lretoid = NULL ;
zend_string * reqoid , * reqdata = NULL ;
2017-06-20 09:26:34 +00:00
struct berval lreqdata , * lretdata = NULL ;
ldap_linkdata * ld ;
2021-03-13 11:11:40 +00:00
ldap_resultdata * result ;
2017-06-20 09:26:34 +00:00
LDAPMessage * ldap_res ;
2017-09-06 14:39:21 +00:00
LDAPControl * * lserverctrls = NULL ;
2017-09-06 10:52:47 +00:00
int rc , msgid ;
2017-06-20 09:26:34 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " OS|S!a!zz " , & link , ldap_link_ce , & reqoid , & reqdata , & serverctrls , & retdata , & retoid ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-06-20 09:26:34 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-06-20 09:26:34 +00:00
2017-09-06 10:52:47 +00:00
if ( reqdata ) {
lreqdata . bv_val = ZSTR_VAL ( reqdata ) ;
lreqdata . bv_len = ZSTR_LEN ( reqdata ) ;
2017-09-06 13:04:37 +00:00
} else {
lreqdata . bv_len = 0 ;
2017-09-06 10:52:47 +00:00
}
2017-09-06 14:39:21 +00:00
if ( serverctrls ) {
2020-09-03 14:21:36 +00:00
lserverctrls = _php_ldap_controls_from_array ( ld - > link , serverctrls , 4 ) ;
2017-09-06 14:39:21 +00:00
if ( lserverctrls = = NULL ) {
RETVAL_FALSE ;
goto cleanup ;
}
}
2017-09-06 10:52:47 +00:00
if ( retdata ) {
2017-06-20 09:26:34 +00:00
/* synchronous call */
2017-09-06 10:52:47 +00:00
rc = ldap_extended_operation_s ( ld - > link , ZSTR_VAL ( reqoid ) ,
2017-09-06 13:04:37 +00:00
lreqdata . bv_len > 0 ? & lreqdata : NULL ,
2017-09-06 14:39:21 +00:00
lserverctrls ,
2017-06-20 09:26:34 +00:00
NULL ,
2017-09-06 10:52:47 +00:00
retoid ? & lretoid : NULL ,
2017-06-29 15:19:38 +00:00
& lretdata ) ;
2017-06-20 09:26:34 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2017-09-06 10:52:47 +00:00
php_error_docref ( NULL , E_WARNING , " Extended operation %s failed: %s (%d) " , ZSTR_VAL ( reqoid ) , ldap_err2string ( rc ) , rc ) ;
2017-09-06 14:39:21 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-06-20 09:26:34 +00:00
}
2017-09-06 10:52:47 +00:00
if ( retoid ) {
if ( lretoid ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRING ( retoid , lretoid ) ;
2017-09-06 10:52:47 +00:00
ldap_memfree ( lretoid ) ;
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( retoid ) ;
2017-09-06 10:52:47 +00:00
}
}
if ( lretdata ) {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_STRINGL ( retdata , lretdata - > bv_val , lretdata - > bv_len ) ;
2017-09-06 10:52:47 +00:00
ldap_memfree ( lretdata - > bv_val ) ;
ldap_memfree ( lretdata ) ;
} else {
2019-04-24 13:14:48 +00:00
ZEND_TRY_ASSIGN_REF_EMPTY_STRING ( retdata ) ;
2017-06-20 09:26:34 +00:00
}
2017-09-06 14:39:21 +00:00
RETVAL_TRUE ;
goto cleanup ;
2017-06-20 09:26:34 +00:00
}
/* asynchronous call */
2017-09-06 10:52:47 +00:00
rc = ldap_extended_operation ( ld - > link , ZSTR_VAL ( reqoid ) ,
2017-06-20 09:26:34 +00:00
lreqdata . bv_len > 0 ? & lreqdata : NULL ,
2017-09-06 14:39:21 +00:00
lserverctrls ,
NULL ,
& msgid ) ;
2017-06-20 09:26:34 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2017-09-06 10:52:47 +00:00
php_error_docref ( NULL , E_WARNING , " Extended operation %s failed: %s (%d) " , ZSTR_VAL ( reqoid ) , ldap_err2string ( rc ) , rc ) ;
2017-09-06 14:39:21 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-06-20 09:26:34 +00:00
}
rc = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( rc = = - 1 ) {
2017-09-06 10:52:47 +00:00
php_error_docref ( NULL , E_WARNING , " Extended operation %s failed " , ZSTR_VAL ( reqoid ) ) ;
2017-09-06 14:39:21 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-06-20 09:26:34 +00:00
}
/* return a PHP control object */
2021-03-13 11:11:40 +00:00
object_init_ex ( return_value , ldap_result_ce ) ;
result = Z_LDAP_RESULT_P ( return_value ) ;
result - > result = ldap_res ;
2017-09-06 14:39:21 +00:00
cleanup :
if ( lserverctrls ) {
_php_ldap_controls_free ( & lserverctrls ) ;
}
2017-06-20 09:26:34 +00:00
}
/* }}} */
2017-06-26 13:58:02 +00:00
# endif
2017-06-20 09:26:34 +00:00
2017-07-20 10:17:59 +00:00
# ifdef HAVE_LDAP_PASSWD
2020-07-01 13:32:55 +00:00
/* {{{ Passwd modify extended operation */
2017-06-20 09:26:34 +00:00
PHP_FUNCTION ( ldap_exop_passwd )
{
2019-06-13 18:58:45 +00:00
zval * link , * serverctrls ;
2020-07-13 04:19:34 +00:00
struct berval luser = { 0L , NULL } ;
struct berval loldpw = { 0L , NULL } ;
struct berval lnewpw = { 0L , NULL } ;
struct berval lgenpasswd = { 0L , NULL } ;
LDAPControl * ctrl , * * lserverctrls = NULL , * requestctrls [ 2 ] = { NULL , NULL } ;
LDAPMessage * ldap_res = NULL ;
2017-06-20 09:26:34 +00:00
ldap_linkdata * ld ;
2017-07-20 10:17:59 +00:00
int rc , myargcount = ZEND_NUM_ARGS ( ) , msgid , err ;
2020-07-13 04:19:34 +00:00
char * errmsg = NULL ;
2019-06-13 18:58:45 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( myargcount , " O|sssz/ " , & link , ldap_link_ce , & luser . bv_val , & luser . bv_len , & loldpw . bv_val , & loldpw . bv_len , & lnewpw . bv_val , & lnewpw . bv_len , & serverctrls ) = = FAILURE ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-06-20 09:26:34 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-06-20 09:26:34 +00:00
switch ( myargcount ) {
2017-07-20 10:17:59 +00:00
case 5 :
2020-07-13 04:19:34 +00:00
/* ldap_create_passwordpolicy_control() allocates ctrl */
2017-07-20 10:17:59 +00:00
if ( ldap_create_passwordpolicy_control ( ld - > link , & ctrl ) = = LDAP_SUCCESS ) {
2020-07-13 04:19:34 +00:00
requestctrls [ 0 ] = ctrl ;
2017-07-20 10:17:59 +00:00
}
2017-06-20 09:26:34 +00:00
}
2017-07-20 10:17:59 +00:00
/* asynchronous call to get result and controls */
rc = ldap_passwd ( ld - > link , & luser ,
2017-06-20 09:26:34 +00:00
loldpw . bv_len > 0 ? & loldpw : NULL ,
lnewpw . bv_len > 0 ? & lnewpw : NULL ,
2017-07-20 10:17:59 +00:00
requestctrls ,
NULL , & msgid ) ;
2020-07-03 00:11:44 +00:00
2020-07-13 04:19:34 +00:00
if ( requestctrls [ 0 ] ! = NULL ) {
ldap_control_free ( requestctrls [ 0 ] ) ;
2020-07-03 00:11:44 +00:00
}
2017-06-20 09:26:34 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2017-07-03 10:07:41 +00:00
php_error_docref ( NULL , E_WARNING , " Passwd modify extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2020-07-13 04:19:34 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-06-20 09:26:34 +00:00
}
2017-07-20 10:17:59 +00:00
rc = ldap_result ( ld - > link , msgid , 1 /* LDAP_MSG_ALL */ , NULL , & ldap_res ) ;
if ( ( rc < 0 ) | | ! ldap_res ) {
rc = _get_lderrno ( ld - > link ) ;
php_error_docref ( NULL , E_WARNING , " Passwd modify extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2020-07-13 04:19:34 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-07-20 10:17:59 +00:00
}
rc = ldap_parse_passwd ( ld - > link , ldap_res , & lgenpasswd ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Passwd modify extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2020-07-13 04:19:34 +00:00
RETVAL_FALSE ;
goto cleanup ;
2017-07-20 10:17:59 +00:00
}
2020-07-13 04:19:34 +00:00
rc = ldap_parse_result ( ld - > link , ldap_res , & err , NULL , & errmsg , NULL , ( myargcount > 4 ? & lserverctrls : NULL ) , 0 ) ;
2017-07-20 10:17:59 +00:00
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Passwd modify extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2020-07-13 04:19:34 +00:00
RETVAL_FALSE ;
goto cleanup ;
}
if ( myargcount > 4 ) {
_php_ldap_controls_to_array ( ld - > link , lserverctrls , serverctrls , 0 ) ;
2017-07-20 10:17:59 +00:00
}
2020-07-13 04:19:34 +00:00
/* return */
2017-07-04 08:01:44 +00:00
if ( lnewpw . bv_len = = 0 ) {
if ( lgenpasswd . bv_len = = 0 ) {
RETVAL_EMPTY_STRING ( ) ;
2017-06-29 14:46:58 +00:00
} else {
2017-07-04 08:01:44 +00:00
RETVAL_STRINGL ( lgenpasswd . bv_val , lgenpasswd . bv_len ) ;
2017-06-29 14:46:58 +00:00
}
2017-07-20 10:17:59 +00:00
} else if ( err = = LDAP_SUCCESS ) {
RETVAL_TRUE ;
2017-07-04 08:01:44 +00:00
} else {
2017-09-06 14:39:21 +00:00
php_error_docref ( NULL , E_WARNING , " Passwd modify extended operation failed: %s (%d) " , ( errmsg ? errmsg : ldap_err2string ( err ) ) , err ) ;
2017-07-20 10:17:59 +00:00
RETVAL_FALSE ;
}
2020-07-13 04:19:34 +00:00
cleanup :
if ( lgenpasswd . bv_val ! = NULL ) {
ldap_memfree ( lgenpasswd . bv_val ) ;
}
if ( ldap_res ! = NULL ) {
ldap_msgfree ( ldap_res ) ;
}
if ( errmsg ! = NULL ) {
ldap_memfree ( errmsg ) ;
2017-06-20 09:26:34 +00:00
}
}
/* }}} */
# endif
# ifdef HAVE_LDAP_WHOAMI_S
2020-07-01 13:32:55 +00:00
/* {{{ Whoami extended operation */
2017-06-20 09:26:34 +00:00
PHP_FUNCTION ( ldap_exop_whoami )
{
2017-07-04 08:01:44 +00:00
zval * link ;
2017-06-20 09:26:34 +00:00
struct berval * lauthzid ;
ldap_linkdata * ld ;
2018-02-10 11:39:12 +00:00
int rc ;
2017-06-20 09:26:34 +00:00
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & link , ldap_link_ce ) = = FAILURE ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-06-20 09:26:34 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-06-20 09:26:34 +00:00
2017-06-29 14:46:58 +00:00
/* synchronous call */
rc = ldap_whoami_s ( ld - > link , & lauthzid , NULL , NULL ) ;
2017-06-20 09:26:34 +00:00
if ( rc ! = LDAP_SUCCESS ) {
2017-07-03 10:07:41 +00:00
php_error_docref ( NULL , E_WARNING , " Whoami extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
2017-06-20 09:26:34 +00:00
RETURN_FALSE ;
}
2017-06-29 14:46:58 +00:00
if ( lauthzid = = NULL ) {
2017-07-04 08:01:44 +00:00
RETVAL_EMPTY_STRING ( ) ;
2017-06-29 14:46:58 +00:00
} else {
2017-07-04 08:01:44 +00:00
RETVAL_STRINGL ( lauthzid - > bv_val , lauthzid - > bv_len ) ;
2017-06-29 14:46:58 +00:00
ldap_memfree ( lauthzid - > bv_val ) ;
ldap_memfree ( lauthzid ) ;
2017-06-20 09:26:34 +00:00
}
}
/* }}} */
# endif
2017-07-20 14:14:47 +00:00
# ifdef HAVE_LDAP_REFRESH_S
2020-07-01 13:32:55 +00:00
/* {{{ DDS refresh extended operation */
2017-07-20 14:14:47 +00:00
PHP_FUNCTION ( ldap_exop_refresh )
{
2020-08-02 22:38:59 +00:00
zval * link ;
zend_long ttl ;
2017-07-20 14:14:47 +00:00
struct berval ldn ;
ber_int_t lttl ;
ber_int_t newttl ;
ldap_linkdata * ld ;
int rc ;
2021-03-13 11:11:40 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " Osl " , & link , ldap_link_ce , & ldn . bv_val , & ldn . bv_len , & ttl ) ! = SUCCESS ) {
2019-12-31 10:27:02 +00:00
RETURN_THROWS ( ) ;
2017-07-20 14:14:47 +00:00
}
2021-03-13 11:11:40 +00:00
ld = Z_LDAP_LINK_P ( link ) ;
VERIFY_LDAP_LINK_CONNECTED ( ld ) ;
2017-07-20 14:14:47 +00:00
2020-08-02 22:38:59 +00:00
lttl = ( ber_int_t ) ttl ;
2017-07-20 14:14:47 +00:00
rc = ldap_refresh_s ( ld - > link , & ldn , lttl , & newttl , NULL , NULL ) ;
if ( rc ! = LDAP_SUCCESS ) {
php_error_docref ( NULL , E_WARNING , " Refresh extended operation failed: %s (%d) " , ldap_err2string ( rc ) , rc ) ;
RETURN_FALSE ;
}
RETURN_LONG ( newttl ) ;
}
2017-06-20 09:26:34 +00:00
/* }}} */
2017-07-20 14:14:47 +00:00
# endif
2017-06-20 09:26:34 +00:00
2008-04-16 14:21:04 +00:00
zend_module_entry ldap_module_entry = { /* {{{ */
STANDARD_MODULE_HEADER ,
2015-01-03 09:22:58 +00:00
" ldap " ,
2020-04-04 19:26:46 +00:00
ext_functions ,
2015-01-03 09:22:58 +00:00
PHP_MINIT ( ldap ) ,
PHP_MSHUTDOWN ( ldap ) ,
NULL ,
2008-04-16 14:21:04 +00:00
NULL ,
2015-01-03 09:22:58 +00:00
PHP_MINFO ( ldap ) ,
2015-03-23 19:33:54 +00:00
PHP_LDAP_VERSION ,
2008-04-16 14:21:04 +00:00
PHP_MODULE_GLOBALS ( ldap ) ,
PHP_GINIT ( ldap ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
} ;
/* }}} */