@@ -859,6 +859,21 @@ static PHP_GINIT_FUNCTION(ldap)
859859}
860860/* }}} */
861861
862+ /* {{{ PHP_RINIT_FUNCTION */
863+ static PHP_RINIT_FUNCTION (ldap )
864+ {
865+ #if defined(COMPILE_DL_LDAP ) && defined(ZTS )
866+ ZEND_TSRMLS_CACHE_UPDATE ();
867+ #endif
868+
869+ /* needed before first connect and after TLS option changes */
870+ LDAPG (tls_newctx ) = true;
871+
872+ return SUCCESS ;
873+ }
874+ /* }}} */
875+
876+
862877/* {{{ PHP_MINIT_FUNCTION */
863878PHP_MINIT_FUNCTION (ldap )
864879{
@@ -1014,6 +1029,20 @@ PHP_FUNCTION(ldap_connect)
10141029 snprintf ( url , urllen , "ldap://%s:" ZEND_LONG_FMT , host , port );
10151030 }
10161031
1032+ #ifdef LDAP_OPT_X_TLS_NEWCTX
1033+ if (LDAPG (tls_newctx ) && url && !strncmp (url , "ldaps:" , 6 )) {
1034+ int val = 0 ;
1035+
1036+ /* ensure all pending TLS options are applied in a new context */
1037+ if (ldap_set_option (NULL , LDAP_OPT_X_TLS_NEWCTX , & val ) != LDAP_OPT_SUCCESS ) {
1038+ zval_ptr_dtor (return_value );
1039+ php_error_docref (NULL , E_WARNING , "Could not create new security context" );
1040+ RETURN_FALSE ;
1041+ }
1042+ LDAPG (tls_newctx ) = false;
1043+ }
1044+ #endif
1045+
10171046#ifdef LDAP_API_FEATURE_X_OPENLDAP
10181047 /* ldap_init() is deprecated, use ldap_initialize() instead.
10191048 */
@@ -3141,15 +3170,7 @@ PHP_FUNCTION(ldap_set_option)
31413170 }
31423171
31433172 switch (option ) {
3144- /* options with int value */
3145- case LDAP_OPT_DEREF :
3146- case LDAP_OPT_SIZELIMIT :
3147- case LDAP_OPT_TIMELIMIT :
3148- case LDAP_OPT_PROTOCOL_VERSION :
3149- case LDAP_OPT_ERROR_NUMBER :
3150- #ifdef LDAP_OPT_DEBUG_LEVEL
3151- case LDAP_OPT_DEBUG_LEVEL :
3152- #endif
3173+ /* TLS options with int value */
31533174#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
31543175 case LDAP_OPT_X_TLS_REQUIRE_CERT :
31553176#endif
@@ -3161,6 +3182,18 @@ PHP_FUNCTION(ldap_set_option)
31613182#endif
31623183#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
31633184 case LDAP_OPT_X_TLS_PROTOCOL_MAX :
3185+ #endif
3186+ /* TLS option change requires resetting TLS context */
3187+ LDAPG (tls_newctx ) = true;
3188+ ZEND_FALLTHROUGH ;
3189+ /* other options with int value */
3190+ case LDAP_OPT_DEREF :
3191+ case LDAP_OPT_SIZELIMIT :
3192+ case LDAP_OPT_TIMELIMIT :
3193+ case LDAP_OPT_PROTOCOL_VERSION :
3194+ case LDAP_OPT_ERROR_NUMBER :
3195+ #ifdef LDAP_OPT_DEBUG_LEVEL
3196+ case LDAP_OPT_DEBUG_LEVEL :
31643197#endif
31653198#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
31663199 case LDAP_OPT_X_KEEPALIVE_IDLE :
@@ -3234,17 +3267,7 @@ PHP_FUNCTION(ldap_set_option)
32343267 }
32353268 } break ;
32363269#endif
3237- /* options with string value */
3238- case LDAP_OPT_ERROR_STRING :
3239- #ifdef LDAP_OPT_HOST_NAME
3240- case LDAP_OPT_HOST_NAME :
3241- #endif
3242- #ifdef HAVE_LDAP_SASL
3243- case LDAP_OPT_X_SASL_MECH :
3244- case LDAP_OPT_X_SASL_REALM :
3245- case LDAP_OPT_X_SASL_AUTHCID :
3246- case LDAP_OPT_X_SASL_AUTHZID :
3247- #endif
3270+ /* TLS options with string value */
32483271#if (LDAP_API_VERSION > 2000 )
32493272 case LDAP_OPT_X_TLS_CACERTDIR :
32503273 case LDAP_OPT_X_TLS_CACERTFILE :
@@ -3258,6 +3281,20 @@ PHP_FUNCTION(ldap_set_option)
32583281#endif
32593282#ifdef LDAP_OPT_X_TLS_DHFILE
32603283 case LDAP_OPT_X_TLS_DHFILE :
3284+ #endif
3285+ /* TLS option change requires resetting TLS context */
3286+ LDAPG (tls_newctx ) = true;
3287+ ZEND_FALLTHROUGH ;
3288+ /* other options with string value */
3289+ case LDAP_OPT_ERROR_STRING :
3290+ #ifdef LDAP_OPT_HOST_NAME
3291+ case LDAP_OPT_HOST_NAME :
3292+ #endif
3293+ #ifdef HAVE_LDAP_SASL
3294+ case LDAP_OPT_X_SASL_MECH :
3295+ case LDAP_OPT_X_SASL_REALM :
3296+ case LDAP_OPT_X_SASL_AUTHCID :
3297+ case LDAP_OPT_X_SASL_AUTHZID :
32613298#endif
32623299#ifdef LDAP_OPT_MATCHED_DN
32633300 case LDAP_OPT_MATCHED_DN :
@@ -3675,6 +3712,9 @@ PHP_FUNCTION(ldap_start_tls)
36753712 zval * link ;
36763713 ldap_linkdata * ld ;
36773714 int rc , protocol = LDAP_VERSION3 ;
3715+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3716+ int val = 0 ;
3717+ #endif
36783718
36793719 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O" , & link , ldap_link_ce ) != SUCCESS ) {
36803720 RETURN_THROWS ();
@@ -3684,13 +3724,16 @@ PHP_FUNCTION(ldap_start_tls)
36843724 VERIFY_LDAP_LINK_CONNECTED (ld );
36853725
36863726 if (((rc = ldap_set_option (ld -> link , LDAP_OPT_PROTOCOL_VERSION , & protocol )) != LDAP_SUCCESS ) ||
3727+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3728+ (LDAPG (tls_newctx ) && (rc = ldap_set_option (ld -> link , LDAP_OPT_X_TLS_NEWCTX , & val )) != LDAP_OPT_SUCCESS ) ||
3729+ #endif
36873730 ((rc = ldap_start_tls_s (ld -> link , NULL , NULL )) != LDAP_SUCCESS )
36883731 ) {
36893732 php_error_docref (NULL , E_WARNING ,"Unable to start TLS: %s" , ldap_err2string (rc ));
36903733 RETURN_FALSE ;
3691- } else {
3692- RETURN_TRUE ;
36933734 }
3735+ LDAPG (tls_newctx ) = false;
3736+ RETURN_TRUE ;
36943737}
36953738/* }}} */
36963739#endif
@@ -4213,7 +4256,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
42134256 ext_functions ,
42144257 PHP_MINIT (ldap ),
42154258 PHP_MSHUTDOWN (ldap ),
4216- NULL ,
4259+ PHP_RINIT ( ldap ) ,
42174260 NULL ,
42184261 PHP_MINFO (ldap ),
42194262 PHP_LDAP_VERSION ,
0 commit comments