From bd8514fb1eb55b84b75e1166af568516cedb93b5 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 13 Apr 2006 16:20:00 +0000 Subject: [PATCH] address protocol version issues (ITS#4488) --- servers/slapd/back-ldap/bind.c | 56 +++++++++++++++++++++++++++----- servers/slapd/back-ldap/config.c | 34 +++++++++++++++++++ servers/slapd/back-ldap/modrdn.c | 20 ++++++++++-- servers/slapd/back-meta/config.c | 32 ++++++++++++++++++ servers/slapd/back-meta/conn.c | 14 ++++++-- servers/slapd/back-meta/modrdn.c | 23 ++++++++++--- 6 files changed, 160 insertions(+), 19 deletions(-) diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 2399c85a6d..b1d791a22a 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -355,13 +355,15 @@ ldap_back_start_tls( } if ( protocol < LDAP_VERSION3 ) { - protocol = LDAP_VERSION3; - /* Set LDAP version */ - ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, - (const void *)&protocol ); + /* we should rather bail out... */ + rc = LDAP_UNWILLING_TO_PERFORM; + *text = "invalid protocol version"; + } + + if ( rc == LDAP_SUCCESS ) { + rc = ldap_start_tls( ld, NULL, NULL, &msgid ); } - rc = ldap_start_tls( ld, NULL, NULL, &msgid ); if ( rc == LDAP_SUCCESS ) { LDAPMessage *res = NULL; 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 ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - int vers = op->o_protocol; + int version; LDAP *ld = NULL; #ifdef HAVE_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 * 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 */ - 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) */ 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 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 ) ) { ndn = op->o_conn->c_ndn; @@ -1460,6 +1483,21 @@ ldap_back_proxy_authz_ctrl( 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, * but if it is not set this test fails. We need a different * means to detect if idassert is enabled */ diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 32ef33d6df..d728a584f6 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -63,6 +63,7 @@ enum { LDAP_BACK_CFG_IDLE_TIMEOUT, LDAP_BACK_CFG_CONN_TTL, LDAP_BACK_CFG_NETWORK_TIMEOUT, + LDAP_BACK_CFG_VERSION, LDAP_BACK_CFG_REWRITE, LDAP_BACK_CFG_LAST @@ -241,6 +242,14 @@ static ConfigTable ldapcfg[] = { "SYNTAX OMsDirectoryString " "SINGLE-VALUE )", 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]> rvalue_vals, &bv ); } break; + case LDAP_BACK_CFG_VERSION: + if ( li->li_version == 0 ) { + return 1; + } + + c->value_int = li->li_version; + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -701,6 +718,10 @@ ldap_back_cf_gen( ConfigArgs *c ) li->li_network_timeout = 0; break; + case LDAP_BACK_CFG_VERSION: + li->li_version = 0; + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1291,6 +1312,19 @@ done_url:; li->li_network_timeout = (time_t)t; } 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: snprintf( c->msg, sizeof( c->msg ), "rewrite/remap capabilities have been moved " diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 1ea94a0ba8..eb5690ce6c 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -51,9 +51,25 @@ ldap_back_modrdn( } 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; } diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 4e5997a64c..1f0afe0a0d 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -1050,6 +1050,38 @@ meta_back_db_config( 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 \"\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 \"\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 \"\n", + fname, lineno, argv[ 1 ] ); + return 1; + } + /* anything else */ } else { return SLAP_CONF_UNKNOWN; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 36d85be07f..5a99302291 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -260,7 +260,7 @@ meta_back_init_one_conn( { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; - int vers; + int version; dncookie dc; 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 * bound with a particular version, then so can we. */ - vers = op->o_conn->c_protocol; - ldap_set_option( msc->msc_ld, LDAP_OPT_PROTOCOL_VERSION, &vers ); + if ( mt->mt_version != 0 ) { + 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) */ ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS, diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index a490553b64..a0f54f7b08 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -55,7 +55,6 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) dc.rs = rs; if ( op->orr_newSup ) { - int version = LDAP_VERSION3; /* * NOTE: the newParent, if defined, must be on the @@ -76,11 +75,25 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) * feature from back-ldap */ - /* newSuperior needs LDAPv3; if we got here, we can safely - * enforce it */ - ldap_set_option( mc->mc_conns[ candidate ].msc_ld, - LDAP_OPT_PROTOCOL_VERSION, &version ); + /* needs LDAPv3 */ + switch ( mi->mi_targets[ candidate ].mt_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; + maperr = 0; + goto cleanup; + } + /* * Rewrite the new superior, if defined and required */ -- 2.39.5