address protocol version issues (ITS#4488)

This commit is contained in:
Pierangelo Masarati 2006-04-13 16:20:00 +00:00
parent 423a2c73f4
commit bd8514fb1e
6 changed files with 160 additions and 19 deletions

View File

@ -355,13 +355,15 @@ ldap_back_start_tls(
} }
if ( protocol < LDAP_VERSION3 ) { if ( protocol < LDAP_VERSION3 ) {
protocol = LDAP_VERSION3; /* we should rather bail out... */
/* Set LDAP version */ rc = LDAP_UNWILLING_TO_PERFORM;
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, *text = "invalid protocol version";
(const void *)&protocol ); }
if ( rc == LDAP_SUCCESS ) {
rc = ldap_start_tls( ld, NULL, NULL, &msgid );
} }
rc = ldap_start_tls( ld, NULL, NULL, &msgid );
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
LDAPMessage *res = NULL; LDAPMessage *res = NULL;
struct timeval tv; struct timeval tv;
@ -469,7 +471,7 @@ static int
ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{ {
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
int vers = op->o_protocol; int version;
LDAP *ld = NULL; LDAP *ld = NULL;
#ifdef HAVE_TLS #ifdef HAVE_TLS
int is_tls = op->o_conn->c_is_tls; int is_tls = op->o_conn->c_is_tls;
@ -485,11 +487,17 @@ ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_bac
/* Set LDAP version. This will always succeed: If the client /* Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we. * bound with a particular version, then so can we.
*/ */
if ( vers == 0 ) { if ( li->li_version != 0 ) {
version = li->li_version;
} else if ( op->o_protocol != 0 ) {
version = op->o_protocol;
} else {
/* assume it's an internal op; set to LDAPv3 */ /* assume it's an internal op; set to LDAPv3 */
vers = LDAP_VERSION3; version = LDAP_VERSION3;
} }
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers ); ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&version );
/* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */ /* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */
ldap_set_option( ld, LDAP_OPT_REFERRALS, ldap_set_option( ld, LDAP_OPT_REFERRALS,
@ -1205,6 +1213,21 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_b
int msgid; int msgid;
int rc; int rc;
/* don't proxyAuthz if protocol is not LDAPv3 */
switch ( li->li_version ) {
case LDAP_VERSION3:
break;
case 0:
if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
break;
}
/* fall thru */
default:
goto done;
}
if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) { if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
ndn = op->o_conn->c_ndn; ndn = op->o_conn->c_ndn;
@ -1460,6 +1483,21 @@ ldap_back_proxy_authz_ctrl(
rs->sr_err = LDAP_SUCCESS; rs->sr_err = LDAP_SUCCESS;
/* don't proxyAuthz if protocol is not LDAPv3 */
switch ( li->li_version ) {
case LDAP_VERSION3:
break;
case 0:
if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
break;
}
/* fall thru */
default:
goto done;
}
/* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID, /* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
* but if it is not set this test fails. We need a different * but if it is not set this test fails. We need a different
* means to detect if idassert is enabled */ * means to detect if idassert is enabled */

View File

@ -63,6 +63,7 @@ enum {
LDAP_BACK_CFG_IDLE_TIMEOUT, LDAP_BACK_CFG_IDLE_TIMEOUT,
LDAP_BACK_CFG_CONN_TTL, LDAP_BACK_CFG_CONN_TTL,
LDAP_BACK_CFG_NETWORK_TIMEOUT, LDAP_BACK_CFG_NETWORK_TIMEOUT,
LDAP_BACK_CFG_VERSION,
LDAP_BACK_CFG_REWRITE, LDAP_BACK_CFG_REWRITE,
LDAP_BACK_CFG_LAST LDAP_BACK_CFG_LAST
@ -241,6 +242,14 @@ static ConfigTable ldapcfg[] = {
"SYNTAX OMsDirectoryString " "SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", "SINGLE-VALUE )",
NULL, NULL }, NULL, NULL },
{ "protocol-version", "version", 2, 0, 0,
ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
"NAME 'olcDbProtocolVersion' "
"DESC 'protocol version' "
"SYNTAX OMsInteger "
"SINGLE-VALUE )",
NULL, NULL },
{ "suffixmassage", "[virtual]> <real", 2, 3, 0, { "suffixmassage", "[virtual]> <real", 2, 3, 0,
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
ldap_back_cf_gen, NULL, NULL, NULL }, ldap_back_cf_gen, NULL, NULL, NULL },
@ -612,6 +621,14 @@ ldap_back_cf_gen( ConfigArgs *c )
value_add_one( &c->rvalue_vals, &bv ); value_add_one( &c->rvalue_vals, &bv );
} break; } break;
case LDAP_BACK_CFG_VERSION:
if ( li->li_version == 0 ) {
return 1;
}
c->value_int = li->li_version;
break;
default: default:
/* FIXME: we need to handle all... */ /* FIXME: we need to handle all... */
assert( 0 ); assert( 0 );
@ -701,6 +718,10 @@ ldap_back_cf_gen( ConfigArgs *c )
li->li_network_timeout = 0; li->li_network_timeout = 0;
break; break;
case LDAP_BACK_CFG_VERSION:
li->li_version = 0;
break;
default: default:
/* FIXME: we need to handle all... */ /* FIXME: we need to handle all... */
assert( 0 ); assert( 0 );
@ -1291,6 +1312,19 @@ done_url:;
li->li_network_timeout = (time_t)t; li->li_network_timeout = (time_t)t;
} break; } break;
case LDAP_BACK_CFG_VERSION:
switch ( c->value_int ) {
case 0:
case LDAP_VERSION2:
case LDAP_VERSION3:
li->li_version = c->value_int;
break;
default:
return 1;
}
break;
case LDAP_BACK_CFG_REWRITE: case LDAP_BACK_CFG_REWRITE:
snprintf( c->msg, sizeof( c->msg ), snprintf( c->msg, sizeof( c->msg ),
"rewrite/remap capabilities have been moved " "rewrite/remap capabilities have been moved "

View File

@ -51,9 +51,25 @@ ldap_back_modrdn(
} }
if ( op->orr_newSup ) { if ( op->orr_newSup ) {
int version = LDAP_VERSION3; /* needs LDAPv3 */
switch ( li->li_version ) {
case LDAP_VERSION3:
break;
case 0:
if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
break;
}
/* fall thru */
default:
/* op->o_protocol cannot be anything but LDAPv3,
* otherwise wouldn't be here */
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
send_ldap_result( op, rs );
goto cleanup;
}
ldap_set_option( lc->lc_ld, LDAP_OPT_PROTOCOL_VERSION, &version );
newSup = op->orr_newSup->bv_val; newSup = op->orr_newSup->bv_val;
} }

View File

@ -1050,6 +1050,38 @@ meta_back_db_config(
mi->mi_targets[ i ].mt_nretries = nretries; mi->mi_targets[ i ].mt_nretries = nretries;
} }
} else if ( strcasecmp( argv[ 0 ], "protocol-version" ) == 0 ) {
int *version = mi->mi_ntargets ?
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_version
: &mi->mi_version;
if ( argc != 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: need value in \"protocol-version <version>\"\n",
fname, lineno, 0 );
return 1;
}
if ( lutil_atou( version, argv[ 1 ] ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse version \"%s\" in \"protocol-version <version>\"\n",
fname, lineno, argv[ 1 ] );
return 1;
}
switch ( *version ) {
case 0:
case LDAP_VERSION2:
case LDAP_VERSION3:
break;
default:
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unsupported version \"%s\" in \"protocol-version <version>\"\n",
fname, lineno, argv[ 1 ] );
return 1;
}
/* anything else */ /* anything else */
} else { } else {
return SLAP_CONF_UNKNOWN; return SLAP_CONF_UNKNOWN;

View File

@ -260,7 +260,7 @@ meta_back_init_one_conn(
{ {
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metasingleconn_t *msc = &mc->mc_conns[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int vers; int version;
dncookie dc; dncookie dc;
int isauthz = ( candidate == mc->mc_authz_target ); int isauthz = ( candidate == mc->mc_authz_target );
@ -285,8 +285,16 @@ meta_back_init_one_conn(
* Set LDAP version. This will always succeed: If the client * Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we. * bound with a particular version, then so can we.
*/ */
vers = op->o_conn->c_protocol; if ( mt->mt_version != 0 ) {
ldap_set_option( msc->msc_ld, LDAP_OPT_PROTOCOL_VERSION, &vers ); version = mt->mt_version;
} else if ( op->o_conn->c_protocol != 0 ) {
version = op->o_conn->c_protocol;
} else {
version = LDAP_VERSION3;
}
ldap_set_option( msc->msc_ld, LDAP_OPT_PROTOCOL_VERSION, &version );
/* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */ /* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */
ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS, ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS,

View File

@ -55,7 +55,6 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
dc.rs = rs; dc.rs = rs;
if ( op->orr_newSup ) { if ( op->orr_newSup ) {
int version = LDAP_VERSION3;
/* /*
* NOTE: the newParent, if defined, must be on the * NOTE: the newParent, if defined, must be on the
@ -76,11 +75,25 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
* feature from back-ldap * feature from back-ldap
*/ */
/* newSuperior needs LDAPv3; if we got here, we can safely /* needs LDAPv3 */
* enforce it */ switch ( mi->mi_targets[ candidate ].mt_version ) {
ldap_set_option( mc->mc_conns[ candidate ].msc_ld, case LDAP_VERSION3:
LDAP_OPT_PROTOCOL_VERSION, &version ); break;
case 0:
if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
break;
}
/* fall thru */
default:
/* op->o_protocol cannot be anything but LDAPv3,
* otherwise wouldn't be here */
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
maperr = 0;
goto cleanup;
}
/* /*
* Rewrite the new superior, if defined and required * Rewrite the new superior, if defined and required
*/ */