]> git.sur5r.net Git - openldap/commitdiff
improve previous commit; consistently use dn/ndn; add support for LDAP_SCOPE_SUBORDINATE
authorPierangelo Masarati <ando@openldap.org>
Sun, 3 Oct 2004 21:08:54 +0000 (21:08 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 3 Oct 2004 21:08:54 +0000 (21:08 +0000)
servers/slapd/back-sql/add.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/compare.c
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/search.c
servers/slapd/back-sql/util.c

index 8bb4c727e99b6966afc14c204cc9f0bf7e9134e4..19fd90ef7209772a5648f74d471f10c73c5b7fbe 100644 (file)
@@ -752,7 +752,7 @@ backsql_add_attr(
                 * to build the entry
                 */
                if ( at->a_desc == slap_schema.si_ad_objectClass ) {
-                       if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) )
+                       if ( dn_match( at_val, &oc->bom_oc->soc_cname ) )
                        {
                                continue;
                        }
@@ -882,6 +882,7 @@ backsql_add( Operation *op, SlapReply *rs )
                                *at_objectClass = NULL;
        struct berval           pdn;
        struct berval           realdn = BER_BVNULL,
+                               realndn = BER_BVNULL,
                                realpdn = BER_BVNULL;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
@@ -965,14 +966,23 @@ backsql_add( Operation *op, SlapReply *rs )
        if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "backsql_api_dn2odbc(\"%s\") failed\n", 
-                       op->oq_add.rs_e->e_name.bv_val,
-                       op->oq_add.rs_e->e_name.bv_val, 0 );
+                       op->oq_add.rs_e->e_name.bv_val, realdn.bv_val, 0 );
+               rs->sr_err = LDAP_OTHER;
+               rs->sr_text = "SQL-backend error";
+               goto done;
+       }
+
+       realndn = op->oq_add.rs_e->e_nname;
+       if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
+               Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+                       "backsql_api_dn2odbc(\"%s\") failed\n", 
+                       op->oq_add.rs_e->e_name.bv_val, realndn.bv_val, 0 );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
                goto done;
        }
 
-       rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realdn );
+       rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realndn );
        if ( rs->sr_err == LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
                        "entry exists\n",
@@ -1388,10 +1398,15 @@ done:;
        {
                ch_free( realdn.bv_val );
        }
+       if ( !BER_BVISNULL( &realndn )
+                       && realndn.bv_val != op->oq_add.rs_e->e_nname.bv_val )
+       {
+               ch_free( realndn.bv_val );
+       }
        if ( !BER_BVISNULL( &realpdn ) && realpdn.bv_val != pdn.bv_val ) {
                ch_free( realpdn.bv_val );
        }
-       if ( !BER_BVISNULL( &parent_id.eid_dn ) ) {
+       if ( !BER_BVISNULL( &parent_id.eid_ndn ) ) {
                (void)backsql_free_entryID( &parent_id, 0 );
        }
 
index fa74a36d2a1c7c05c2d8354f54d93bfb26304cb0..d41ecd05795ba7a942be87b0f83ffd7f909690bc 100644 (file)
@@ -153,13 +153,14 @@ typedef struct backsql_entryID {
 
        unsigned long           eid_oc_id;
        struct berval           eid_dn;
+       struct berval           eid_ndn;
        struct backsql_entryID  *eid_next;
 } backsql_entryID;
 
 #ifdef BACKSQL_ARBITRARY_KEY
-#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, NULL }
+#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, BER_BVNULL, NULL }
 #else /* ! BACKSQL_ARBITRARY_KEY */
-#define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, NULL }
+#define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, BER_BVNULL, NULL }
 #endif /* BACKSQL_ARBITRARY_KEY */
 
 /*
@@ -265,9 +266,14 @@ typedef struct backsql_srch_info {
 #define        BSQL_SF_ALL_OPER                0x0001
 #define BSQL_SF_FILTER_HASSUBORDINATE  0x0002
 
-       struct berval           *bsi_base_dn;
+       struct berval           *bsi_base_ndn;
        backsql_entryID         bsi_base_id;
        int                     bsi_scope;
+/* BACKSQL_SCOPE_BASE_LIKE can be set by API in ors_scope
+ * whenever the search base DN contains chars that cannot
+ * be mapped into the charset used in the RDBMS; so they're
+ * turned into '%' and an approximate ('LIKE') condition
+ * is used */
 #define BACKSQL_SCOPE_BASE_LIKE                ( LDAP_SCOPE_BASE | 0x1000 )
        Filter                  *bsi_filter;
        int                     bsi_slimit,
index 836b865fa4d758602f368a335a672d99ba109638..7803776f6ba6a122def744745624c3add50cafd9 100644 (file)
@@ -38,7 +38,7 @@ backsql_bind( Operation *op, SlapReply *rs )
        backsql_srch_info       bsi;
        AttributeName           anlist[2];
        int                     rc;
-       struct berval           dn;
+       struct berval           ndn;
  
        Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
 
@@ -73,8 +73,8 @@ backsql_bind( Operation *op, SlapReply *rs )
                return 1;
        }
 
-       dn = op->o_req_ndn;
-       if ( backsql_api_dn2odbc( op, rs, &dn ) ) {
+       ndn = op->o_req_ndn;
+       if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
                        "backsql_api_dn2odbc failed\n", 
                        0, 0, 0 );
@@ -87,11 +87,11 @@ backsql_bind( Operation *op, SlapReply *rs )
        anlist[0].an_desc = password;
        anlist[1].an_name.bv_val = NULL;
 
-       rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, 
+       rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE, 
                        -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
        if ( rc != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
-                       "could not retrieve bind dn id - no such entry\n", 
+                       "could not retrieve bindDN ID - no such entry\n", 
                        0, 0, 0 );
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
                send_ldap_result( op, rs );
@@ -134,7 +134,7 @@ backsql_bind( Operation *op, SlapReply *rs )
        }
 
 error_return:;
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
                (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
        }
 
@@ -143,8 +143,8 @@ error_return:;
                return 1;
        }
        
-       if ( dn.bv_val != op->o_req_dn.bv_val ) {
-               ch_free( dn.bv_val );
+       if ( ndn.bv_val != op->o_req_ndn.bv_val ) {
+               ch_free( ndn.bv_val );
        }
 
        Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
index ab2a2d0bdaf34e01d81515bc26b04636241cf1e1..1f64cc749c06453eb99195932a1d34ffdddbd7b5 100644 (file)
@@ -37,7 +37,7 @@ backsql_compare( Operation *op, SlapReply *rs )
        backsql_srch_info       bsi;
        int                     rc;
        AttributeName           anlist[2];
-       struct berval           dn;
+       struct berval           ndn;
 
        user_entry.e_name.bv_val = NULL;
        user_entry.e_name.bv_len = 0;
@@ -58,8 +58,8 @@ backsql_compare( Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-       dn = op->o_req_ndn;
-       if ( backsql_api_dn2odbc( op, rs, &dn ) ) {
+       ndn = op->o_req_ndn;
+       if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
                        "backsql_api_dn2odbc failed\n", 
                        0, 0, 0 );
@@ -95,11 +95,11 @@ backsql_compare( Operation *op, SlapReply *rs )
                user_entry.e_attrs = nrs.sr_operational_attrs;
 
        } else {
-               rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, 
+               rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE, 
                                -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
                if ( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
-                               "could not retrieve compare dn id - no such entry\n", 
+                               "could not retrieve compareDN ID - no such entry\n", 
                                0, 0, 0 );
                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
                        goto return_results;
@@ -145,12 +145,12 @@ backsql_compare( Operation *op, SlapReply *rs )
 return_results:;
        send_ldap_result( op, rs );
 
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
                (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
        }
 
-       if ( dn.bv_val != op->o_req_dn.bv_val ) {
-               ch_free( dn.bv_val );
+       if ( ndn.bv_val != op->o_req_ndn.bv_val ) {
+               ch_free( ndn.bv_val );
        }
 
        if ( e != NULL ) {
index 5cf9b6456eeec29784f9d631c6076536d817b465..f9e14f0cad120b5af7e963e8ef1138051d8fa546 100644 (file)
@@ -120,6 +120,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                goto done;
        }
        
+       /* FIXME: API... */
        rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
index 13d9840dbb64f4f6d1a29a0b64b083fcc892df34..1153bd0ec7ee7bd352f22b8a0644d59a57f968f1 100644 (file)
@@ -42,9 +42,16 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
 
        next = id->eid_next;
 
-       if ( id->eid_dn.bv_val != NULL ) {
-               free( id->eid_dn.bv_val );
-               BER_BVZERO( &id->eid_dn );
+       if ( !BER_BVISNULL( &id->eid_ndn ) ) {
+               if ( !BER_BVISNULL( &id->eid_dn )
+                               && id->eid_dn.bv_val != id->eid_ndn.bv_val )
+               {
+                       free( id->eid_dn.bv_val );
+                       BER_BVZERO( &id->eid_dn );
+               }
+
+               free( id->eid_ndn.bv_val );
+               BER_BVZERO( &id->eid_ndn );
        }
 
 #ifdef BACKSQL_ARBITRARY_KEY
@@ -66,12 +73,15 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
        return next;
 }
 
+/*
+ * NOTE: the dn must be normalized
+ */
 int
 backsql_dn2id(
        backsql_info            *bi,
        backsql_entryID         *id,
        SQLHDBC                 dbh,
-       struct berval           *dn )
+       struct berval           *ndn )
 {
        SQLHSTMT                sth; 
        BACKSQL_ROW_NTS         row;
@@ -80,7 +90,7 @@ backsql_dn2id(
 
        /* TimesTen */
        char                    upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
-       struct berval           toBind;
+       struct berval           tbbDN;
        int                     i, j;
 
        /*
@@ -91,18 +101,18 @@ backsql_dn2id(
         */
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn=\"%s\"%s\n", 
-                       dn->bv_val, id == NULL ? " (no ID)" : "", 0 );
+                       ndn->bv_val, id == NULL ? " (no ID)" : "", 0 );
 
-       if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
+       if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
                Debug( LDAP_DEBUG_TRACE, 
                        "backsql_dn2id(): DN \"%s\" (%ld bytes) "
                        "exceeds max DN length (%d):\n",
-                       dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
+                       ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
                return LDAP_OTHER;
        }
 
        /* return baseObject if available and matches */
-       if ( bi->sql_baseObject != NULL && bvmatch( dn, &bi->sql_baseObject->e_nname ) ) {
+       if ( bi->sql_baseObject != NULL && dn_match( ndn, &bi->sql_baseObject->e_nname ) ) {
                if ( id != NULL ) {
 #ifdef BACKSQL_ARBITRARY_KEY
                        ber_dupbv( &id->eid_id, &backsql_baseObject_bv );
@@ -113,7 +123,8 @@ backsql_dn2id(
 #endif /* ! BACKSQL_ARBITRARY_KEY */
                        id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
 
-                       ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_nname );
+                       ber_dupbv( &id->eid_ndn, &bi->sql_baseObject->e_nname );
+                       ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_name );
 
                        id->eid_next = NULL;
                }
@@ -140,36 +151,36 @@ backsql_dn2id(
                 * that can be searched using indexes
                 */
 
-               for ( i = 0, j = dn->bv_len - 1; dn->bv_val[ i ]; i++, j--) {
-                       upperdn[ i ] = dn->bv_val[ j ];
+               for ( i = 0, j = ndn->bv_len - 1; ndn->bv_val[ i ]; i++, j--) {
+                       upperdn[ i ] = ndn->bv_val[ j ];
                }
                upperdn[ i ] = '\0';
                ldap_pvt_str2upper( upperdn );
 
                Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn=\"%s\"\n",
                                upperdn, 0, 0 );
-               ber_str2bv( upperdn, 0, 0, &toBind );
+               ber_str2bv( upperdn, 0, 0, &tbbDN );
 
        } else {
                if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
-                       AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
+                       AC_MEMCPY( upperdn, ndn->bv_val, ndn->bv_len + 1 );
                        ldap_pvt_str2upper( upperdn );
                        Debug( LDAP_DEBUG_TRACE,
                                "==>backsql_dn2id(): upperdn=\"%s\"\n",
                                upperdn, 0, 0 );
-                       ber_str2bv( upperdn, 0, 0, &toBind );
+                       ber_str2bv( upperdn, 0, 0, &tbbDN );
 
                } else {
-                       toBind = *dn;
+                       tbbDN = *ndn;
                }
        }
 
-       rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &toBind );
+       rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
        if ( rc != SQL_SUCCESS) {
                /* end TimesTen */ 
                Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
                        "error binding dn=\"%s\" parameter:\n", 
-                       toBind.bv_val, 0, 0 );
+                       tbbDN.bv_val, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
                return LDAP_OTHER;
@@ -179,7 +190,7 @@ backsql_dn2id(
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
                        "error executing query (\"%s\", \"%s\"):\n", 
-                       bi->sql_id_query, toBind.bv_val, 0 );
+                       bi->sql_id_query, tbbDN.bv_val, 0 );
                backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
                return LDAP_OTHER;
@@ -188,11 +199,21 @@ backsql_dn2id(
        backsql_BindRowAsStrings( sth, &row );
        rc = SQLFetch( sth );
        if ( BACKSQL_SUCCESS( rc ) ) {
-               res = LDAP_SUCCESS;
-               Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%s keyval=%s oc_id=%s\n",
-                               row.cols[ 0 ], row.cols[ 1 ], row.cols[ 2 ] );
+               char    buf[BUFSIZ];
 
+#ifdef LDAP_DEBUG
+               snprintf( buf, sizeof(buf),
+                       "id=%s keyval=%s oc_id=%s dn=%s",
+                       row.cols[ 0 ], row.cols[ 1 ],
+                       row.cols[ 2 ], row.cols[ 3 ] );
+               Debug( LDAP_DEBUG_TRACE,
+                       "<==backsql_dn2id(): %s\n", buf, 0, 0 );
+#endif /* LDAP_DEBUG */
+
+               res = LDAP_SUCCESS;
                if ( id != NULL ) {
+                       struct berval   dn;
+
 #ifdef BACKSQL_ARBITRARY_KEY
                        ber_str2bv( row.cols[ 0 ], 0, 1, &id->eid_id );
                        ber_str2bv( row.cols[ 1 ], 0, 1, &id->eid_keyval );
@@ -202,7 +223,20 @@ backsql_dn2id(
 #endif /* ! BACKSQL_ARBITRARY_KEY */
                        id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 );
 
-                       ber_dupbv( &id->eid_dn, dn );
+                       ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
+
+                       res = dnPrettyNormal( NULL, &dn, &id->eid_dn, &id->eid_ndn, NULL );
+                       if ( res != LDAP_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "<==backsql_dn2id(\"%s\"): "
+                                       "dnPrettyNormal failed (%d: %s)\n",
+                                       ndn->bv_val, res,
+                                       ldap_err2string( res ) );
+
+                               /* cleanup... */
+                               (void)backsql_free_entryID( id, 0 );
+                       }
+
                        id->eid_next = NULL;
                }
 
@@ -456,12 +490,8 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
                goto done;
        }
 
-       rc = dnPrettyNormal( NULL, &eid->eid_dn,
-                       &bsi->bsi_e->e_name, &bsi->bsi_e->e_nname,
-                       bsi->bsi_op->o_tmpmemctx );
-       if ( rc != LDAP_SUCCESS ) {
-               return rc;
-       }
+       ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, bsi->bsi_op->o_tmpmemctx );
+       ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, bsi->bsi_op->o_tmpmemctx );
 
        bsi->bsi_e->e_attrs = NULL;
        bsi->bsi_e->e_private = NULL;
index 2e43e13c120cd5ddd5f1ed44d465e8323c45596c..168d4cc8bbc5487c99e069d43d1bade913eb3eb4 100644 (file)
@@ -61,6 +61,7 @@ backsql_modify( Operation *op, SlapReply *rs )
                return 1;
        }
 
+       /* FIXME: API... */
        rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modify(): "
index 5cade96a3c43eed103e8b5558a4ef6d082c285e9..f57d6e67e45602b80a3bb8696a3cd862aaf1d08a 100644 (file)
@@ -65,6 +65,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                return 1;
        }
 
+       /* FIXME: API... */
        rs->sr_err = backsql_dn2id( bi, &e_id, dbh, &op->o_req_ndn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
@@ -191,6 +192,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
        Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): new entry dn is \"%s\"\n",
                        new_dn.bv_val, 0, 0 );
 
+       /* FIXME: API... */
        rs->sr_err = backsql_dn2id( bi, &pe_id, dbh, &p_ndn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
@@ -211,6 +213,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
        (void)backsql_free_entryID( &pe_id, 0 );
 
+       /* FIXME: API... */
        rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
@@ -450,7 +453,7 @@ modrdn_return:;
                }
        }
 
-       if ( new_pe_id.eid_dn.bv_val ) {
+       if ( !BER_BVISNULL( &new_pe_id.eid_ndn ) ) {
                (void)backsql_free_entryID( &new_pe_id, 0 );
        }
 
index 8e4f59479547870e52908519ddb75db5ee3d971b..2cde0d2b81399fd7c71f509550f02065b3887569 100644 (file)
@@ -96,13 +96,15 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
  * Initializes the search structure.
  * 
  * If get_base_id != 0, the field bsi_base_id is filled 
- * with the entryID of bsi_base_dn; it must be freed
+ * with the entryID of bsi_base_ndn; it must be freed
  * by backsql_free_entryID() when no longer required.
+ *
+ * NOTE: base must be normalized
  */
 int
 backsql_init_search(
        backsql_srch_info       *bsi, 
-       struct berval           *base, 
+       struct berval           *nbase, 
        int                     scope, 
        int                     slimit,
        int                     tlimit,
@@ -117,8 +119,9 @@ backsql_init_search(
        AttributeName           *p;
        int                     rc = LDAP_SUCCESS;
 
-       bsi->bsi_base_dn = base;
+       bsi->bsi_base_ndn = nbase;
        BER_BVZERO( &bsi->bsi_base_id.eid_dn );
+       BER_BVZERO( &bsi->bsi_base_id.eid_ndn );
        bsi->bsi_scope = scope;
        bsi->bsi_slimit = slimit;
        bsi->bsi_tlimit = tlimit;
@@ -187,7 +190,7 @@ backsql_init_search(
                assert( op->o_bd->be_private );
 
                rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
-                               &bsi->bsi_base_id, dbh, base );
+                               &bsi->bsi_base_id, dbh, nbase );
        }
 
        return ( bsi->bsi_status = rc );
@@ -1109,6 +1112,9 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
                                        "ldap_entries.parent=?" );
                break;
 
+#ifdef LDAP_SCOPE_SUBORDINATE
+       case LDAP_SCOPE_SUBORDINATE:
+#endif /* LDAP_SCOPE_SUBORDINATE */
        case LDAP_SCOPE_SUBTREE:
                if ( BACKSQL_CANUPPERCASE( bi ) ) {
                        backsql_strfcat( &bsi->bsi_join_where, "bl",
@@ -1184,11 +1190,13 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
        int                     n_candidates = bsi->bsi_n_candidates;
 
        /* 
-        * + 1 because we need room for '%'; this makes a subtree
+        * + 1 because we need room for '%';
+        * + 1 because we need room for ',' for LDAP_SCOPE_SUBORDINATE;
+        * this makes a subtree
         * search for a DN BACKSQL_MAX_DN_LEN long legal 
         * if it returns that DN only
         */
-       char                    temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 + 1 ];
+       char                    tmp_base_ndn[ BACKSQL_MAX_DN_LEN + 1 + 1 ];
 
        bsi->bsi_status = LDAP_SUCCESS;
  
@@ -1271,28 +1279,28 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                 * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
                 * however this should be handled earlier
                 */
-               if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) {
+               if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
                        bsi->bsi_status = LDAP_OTHER;
                        return BACKSQL_AVL_CONTINUE;
                }
 
-               AC_MEMCPY( temp_base_dn, bsi->bsi_base_dn->bv_val,
-                               bsi->bsi_base_dn->bv_len + 1 );
+               AC_MEMCPY( tmp_base_ndn, bsi->bsi_base_ndn->bv_val,
+                               bsi->bsi_base_ndn->bv_len + 1 );
 
                /* uppercase DN only if the stored DN can be uppercased
                 * for comparison */
                if ( BACKSQL_CANUPPERCASE( bi ) ) {
-                       ldap_pvt_str2upper( temp_base_dn );
+                       ldap_pvt_str2upper( tmp_base_ndn );
                }
 
                Debug( LDAP_DEBUG_TRACE, "(base)dn: \"%s\"\n",
-                               temp_base_dn, 0, 0 );
+                               tmp_base_ndn, 0, 0 );
 
                rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,
-                               temp_base_dn, BACKSQL_MAX_DN_LEN );
+                               tmp_base_ndn, BACKSQL_MAX_DN_LEN );
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
-                               "error binding base_dn parameter\n", 0, 0, 0 );
+                               "error binding base_ndn parameter\n", 0, 0, 0 );
                        backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, 
                                        sth, rc );
                        bsi->bsi_status = LDAP_OTHER;
@@ -1300,12 +1308,16 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                }
                break;
 
-       case LDAP_SCOPE_SUBTREE: {
+#ifdef LDAP_SCOPE_SUBORDINATE
+       case LDAP_SCOPE_SUBORDINATE:
+#endif /* LDAP_SCOPE_SUBORDINATE */
+       case LDAP_SCOPE_SUBTREE:
+       {
                /*
                 * We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
                 * however this should be handled earlier
                 */
-               if ( bsi->bsi_base_dn->bv_len > BACKSQL_MAX_DN_LEN ) {
+               if ( bsi->bsi_base_ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
                        bsi->bsi_status = LDAP_OTHER;
                        return BACKSQL_AVL_CONTINUE;
                }
@@ -1324,34 +1336,59 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                 * If "dn_ru" is being used, do a prefix search.
                 */
                if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
-                       temp_base_dn[ 0 ] = '\0';
-                       for ( i = 0, j = bsi->bsi_base_dn->bv_len - 1;
+                       tmp_base_ndn[ 0 ] = '\0';
+
+                       for ( i = 0, j = bsi->bsi_base_ndn->bv_len - 1;
                                        j >= 0; i++, j--) {
-                               temp_base_dn[ i ] = bsi->bsi_base_dn->bv_val[ j ];
+                               tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ];
                        }
-                       temp_base_dn[ i ] = '%';
-                       temp_base_dn[ i + 1 ] = '\0';
+
+#ifdef LDAP_SCOPE_SUBORDINATE
+                       if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
+                               tmp_base_ndn[ i++ ] = ',';
+                       }
+#endif /* LDAP_SCOPE_SUBORDINATE */
+
+                       tmp_base_ndn[ i ] = '%';
+                       tmp_base_ndn[ i + 1 ] = '\0';
 
                } else {
-                       temp_base_dn[ 0 ] = '%';
-                       AC_MEMCPY( &temp_base_dn[ 1 ], bsi->bsi_base_dn->bv_val,
-                               bsi->bsi_base_dn->bv_len + 1 );
+                       i = 0;
+
+                       tmp_base_ndn[ i++ ] = '%';
+
+#ifdef LDAP_SCOPE_SUBORDINATE
+                       if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
+                               tmp_base_ndn[ i++ ] = ',';
+                       }
+#endif /* LDAP_SCOPE_SUBORDINATE */
+
+                       AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val,
+                               bsi->bsi_base_ndn->bv_len + 1 );
                }
 
                /* uppercase DN only if the stored DN can be uppercased
                 * for comparison */
                if ( BACKSQL_CANUPPERCASE( bi ) ) {
-                       ldap_pvt_str2upper( temp_base_dn );
+                       ldap_pvt_str2upper( tmp_base_ndn );
                }
 
-               Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n", temp_base_dn,
-                               0, 0 );
+#ifdef LDAP_SCOPE_SUBORDINATE
+               if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
+                       Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n",
+                               tmp_base_ndn, 0, 0 );
+               } else 
+#endif /* LDAP_SCOPE_SUBORDINATE */
+               {
+                       Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n",
+                               tmp_base_ndn, 0, 0 );
+               }
 
                rc = backsql_BindParamStr( sth, 2, SQL_PARAM_INPUT,
-                               temp_base_dn, BACKSQL_MAX_DN_LEN );
+                               tmp_base_ndn, BACKSQL_MAX_DN_LEN );
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
-                               "error binding base_dn parameter (2)\n",
+                               "error binding base_ndn parameter (2)\n",
                                0, 0, 0 );
                        backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, 
                                        sth, rc );
@@ -1362,7 +1399,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
        }
 
        case LDAP_SCOPE_ONELEVEL:
-               assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_dn ) );
+               assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_ndn ) );
 
 #ifdef BACKSQL_ARBITRARY_KEY
                Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",
@@ -1395,7 +1432,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
        backsql_BindRowAsStrings( sth, &row );
        rc = SQLFetch( sth );
        for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
-               struct berval           dn, ndn;
+               struct berval           dn, pdn, ndn;
                backsql_entryID         *c_id = NULL;
                int                     ret;
 
@@ -1405,7 +1442,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                        continue;
                }
 
-               ret = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
+               ret = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
                if ( dn.bv_val != row.cols[ 3 ] ) {
                        free( dn.bv_val );
                }
@@ -1414,7 +1451,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
                        continue;
                }
 
-               if ( bi->sql_baseObject && bvmatch( &ndn, &bi->sql_baseObject->e_nname ) ) {
+               if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {
+                       free( pdn.bv_val );
                        free( ndn.bv_val );
                        continue;
                }
@@ -1430,11 +1468,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 #endif /* ! BACKSQL_ARBITRARY_KEY */
                c_id->eid_oc_id = bsi->bsi_oc->bom_id;
 
-               if ( ndn.bv_val == row.cols[ 3 ] ) {
-                       ber_dupbv( &c_id->eid_dn, &ndn );
-               } else {
-                       c_id->eid_dn = ndn;
-               }
+               c_id->eid_dn = pdn;
+               c_id->eid_ndn = ndn;
 
                /* append at end of list ... */
                c_id->eid_next = NULL;
@@ -1478,7 +1513,7 @@ backsql_search( Operation *op, SlapReply *rs )
        time_t                  stoptime = 0;
        backsql_srch_info       bsi;
        backsql_entryID         *eid = NULL;
-       struct berval           base;
+       struct berval           nbase = BER_BVNULL;
 
        manageDSAit = get_manageDSAit( op );
 
@@ -1521,19 +1556,19 @@ backsql_search( Operation *op, SlapReply *rs )
        /* compute it anyway; root does not use it */
        stoptime = op->o_time + op->ors_tlimit;
 
-       base = op->o_req_ndn;
-       if ( backsql_api_dn2odbc( op, rs, &base ) ) {
+       nbase = op->o_req_ndn;
+       if ( backsql_api_dn2odbc( op, rs, &nbase ) ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
                        "backsql_api_dn2odbc failed\n", 
                        0, 0, 0 );
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "SQL-backend error";
                send_ldap_result( op, rs );
-               return 1;
+               goto done;
        }
 
        /* init search */
-       rs->sr_err = backsql_init_search( &bsi, &base,
+       rs->sr_err = backsql_init_search( &bsi, &nbase,
                        op->ors_scope,
                        op->ors_slimit, op->ors_tlimit,
                        stoptime, op->ors_filter,
@@ -1654,7 +1689,7 @@ backsql_search( Operation *op, SlapReply *rs )
                switch ( op->ors_scope ) {
                case LDAP_SCOPE_BASE:
                case BACKSQL_SCOPE_BASE_LIKE:
-                       if ( !bvmatch( &e->e_nname, &op->o_req_ndn ) ) {
+                       if ( !dn_match( &e->e_nname, &op->o_req_ndn ) ) {
                                goto next_entry;
                        }
                        break;
@@ -1662,6 +1697,7 @@ backsql_search( Operation *op, SlapReply *rs )
                case LDAP_SCOPE_ONE:
                {
                        struct berval   rdn = user_entry.e_nname;
+
                        rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
                        if ( !dnIsOneLevelRDN( &rdn ) ) {
                                goto next_entry;
@@ -1669,7 +1705,17 @@ backsql_search( Operation *op, SlapReply *rs )
                        /* fall thru */
                }
 
+#ifdef LDAP_SCOPE_SUBORDINATE
+               case LDAP_SCOPE_SUBORDINATE:
+                       /* discard the baseObject entry */
+                       if ( dn_match( &e->e_nname, &op->o_req_ndn ) ) {
+                               goto next_entry;
+                       }
+               /* FALLTHRU */
+#endif /* LDAP_SCOPE_SUBORDINATE */
+
                case LDAP_SCOPE_SUBTREE:
+                       /* FIXME: this should never fail... */
                        if ( !dnIsSuffix( &e->e_nname, &op->o_req_ndn ) ) {
                                goto next_entry;
                        }
@@ -1829,7 +1875,7 @@ end_of_search:;
        }
 
 done:;
-       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
                (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
        }
 
@@ -1837,8 +1883,16 @@ done:;
                ch_free( bsi.bsi_attrs );
        }
 
-       if ( base.bv_val != op->o_req_ndn.bv_val ) {
-               ch_free( base.bv_val );
+       if ( !BER_BVISNULL( &nbase )
+                       && nbase.bv_val != op->o_req_ndn.bv_val )
+       {
+               ch_free( nbase.bv_val );
+       }
+
+       /* restore scope ... FIXME: this should be done before ANY
+        * frontend call that uses op */
+       if ( op->ors_scope == BACKSQL_SCOPE_BASE_LIKE ) {
+               op->ors_scope = LDAP_SCOPE_BASE;
        }
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );
index 41f099ce18988ca75edda0b7872552c6925e5c53..f198ebedfeeee132ae0b396eac0515ff06aa779d 100644 (file)
@@ -56,7 +56,7 @@ char backsql_def_delreferrals_query[] = "DELETE FROM ldap_referrals "
        "WHERE entry_id=?";
 char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
 char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";
-char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
+char backsql_id_query[] = "SELECT id,keyval,oc_map_id,dn FROM ldap_entries WHERE ";
 /* better ?||? or cast(?||? as varchar) */ 
 char backsql_def_concat_func[] = "CONCAT(?,?)";