@@ -834,6 +834,21 @@ static PHP_GINIT_FUNCTION(ldap)
834834}
835835/* }}} */
836836
837+ /* {{{ PHP_RINIT_FUNCTION */
838+ static PHP_RINIT_FUNCTION (ldap )
839+ {
840+ #if defined(COMPILE_DL_LDAP ) && defined(ZTS )
841+ ZEND_TSRMLS_CACHE_UPDATE ();
842+ #endif
843+
844+ /* needed before first connect and after TLS option changes */
845+ LDAPG (tls_newctx ) = true;
846+
847+ return SUCCESS ;
848+ }
849+ /* }}} */
850+
851+
837852/* {{{ PHP_MINIT_FUNCTION */
838853PHP_MINIT_FUNCTION (ldap )
839854{
@@ -989,6 +1004,20 @@ PHP_FUNCTION(ldap_connect)
9891004 snprintf ( url , urllen , "ldap://%s:" ZEND_LONG_FMT , host , port );
9901005 }
9911006
1007+ #ifdef LDAP_OPT_X_TLS_NEWCTX
1008+ if (LDAPG (tls_newctx ) && url && !strncmp (url , "ldaps:" , 6 )) {
1009+ int val = 0 ;
1010+
1011+ /* ensure all pending TLS options are applied in a new context */
1012+ if (ldap_set_option (NULL , LDAP_OPT_X_TLS_NEWCTX , & val ) != LDAP_OPT_SUCCESS ) {
1013+ zval_ptr_dtor (return_value );
1014+ php_error_docref (NULL , E_WARNING , "Could not create new security context" );
1015+ RETURN_FALSE ;
1016+ }
1017+ LDAPG (tls_newctx ) = false;
1018+ }
1019+ #endif
1020+
9921021#ifdef LDAP_API_FEATURE_X_OPENLDAP
9931022 /* ldap_init() is deprecated, use ldap_initialize() instead.
9941023 */
@@ -3177,15 +3206,7 @@ PHP_FUNCTION(ldap_set_option)
31773206 }
31783207
31793208 switch (option ) {
3180- /* options with int value */
3181- case LDAP_OPT_DEREF :
3182- case LDAP_OPT_SIZELIMIT :
3183- case LDAP_OPT_TIMELIMIT :
3184- case LDAP_OPT_PROTOCOL_VERSION :
3185- case LDAP_OPT_ERROR_NUMBER :
3186- #ifdef LDAP_OPT_DEBUG_LEVEL
3187- case LDAP_OPT_DEBUG_LEVEL :
3188- #endif
3209+ /* TLS options with int value */
31893210#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
31903211 case LDAP_OPT_X_TLS_REQUIRE_CERT :
31913212#endif
@@ -3197,6 +3218,18 @@ PHP_FUNCTION(ldap_set_option)
31973218#endif
31983219#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
31993220 case LDAP_OPT_X_TLS_PROTOCOL_MAX :
3221+ #endif
3222+ /* TLS option change requires resetting TLS context */
3223+ LDAPG (tls_newctx ) = true;
3224+ ZEND_FALLTHROUGH ;
3225+ /* other options with int value */
3226+ case LDAP_OPT_DEREF :
3227+ case LDAP_OPT_SIZELIMIT :
3228+ case LDAP_OPT_TIMELIMIT :
3229+ case LDAP_OPT_PROTOCOL_VERSION :
3230+ case LDAP_OPT_ERROR_NUMBER :
3231+ #ifdef LDAP_OPT_DEBUG_LEVEL
3232+ case LDAP_OPT_DEBUG_LEVEL :
32003233#endif
32013234#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
32023235 case LDAP_OPT_X_KEEPALIVE_IDLE :
@@ -3253,17 +3286,7 @@ PHP_FUNCTION(ldap_set_option)
32533286 }
32543287 } break ;
32553288#endif
3256- /* options with string value */
3257- case LDAP_OPT_ERROR_STRING :
3258- #ifdef LDAP_OPT_HOST_NAME
3259- case LDAP_OPT_HOST_NAME :
3260- #endif
3261- #ifdef HAVE_LDAP_SASL
3262- case LDAP_OPT_X_SASL_MECH :
3263- case LDAP_OPT_X_SASL_REALM :
3264- case LDAP_OPT_X_SASL_AUTHCID :
3265- case LDAP_OPT_X_SASL_AUTHZID :
3266- #endif
3289+ /* TLS options with string value */
32673290#if (LDAP_API_VERSION > 2000 )
32683291 case LDAP_OPT_X_TLS_CACERTDIR :
32693292 case LDAP_OPT_X_TLS_CACERTFILE :
@@ -3277,6 +3300,20 @@ PHP_FUNCTION(ldap_set_option)
32773300#endif
32783301#ifdef LDAP_OPT_X_TLS_DHFILE
32793302 case LDAP_OPT_X_TLS_DHFILE :
3303+ #endif
3304+ /* TLS option change requires resetting TLS context */
3305+ LDAPG (tls_newctx ) = true;
3306+ ZEND_FALLTHROUGH ;
3307+ /* other options with string value */
3308+ case LDAP_OPT_ERROR_STRING :
3309+ #ifdef LDAP_OPT_HOST_NAME
3310+ case LDAP_OPT_HOST_NAME :
3311+ #endif
3312+ #ifdef HAVE_LDAP_SASL
3313+ case LDAP_OPT_X_SASL_MECH :
3314+ case LDAP_OPT_X_SASL_REALM :
3315+ case LDAP_OPT_X_SASL_AUTHCID :
3316+ case LDAP_OPT_X_SASL_AUTHZID :
32803317#endif
32813318#ifdef LDAP_OPT_MATCHED_DN
32823319 case LDAP_OPT_MATCHED_DN :
@@ -3696,6 +3733,9 @@ PHP_FUNCTION(ldap_start_tls)
36963733 zval * link ;
36973734 ldap_linkdata * ld ;
36983735 int rc , protocol = LDAP_VERSION3 ;
3736+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3737+ int val = 0 ;
3738+ #endif
36993739
37003740 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O" , & link , ldap_link_ce ) != SUCCESS ) {
37013741 RETURN_THROWS ();
@@ -3705,13 +3745,16 @@ PHP_FUNCTION(ldap_start_tls)
37053745 VERIFY_LDAP_LINK_CONNECTED (ld );
37063746
37073747 if (((rc = ldap_set_option (ld -> link , LDAP_OPT_PROTOCOL_VERSION , & protocol )) != LDAP_SUCCESS ) ||
3748+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3749+ (LDAPG (tls_newctx ) && (rc = ldap_set_option (ld -> link , LDAP_OPT_X_TLS_NEWCTX , & val )) != LDAP_OPT_SUCCESS ) ||
3750+ #endif
37083751 ((rc = ldap_start_tls_s (ld -> link , NULL , NULL )) != LDAP_SUCCESS )
37093752 ) {
37103753 php_error_docref (NULL , E_WARNING ,"Unable to start TLS: %s" , ldap_err2string (rc ));
37113754 RETURN_FALSE ;
3712- } else {
3713- RETURN_TRUE ;
37143755 }
3756+ LDAPG (tls_newctx ) = false;
3757+ RETURN_TRUE ;
37153758}
37163759/* }}} */
37173760#endif
@@ -4233,7 +4276,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
42334276 ext_functions ,
42344277 PHP_MINIT (ldap ),
42354278 PHP_MSHUTDOWN (ldap ),
4236- NULL ,
4279+ PHP_RINIT ( ldap ) ,
42374280 NULL ,
42384281 PHP_MINFO (ldap ),
42394282 PHP_LDAP_VERSION ,
0 commit comments