.RE
.LP
-.B start-tls
+.B tls-start
.br
-.B try-start-tls
+.B tls-try-start
+.br
+.B tls-propagate
+.br
+.B tls-try-propagate
.RS
-execute the start TLS extended operation when the connection is initialized.
-\fBtry-start-tls\fP continues operations if start TLS fails.
+execute the start TLS extended operation when the connection is initialized;
+only works if the URI directive protocol scheme is not \fBldaps://\fP.
+The \fBtls-propagate\fP version issues the Start TLS exop only if the original
+connection did.
+\fBtry-start-tls\fP and \fBtry-propagate-tls\fP continue operations
+if start TLS failed.
.RE
#define LDAP_BACK_F_NONE 0x00U
#define LDAP_BACK_F_SAVECRED 0x01U
#define LDAP_BACK_F_USE_TLS 0x02U
-#define LDAP_BACK_F_TLS_CRITICAL ( 0x04U | LDAP_BACK_F_USE_TLS )
-#define LDAP_BACK_F_CHASE_REFERRALS 0x8U
+#define LDAP_BACK_F_PROPAGATE_TLS 0x04U
+#define LDAP_BACK_F_TLS_CRITICAL 0x08U
+#define LDAP_BACK_F_CHASE_REFERRALS 0x10U
+
+#define LDAP_BACK_SAVECRED(li) ( (li)->flags & LDAP_BACK_F_SAVECRED )
+#define LDAP_BACK_USE_TLS(li) ( (li)->flags & LDAP_BACK_F_USE_TLS )
+#define LDAP_BACK_PROPAGATE_TLS(li) ( (li)->flags & LDAP_BACK_F_PROPAGATE_TLS )
+#define LDAP_BACK_TLS_CRITICAL(li) ( (li)->flags & LDAP_BACK_F_TLS_CRITICAL )
+#define LDAP_BACK_CHASE_REFERRALS(li) ( (li)->flags & LDAP_BACK_F_CHASE_REFERRALS )
+
Avlnode *conntree;
int rwm_started;
lc->lc_bound = 1;
ber_dupbv( &lc->lc_bound_ndn, &op->o_req_ndn );
- if ( li->flags & LDAP_BACK_F_SAVECRED ) {
+ if ( LDAP_BACK_SAVECRED( li ) ) {
if ( !BER_BVISNULL( &lc->lc_cred ) ) {
memset( lc->lc_cred.bv_val, 0,
lc->lc_cred.bv_len );
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
/* automatically chase referrals ("chase-referrals"/"dont-chase-referrals" statement) */
- if ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) {
+ if ( LDAP_BACK_CHASE_REFERRALS( li ) ) {
ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
}
/* start TLS ("start-tls"/"try-start-tls" statements) */
- if ( ( li->flags & LDAP_BACK_F_USE_TLS )
- && !ldap_is_ldaps_url( li->url )
- && ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS )
- {
+ if ( ( LDAP_BACK_USE_TLS( li ) || ( op->o_conn->c_is_tls && LDAP_BACK_PROPAGATE_TLS( li ) ) )
+ && !ldap_is_ldaps_url( li->url ) ) {
+ int rc, msgid;
+ LDAPMessage *res;
+ int retries = 1;
+
+retry:;
+ rc = ldap_start_tls( ld, NULL, NULL, &msgid );
+ if ( rc == LDAP_SUCCESS ) {
+ struct timeval tv = { 0, 0 };
+
+ rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
+ if ( rc < 0 ) {
+ rs->sr_err = LDAP_OTHER;
+
+ } else if ( rc == 0 ) {
+ if ( retries ) {
+ retries--;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000;
+ goto retry;
+ }
+ rs->sr_err = LDAP_OTHER;
+
+ } else {
+ if ( rc == LDAP_RES_EXTENDED ) {
+ rc = ldap_parse_result( ld, res,
+ &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
+ if ( rc != LDAP_SUCCESS ) {
+ rs->sr_err = rc;
+
+ /* FIXME: in case a referral
+ * is returned, should we try
+ * using it instead of the
+ * configured URI? */
+ } else if ( rs->sr_err == LDAP_REFERRAL ) {
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "unwilling to chase referral returned by Start TLS exop";
+ }
+
+ } else {
+ ldap_msgfree( res );
+ rs->sr_err = LDAP_OTHER;
+ }
+ }
+ }
+
/* if StartTLS is requested, only attempt it if the URL
* is not "ldaps://"; this may occur not only in case
* of misconfiguration, but also when used in the chain
* overlay, where the "uri" can be parsed out of a referral */
if ( rs->sr_err == LDAP_SERVER_DOWN
- || ( li->flags & LDAP_BACK_F_TLS_CRITICAL ) )
+ || ( rs->sr_err != LDAP_SUCCESS && LDAP_BACK_TLS_CRITICAL( li ) ) )
{
ldap_unbind_ext_s( ld, NULL, NULL );
goto error_return;
li->url = ch_strdup( argv[ 1 ] );
#endif
- /* start tls */
- } else if ( strcasecmp( argv[0], "start-tls" ) == 0 ) {
- if ( argc != 1 ) {
- fprintf( stderr,
- "%s: line %d: start-tls takes no arguments\n",
- fname, lineno );
- return( 1 );
- }
- li->flags |= LDAP_BACK_F_TLS_CRITICAL;
+ } else if ( strncasecmp( argv[0], "tls-", STRLENOF( "tls-" ) ) == 0 ) {
+
+ /* start tls */
+ if ( strcasecmp( argv[0], "tls-start" ) == 0 ) {
+ if ( argc != 1 ) {
+ fprintf( stderr,
+ "%s: line %d: tls-start takes no arguments\n",
+ fname, lineno );
+ return( 1 );
+ }
+ li->flags |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
- /* try start tls */
- } else if ( strcasecmp( argv[0], "try-start-tls" ) == 0 ) {
- if ( argc != 1 ) {
- fprintf( stderr,
- "%s: line %d: try-start-tls takes no arguments\n",
- fname, lineno );
- return( 1 );
+ /* try start tls */
+ } else if ( strcasecmp( argv[0], "tls-try-start" ) == 0 ) {
+ if ( argc != 1 ) {
+ fprintf( stderr,
+ "%s: line %d: tls-try-start takes no arguments\n",
+ fname, lineno );
+ return( 1 );
+ }
+ li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
+ li->flags |= LDAP_BACK_F_USE_TLS;
+
+ /* propagate start tls */
+ } else if ( strcasecmp( argv[0], "tls-propagate" ) == 0 ) {
+ if ( argc != 1 ) {
+ fprintf( stderr,
+ "%s: line %d: tls-propagate takes no arguments\n",
+ fname, lineno );
+ return( 1 );
+ }
+ li->flags |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
+
+ /* try start tls */
+ } else if ( strcasecmp( argv[0], "tls-try-propagate" ) == 0 ) {
+ if ( argc != 1 ) {
+ fprintf( stderr,
+ "%s: line %d: tls-try-propagate takes no arguments\n",
+ fname, lineno );
+ return( 1 );
+ }
+ li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
+ li->flags |= LDAP_BACK_F_PROPAGATE_TLS;
}
- li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
- li->flags |= LDAP_BACK_F_USE_TLS;
/* name to use for ldap_back_group */
} else if ( strcasecmp( argv[0], "acl-authcdn" ) == 0
li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
} else {
- fprintf( stderr, "%s: line %s: "
+ fprintf( stderr, "%s: line %d: "
"unknown authz mode \"%s\"\n",
fname, lineno, val );
return 1;