use asynchronous Start TLS exop; allow propagating TLS if used in the original connection; minor cleanup

This commit is contained in:
Pierangelo Masarati 2005-02-05 15:55:02 +00:00
parent e3a19bfa32
commit 43138aa500
4 changed files with 115 additions and 32 deletions

View File

@ -249,12 +249,20 @@ underlying libldap, with rebinding eventually performed if the
.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

View File

@ -94,8 +94,16 @@ struct ldapinfo {
#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;

View File

@ -87,7 +87,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
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 );
@ -242,21 +242,64 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
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;

View File

@ -213,26 +213,50 @@ ldap_back_db_config(
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
@ -723,7 +747,7 @@ parse_idassert(
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;