]> git.sur5r.net Git - openldap/commitdiff
fix, rework and optimize search base; allow orphaned entries addition
authorPierangelo Masarati <ando@openldap.org>
Tue, 28 Sep 2004 23:27:39 +0000 (23:27 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 28 Sep 2004 23:27:39 +0000 (23:27 +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/config.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/search.c

index bf733ff08d666eee3685cd775fe970cab5f954fb..4074f37bd9f6aa9989ffba4bb6d15a092c1283af 100644 (file)
@@ -1016,7 +1016,8 @@ backsql_add( Operation *op, SlapReply *rs )
                 *  if not attempting to add entry at suffix or with parent ""
                 */
                if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) )
-                       || !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e ) )
+                       || !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e )
+                       && !BACKSQL_ALLOW_ORPHANS( bi ) )
                {
                        Debug( LDAP_DEBUG_TRACE, "   backsql_add: %s denied\n",
                                BER_BVISEMPTY( &pdn ) ? "suffix" : "entry at root",
@@ -1391,7 +1392,7 @@ done:;
                ch_free( realpdn.bv_val );
        }
        if ( !BER_BVISNULL( &parent_id.eid_dn ) ) {
-               backsql_free_entryID( &parent_id, 0 );
+               (void)backsql_free_entryID( &parent_id, 0 );
        }
 
        Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",
index 08370e7abeda60f5b35a98cc9f5a57b82ac2d7d7..db901cbbb523408c8a7e9e773d6121a45219bd5b 100644 (file)
@@ -92,6 +92,7 @@
  * define to enable very extensive trace logging (debug only)
  */
 #undef BACKSQL_TRACE
+#define BACKSQL_TRACE
 
 /*
  * define to enable varchars as unique keys in user tables
@@ -254,6 +255,7 @@ typedef struct backsql_srch_info {
 #define BSQL_SF_FILTER_HASSUBORDINATE  0x0002
 
        struct berval           *bsi_base_dn;
+       backsql_entryID         bsi_base_id;
        int                     bsi_scope;
 #define BACKSQL_SCOPE_BASE_LIKE                ( LDAP_SCOPE_BASE | 0x1000 )
        Filter                  *bsi_filter;
@@ -320,6 +322,7 @@ typedef struct {
 #define BSQLF_HAS_LDAPINFO_DN_RU       0x0010
 #define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020
 #define BSQLF_USE_REVERSE_DN           0x0040
+#define BSQLF_ALLOW_ORPHANS            0x0080
 
 #define        BACKSQL_SCHEMA_LOADED(si) \
        ((si)->bsql_flags & BSQLF_SCHEMA_LOADED)
@@ -337,6 +340,8 @@ typedef struct {
        ((si)->bsql_flags & BSQLF_USE_REVERSE_DN)
 #define BACKSQL_CANUPPERCASE(si) \
        ((si)->upper_func.bv_val)
+#define BACKSQL_ALLOW_ORPHANS(si) \
+       ((si)->bsql_flags & BSQLF_ALLOW_ORPHANS)
        
        struct berval   strcast_func;
        Avlnode         *db_conns;
index 2f8d31c2c06c00e6d7c037a63c7b55a604dcce7c..461ef8d18c1da0661faf89eb07a0f00c43c4b1a2 100644 (file)
@@ -31,8 +31,6 @@
 int 
 backsql_bind( Operation *op, SlapReply *rs )
 {
-       backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
-       backsql_entryID         user_id = BACKSQL_ENTRYID_INIT;
        SQLHDBC                 dbh;
        AttributeDescription    *password = slap_schema.si_ad_userPassword;
        Entry                   *e, user_entry;
@@ -85,7 +83,12 @@ backsql_bind( Operation *op, SlapReply *rs )
                goto error_return;
        }
 
-       rc = backsql_dn2id( bi, &user_id, dbh, &dn );
+       anlist[0].an_name = password->ad_cname;
+       anlist[0].an_desc = password;
+       anlist[1].an_name.bv_val = NULL;
+
+       rc = backsql_init_search( &bsi, &dn, 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", 
@@ -95,14 +98,8 @@ backsql_bind( Operation *op, SlapReply *rs )
                return 1;
        }
 
-       anlist[0].an_name = password->ad_cname;
-       anlist[0].an_desc = password;
-       anlist[1].an_name.bv_val = NULL;
-
-       backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, 
-                       -1, -1, -1, NULL, dbh, op, rs, anlist );
        bsi.bsi_e = &user_entry;
-       rc = backsql_id2entry( &bsi, &user_id );
+       rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
        if ( rc != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
                        "error %d in backsql_id2entry() "
@@ -137,6 +134,10 @@ backsql_bind( Operation *op, SlapReply *rs )
        }
 
 error_return:;
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+       }
+
        if ( rs->sr_err ) {
                send_ldap_result( op, rs );
                return 1;
index 9dd4ea76206939756be82a43bda9ae3d312434f0..5296f46beda05d2f3188963752ab488445ddf31b 100644 (file)
@@ -31,8 +31,6 @@
 int
 backsql_compare( Operation *op, SlapReply *rs )
 {
-       backsql_info            *bi = (backsql_info*)op->o_bd->be_private;
-       backsql_entryID         user_id = BACKSQL_ENTRYID_INIT;
        SQLHDBC                 dbh;
        Entry                   *e = NULL, user_entry;
        Attribute               *a = NULL;
@@ -70,15 +68,6 @@ backsql_compare( Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-       rc = backsql_dn2id( bi, &user_id, dbh, &dn );
-       if ( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
-                       "could not retrieve compare dn id - no such entry\n", 
-                       0, 0, 0 );
-               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-               goto return_results;
-       }
-
        memset( &anlist[0], 0, 2 * sizeof( AttributeName ) );
        anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
        anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
@@ -106,10 +95,18 @@ backsql_compare( Operation *op, SlapReply *rs )
                user_entry.e_attrs = nrs.sr_operational_attrs;
 
        } else {
-               backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE, 
-                               -1, -1, -1, NULL, dbh, op, rs, anlist );
+               rc = backsql_init_search( &bsi, &dn, 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", 
+                               0, 0, 0 );
+                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                       goto return_results;
+               }
+
                bsi.bsi_e = &user_entry;
-               rc = backsql_id2entry( &bsi, &user_id );
+               rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
                if ( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
                                "error %d in backsql_id2entry() "
@@ -148,6 +145,10 @@ backsql_compare( Operation *op, SlapReply *rs )
 return_results:;
        send_ldap_result( op, rs );
 
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+       }
+
        if ( dn.bv_val != op->o_req_dn.bv_val ) {
                ch_free( dn.bv_val );
        }
index 02795c64ef7287c44610e9ba8170bb85e7ae90dc..fe62525cf6c7369abdad3a4e685f417d47f30538 100644 (file)
@@ -360,6 +360,35 @@ backsql_db_config(
                        "fail_if_no_mapping=%s\n", 
                        BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 );
 
+       } else if ( !strcasecmp( argv[ 0 ], "allow_orphans") ) {
+               if ( argc < 2 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "missing { yes | no }"
+                               "in \"allow_orphans\" directive\n",
+                               fname, lineno, 0 );
+                       return 1;
+               }
+
+               if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+                       si->bsql_flags |= BSQLF_ALLOW_ORPHANS;
+
+               } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+                       si->bsql_flags &= ~BSQLF_ALLOW_ORPHANS;
+
+               } else {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_db_config (%s line %d): "
+                               "\"allow_orphans\" directive arg "
+                               "must be \"yes\" or \"no\"\n",
+                               fname, lineno, 0 );
+                       return 1;
+
+               }
+               Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+                       "allow_orphans=%s\n", 
+                       BACKSQL_ALLOW_ORPHANS( si ) ? "yes" : "no", 0, 0 );
+
        } else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
                if ( backsql_api_config( si, argv[ 1 ] ) ) {
                        Debug( LDAP_DEBUG_TRACE,
index 698daed1c77923769ea6feecb09578587e2d7400..624ea7b9508bc9a92a9d909cca114234132529a6 100644 (file)
@@ -209,7 +209,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                "old parent entry id is %ld\n", pe_id.eid_id, 0, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
-       backsql_free_entryID( &pe_id, 0 );
+       (void)backsql_free_entryID( &pe_id, 0 );
 
        rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn );
        if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -451,7 +451,7 @@ modrdn_return:;
        }
 
        if ( new_pe_id.eid_dn.bv_val ) {
-               backsql_free_entryID( &new_pe_id, 0 );
+               (void)backsql_free_entryID( &new_pe_id, 0 );
        }
 
        send_ldap_result( op, rs );
index c24e206075e0b738528c1664185fff1e872cc20b..2f623900c4ba9ec2cd73d56cee28f562443d4650 100644 (file)
@@ -149,10 +149,11 @@ int backsql_destroy_schema_map( backsql_info *si );
  * search.c
  */
 
-void backsql_init_search( backsql_srch_info *bsi, 
+int backsql_init_search( backsql_srch_info *bsi, 
                struct berval *nbase, int scope, int slimit, int tlimit,
                time_t stoptime, Filter *filter, SQLHDBC dbh,
-               Operation *op, SlapReply *rs, AttributeName *attrs );
+               Operation *op, SlapReply *rs, AttributeName *attrs,
+               int get_base_id );
 
 /*
  * sql-wrap.h
index f3951734bb63f27ca359b8648c5b76c362a8be8b..c3c96746e0672684d8365878db289593c8189e5d 100644 (file)
@@ -92,7 +92,14 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
        return 1;
 }
 
-void
+/*
+ * 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
+ * by backsql_free_entryID() when no longer required.
+ */
+int
 backsql_init_search(
        backsql_srch_info       *bsi, 
        struct berval           *base, 
@@ -104,11 +111,14 @@ backsql_init_search(
        SQLHDBC                 dbh,
        Operation               *op,
        SlapReply               *rs,
-       AttributeName           *attrs )
+       AttributeName           *attrs,
+       int                     get_base_id )
 {
        AttributeName           *p;
+       int                     rc = LDAP_SUCCESS;
 
        bsi->bsi_base_dn = base;
+       BER_BVZERO( &bsi->bsi_base_id.eid_dn );
        bsi->bsi_scope = scope;
        bsi->bsi_slimit = slimit;
        bsi->bsi_tlimit = tlimit;
@@ -125,7 +135,7 @@ backsql_init_search(
                bsi->bsi_attrs = NULL;
 
        } else {
-               int     is_oc = 0;
+               int     got_oc = 0;
 
                bsi->bsi_attrs = (AttributeName *)ch_calloc( 1, 
                                sizeof( AttributeName ) );
@@ -143,13 +153,13 @@ backsql_init_search(
                                continue;
 
                        } else if ( p->an_desc == slap_schema.si_ad_objectClass ) {
-                               is_oc = 1;
+                               got_oc = 1;
                        }
 
                        backsql_attrlist_add( bsi, p->an_desc );
                }
 
-               if ( is_oc == 0 ) {
+               if ( got_oc == 0 ) {
                        /* add objectClass if not present,
                         * because it is required to understand
                         * if an entry is a referral, an alias 
@@ -173,7 +183,12 @@ backsql_init_search(
        bsi->bsi_flt_where.bb_len = 0;
        bsi->bsi_filter_oc = NULL;
 
-       bsi->bsi_status = LDAP_SUCCESS;
+       if ( get_base_id ) {
+               rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
+                               &bsi->bsi_base_id, dbh, base );
+       }
+
+       return ( bsi->bsi_status = rc );
 }
 
 static int
@@ -1160,7 +1175,6 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
        struct berval           query;
        SQLHSTMT                sth;
        RETCODE                 rc;
-       backsql_entryID         base_id = BACKSQL_ENTRYID_INIT;
        int                     res;
        BACKSQL_ROW_NTS         row;
        int                     i;
@@ -1346,27 +1360,17 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
        }
 
        case LDAP_SCOPE_ONELEVEL:
-               res = backsql_dn2id( bi, &base_id, 
-                               bsi->bsi_dbh, bsi->bsi_base_dn );
-               if ( res != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
-                               "could not retrieve base_dn id%s\n",
-                               res == LDAP_NO_SUCH_OBJECT ? ": no such entry"
-                               : "", 0, 0 );
-                       bsi->bsi_status = res;
-                       return BACKSQL_AVL_CONTINUE;
-               }
+               assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_dn ) );
 
 #ifdef BACKSQL_ARBITRARY_KEY
                Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",
-                               base_id.eid_id.bv_val, 0, 0 );
+                               bsi->bsi_base_id.eid_id.bv_val, 0, 0 );
 #else /* ! BACKSQL_ARBITRARY_KEY */
-               Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n", base_id.eid_id,
-                               0, 0 );
+               Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n",
+                               bsi->bsi_base_id.eid_id, 0, 0 );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
                rc = backsql_BindParamID( sth, 2, SQL_PARAM_INPUT,
-                               &base_id.eid_id );
-               backsql_free_entryID( &base_id, 0 );
+                               &bsi->bsi_base_id.eid_id );
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
                                "error binding base id parameter\n", 0, 0, 0 );
@@ -1511,11 +1515,16 @@ backsql_search( Operation *op, SlapReply *rs )
                return 1;
        }
 
-       backsql_init_search( &srch_info, &base,
+       /* init search */
+       rs->sr_err = backsql_init_search( &srch_info, &base,
                        op->ors_scope,
                        op->ors_slimit, op->ors_tlimit,
                        stoptime, op->ors_filter,
-                       dbh, op, rs, op->ors_attrs );
+                       dbh, op, rs, op->ors_attrs, 1 );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               goto done;
+       }
 
        /*
         * for each objectclass we try to construct query which gets IDs
@@ -1536,7 +1545,7 @@ backsql_search( Operation *op, SlapReply *rs )
                send_ldap_result( op, rs );
                goto done;
        }
-       
+
        /*
         * now we load candidate entries (only those attributes 
         * mentioned in attrs and filter), test it against full filter 
@@ -1620,20 +1629,18 @@ backsql_search( Operation *op, SlapReply *rs )
                                is_entry_referral( &user_entry ) )
                {
                        BerVarray refs;
-                       struct berval matched_dn;
 
-                       ber_dupbv( &matched_dn, &user_entry.e_name );
                        refs = get_entry_referrals( op, &user_entry );
                        if ( !refs ) {
                                backsql_srch_info       srch_info2 = { 0 };
                                Entry                   user_entry2 = { 0 };
 
                                /* retry with the full entry... */
-                               backsql_init_search( &srch_info2,
+                               (void)backsql_init_search( &srch_info2,
                                                &user_entry.e_name,
                                                LDAP_SCOPE_BASE, 
                                                -1, -1, -1, NULL,
-                                               dbh, op, rs, NULL );
+                                               dbh, op, rs, NULL, 0 );
                                srch_info2.bsi_e = &user_entry2;
                                rc = backsql_id2entry( &srch_info2, eid );
                                if ( rc == LDAP_SUCCESS ) {
@@ -1648,7 +1655,8 @@ backsql_search( Operation *op, SlapReply *rs )
 
                        if ( refs ) {
                                rs->sr_ref = referral_rewrite( refs,
-                                               &matched_dn, &op->o_req_dn,
+                                               &user_entry.e_name,
+                                               &op->o_req_dn,
                                                op->ors_scope );
                                ber_bvarray_free( refs );
                        }
@@ -1658,12 +1666,11 @@ backsql_search( Operation *op, SlapReply *rs )
                        }
 
                        rs->sr_err = LDAP_REFERRAL;
-                       rs->sr_matched = matched_dn.bv_val;
+                       rs->sr_matched = user_entry.e_name.bv_val;
                        send_search_reference( op, rs );
 
                        ber_bvarray_free( rs->sr_ref );
                        rs->sr_ref = NULL;
-                       ber_memfree( matched_dn.bv_val );
                        rs->sr_matched = NULL;
 
                        goto next_entry;
@@ -1767,7 +1774,14 @@ end_of_search:;
        }
 
 done:;
-       ch_free( srch_info.bsi_attrs );
+       if ( !BER_BVISNULL( &srch_info.bsi_base_id.eid_dn ) ) {
+               (void)backsql_free_entryID( &srch_info.bsi_base_id, 0 );
+       }
+
+       if ( srch_info.bsi_attrs ) {
+               ch_free( srch_info.bsi_attrs );
+       }
+
        if ( base.bv_val != op->o_req_ndn.bv_val ) {
                ch_free( base.bv_val );
        }