@@ -835,6 +835,21 @@ static PHP_GINIT_FUNCTION(ldap)
835835}
836836/* }}} */
837837
838+ /* {{{ PHP_RINIT_FUNCTION */
839+ static PHP_RINIT_FUNCTION (ldap )
840+ {
841+ #if defined(COMPILE_DL_LDAP ) && defined(ZTS )
842+ ZEND_TSRMLS_CACHE_UPDATE ();
843+ #endif
844+
845+ /* needed before first connect and after TLS option changes */
846+ LDAPG (tls_newctx ) = true;
847+
848+ return SUCCESS ;
849+ }
850+ /* }}} */
851+
852+
838853/* {{{ PHP_MINIT_FUNCTION */
839854PHP_MINIT_FUNCTION (ldap )
840855{
@@ -987,6 +1002,20 @@ PHP_FUNCTION(ldap_connect)
9871002 snprintf ( url , urllen , "ldap://%s:" ZEND_LONG_FMT , host , port );
9881003 }
9891004
1005+ #ifdef LDAP_OPT_X_TLS_NEWCTX
1006+ if (LDAPG (tls_newctx ) && url && !strncmp (url , "ldaps:" , 6 )) {
1007+ int val = 0 ;
1008+
1009+ /* ensure all pending TLS options are applied in a new context */
1010+ if (ldap_set_option (NULL , LDAP_OPT_X_TLS_NEWCTX , & val ) != LDAP_OPT_SUCCESS ) {
1011+ zval_ptr_dtor (return_value );
1012+ php_error_docref (NULL , E_WARNING , "Could not create new security context" );
1013+ RETURN_FALSE ;
1014+ }
1015+ LDAPG (tls_newctx ) = false;
1016+ }
1017+ #endif
1018+
9901019#ifdef LDAP_API_FEATURE_X_OPENLDAP
9911020 /* ldap_init() is deprecated, use ldap_initialize() instead.
9921021 */
@@ -3172,15 +3201,7 @@ PHP_FUNCTION(ldap_set_option)
31723201 }
31733202
31743203 switch (option ) {
3175- /* options with int value */
3176- case LDAP_OPT_DEREF :
3177- case LDAP_OPT_SIZELIMIT :
3178- case LDAP_OPT_TIMELIMIT :
3179- case LDAP_OPT_PROTOCOL_VERSION :
3180- case LDAP_OPT_ERROR_NUMBER :
3181- #ifdef LDAP_OPT_DEBUG_LEVEL
3182- case LDAP_OPT_DEBUG_LEVEL :
3183- #endif
3204+ /* TLS options with int value */
31843205#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
31853206 case LDAP_OPT_X_TLS_REQUIRE_CERT :
31863207#endif
@@ -3189,6 +3210,18 @@ PHP_FUNCTION(ldap_set_option)
31893210#endif
31903211#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
31913212 case LDAP_OPT_X_TLS_PROTOCOL_MIN :
3213+ #endif
3214+ /* TLS option change requires resetting TLS context */
3215+ LDAPG (tls_newctx ) = true;
3216+ ZEND_FALLTHROUGH ;
3217+ /* other options with int value */
3218+ case LDAP_OPT_DEREF :
3219+ case LDAP_OPT_SIZELIMIT :
3220+ case LDAP_OPT_TIMELIMIT :
3221+ case LDAP_OPT_PROTOCOL_VERSION :
3222+ case LDAP_OPT_ERROR_NUMBER :
3223+ #ifdef LDAP_OPT_DEBUG_LEVEL
3224+ case LDAP_OPT_DEBUG_LEVEL :
31923225#endif
31933226#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
31943227 case LDAP_OPT_X_KEEPALIVE_IDLE :
@@ -3245,17 +3278,7 @@ PHP_FUNCTION(ldap_set_option)
32453278 }
32463279 } break ;
32473280#endif
3248- /* options with string value */
3249- case LDAP_OPT_ERROR_STRING :
3250- #ifdef LDAP_OPT_HOST_NAME
3251- case LDAP_OPT_HOST_NAME :
3252- #endif
3253- #ifdef HAVE_LDAP_SASL
3254- case LDAP_OPT_X_SASL_MECH :
3255- case LDAP_OPT_X_SASL_REALM :
3256- case LDAP_OPT_X_SASL_AUTHCID :
3257- case LDAP_OPT_X_SASL_AUTHZID :
3258- #endif
3281+ /* TLS options with string value */
32593282#if (LDAP_API_VERSION > 2000 )
32603283 case LDAP_OPT_X_TLS_CACERTDIR :
32613284 case LDAP_OPT_X_TLS_CACERTFILE :
@@ -3269,6 +3292,20 @@ PHP_FUNCTION(ldap_set_option)
32693292#endif
32703293#ifdef LDAP_OPT_X_TLS_DHFILE
32713294 case LDAP_OPT_X_TLS_DHFILE :
3295+ #endif
3296+ /* TLS option change requires resetting TLS context */
3297+ LDAPG (tls_newctx ) = true;
3298+ ZEND_FALLTHROUGH ;
3299+ /* other options with string value */
3300+ case LDAP_OPT_ERROR_STRING :
3301+ #ifdef LDAP_OPT_HOST_NAME
3302+ case LDAP_OPT_HOST_NAME :
3303+ #endif
3304+ #ifdef HAVE_LDAP_SASL
3305+ case LDAP_OPT_X_SASL_MECH :
3306+ case LDAP_OPT_X_SASL_REALM :
3307+ case LDAP_OPT_X_SASL_AUTHCID :
3308+ case LDAP_OPT_X_SASL_AUTHZID :
32723309#endif
32733310#ifdef LDAP_OPT_MATCHED_DN
32743311 case LDAP_OPT_MATCHED_DN :
@@ -3688,6 +3725,9 @@ PHP_FUNCTION(ldap_start_tls)
36883725 zval * link ;
36893726 ldap_linkdata * ld ;
36903727 int rc , protocol = LDAP_VERSION3 ;
3728+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3729+ int val = 0 ;
3730+ #endif
36913731
36923732 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O" , & link , ldap_link_ce ) != SUCCESS ) {
36933733 RETURN_THROWS ();
@@ -3697,13 +3737,16 @@ PHP_FUNCTION(ldap_start_tls)
36973737 VERIFY_LDAP_LINK_CONNECTED (ld );
36983738
36993739 if (((rc = ldap_set_option (ld -> link , LDAP_OPT_PROTOCOL_VERSION , & protocol )) != LDAP_SUCCESS ) ||
3740+ #ifdef LDAP_OPT_X_TLS_NEWCTX
3741+ (LDAPG (tls_newctx ) && (rc = ldap_set_option (ld -> link , LDAP_OPT_X_TLS_NEWCTX , & val )) != LDAP_OPT_SUCCESS ) ||
3742+ #endif
37003743 ((rc = ldap_start_tls_s (ld -> link , NULL , NULL )) != LDAP_SUCCESS )
37013744 ) {
37023745 php_error_docref (NULL , E_WARNING ,"Unable to start TLS: %s" , ldap_err2string (rc ));
37033746 RETURN_FALSE ;
3704- } else {
3705- RETURN_TRUE ;
37063747 }
3748+ LDAPG (tls_newctx ) = false;
3749+ RETURN_TRUE ;
37073750}
37083751/* }}} */
37093752#endif
@@ -4218,7 +4261,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
42184261 ext_functions ,
42194262 PHP_MINIT (ldap ),
42204263 PHP_MSHUTDOWN (ldap ),
4221- NULL ,
4264+ PHP_RINIT ( ldap ) ,
42224265 NULL ,
42234266 PHP_MINFO (ldap ),
42244267 PHP_LDAP_VERSION ,
0 commit comments