]> git.sur5r.net Git - openldap/commitdiff
address protocol version issues (ITS#4488)
authorPierangelo Masarati <ando@openldap.org>
Thu, 13 Apr 2006 16:20:00 +0000 (16:20 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 13 Apr 2006 16:20:00 +0000 (16:20 +0000)
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/modrdn.c

index 2399c85a6d80f086e329497d8fdd0702247d0f93..b1d791a22abea05eb562dda19593a084bee2741e 100644 (file)
@@ -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 */
index 32ef33d6dfd5c462bbb350a80eab5e24bd057beb..d728a584f6fc5fba21b51cc2102d072bf18bbcdb 100644 (file)
@@ -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]> <real", 2, 3, 0,
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
                ldap_back_cf_gen, NULL, NULL, NULL },
@@ -612,6 +621,14 @@ ldap_back_cf_gen( ConfigArgs *c )
                        value_add_one( &c->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 "
index 1ea94a0ba8e445d4b593d6f118df97ef7b0e3cb6..eb5690ce6c1b9b0d040144d48f501c2b33713c74 100644 (file)
@@ -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;
        }
 
index 4e5997a64c6d5474f6d7fa3ca47e2f22c1f91408..1f0afe0a0df2206d6693b1560a6263a7fecf61b0 100644 (file)
@@ -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 <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 */
        } else {
                return SLAP_CONF_UNKNOWN;
index 36d85be07f056e587ac96ff2805ff04328ecd8f2..5a9930229119ada01a0717c963b90111d97947dd 100644 (file)
@@ -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,
index a490553b64762317e15abd0d0a816eb3b936d4d2..a0f54f7b0883fc04f65fee940a58e5884791a2bb 100644 (file)
@@ -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
                 */