]> git.sur5r.net Git - openldap/commitdiff
first round at enabling back-sql as LDAPsync provider
authorPierangelo Masarati <ando@openldap.org>
Mon, 29 Nov 2004 00:50:55 +0000 (00:50 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 29 Nov 2004 00:50:55 +0000 (00:50 +0000)
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/init.c
servers/slapd/back-sql/operational.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/search.c

index 07a73e261589b0c1e0392b185638c0005a24dad6..af8be8ceba199a6aff07ad5c38f3d274c405512c 100644 (file)
@@ -261,10 +261,12 @@ typedef struct backsql_srch_info {
        Operation               *bsi_op;
        SlapReply               *bsi_rs;
 
-       int                     bsi_flags;
-#define        BSQL_SF_ALL_OPER                0x0001
-#define BSQL_SF_FILTER_HASSUBORDINATE  0x0002
-#define BSQL_SF_FILTER_ENTRYUUID       0x0004
+       unsigned                bsi_flags;
+#define        BSQL_SF_NONE                    0x0000U
+#define        BSQL_SF_ALL_OPER                0x0001U
+#define BSQL_SF_FILTER_HASSUBORDINATE  0x0002U
+#define BSQL_SF_FILTER_ENTRYUUID       0x0004U
+#define BSQL_SF_FILTER_ENTRYCSN                0x0008U
 
        struct berval           *bsi_base_ndn;
        backsql_entryID         bsi_base_id;
index 9d7c37830d03d69a85187c18cc6d0e5e10c793f6..501dedaee65c57cd2a52fce62f78552bf93c104c 100644 (file)
@@ -65,6 +65,7 @@ sql_back_initialize(
        
        bi->bi_chk_referrals = 0;
        bi->bi_operational = backsql_operational;
+       bi->bi_entry_get_rw = backsql_entry_get;
  
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = backsql_connection_destroy;
index 9df0eb0c86a86917ecbb3113cb9c7fcf33466e7d..9e301482e6affcc8a72af45f7e5c8d0c0f86ffbd 100644 (file)
@@ -80,7 +80,15 @@ backsql_operational_entryCSN( Operation *op )
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
        BER_BVZERO( &a->a_vals[ 1 ] );
 
-       slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+       if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) {
+               assert( op->o_private );
+
+               entryCSN = *((struct berval *)op->o_private);
+
+       } else {
+               slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+       }
+
        ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
 
        a->a_nvals = a->a_vals;
index 5f6dd8965ffbbcc89d215cb9714e4125624b5d0e..d438c7dda423fc8baf24b925ffa37ce35660a597 100644 (file)
@@ -279,6 +279,7 @@ extern BI_op_add            backsql_add;
 extern BI_op_delete            backsql_delete;
 
 extern BI_operational          backsql_operational;
+extern BI_entry_get_rw         backsql_entry_get;
 
 extern BI_connection_destroy   backsql_connection_destroy;
 
index fff39dc3c1e23db1cc733d7f66b59992191253a5..823fa6bc25fe93329f4873aec29779763c6e4698 100644 (file)
@@ -127,7 +127,7 @@ backsql_init_search(
        bsi->bsi_dbh = dbh;
        bsi->bsi_op = op;
        bsi->bsi_rs = rs;
-       bsi->bsi_flags = 0;
+       bsi->bsi_flags = BSQL_SF_NONE;
 
        /*
         * handle "*"
@@ -676,13 +676,25 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                 * TODO: introduce appropriate entryCSN filtering
                 * to support syncrepl as producer...
                 */
-               if ( bsi->bsi_op->o_sync ) {
+               if ( !bsi->bsi_op->o_sync ) {
                        /* unsupported at present... */
                        bsi->bsi_status = LDAP_OTHER;
                        rc = -1;
                        goto done;
                }
 
+               /* if doing a syncrepl, try to return as much as possible,
+                * and always match the filter */
+               backsql_strfcat( &bsi->bsi_flt_where, "l",
+                               (ber_len_t)STRLENOF( "1=1" ), "1=1" );
+
+               /* save for later use in operational attributes */
+               bsi->bsi_op->o_private = &f->f_av_value;
+
+               bsi->bsi_flags |= BSQL_SF_FILTER_ENTRYCSN;
+               bsi->bsi_status = LDAP_SUCCESS;
+               rc = 1;
+               goto done;
 
        } else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
                /*
@@ -1696,6 +1708,7 @@ backsql_search( Operation *op, SlapReply *rs )
                int             rc;
                Attribute       *a_hasSubordinate = NULL,
                                *a_entryUUID = NULL,
+                               *a_entryCSN = NULL,
                                *a = NULL;
                Entry           *e = NULL;
 
@@ -1878,26 +1891,19 @@ backsql_search( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
-               {
-#if 0
-                       if ( a_hasSubordinate && !( bsi.bsi_flags & BSQL_SF_ALL_OPER ) 
-                                       && !ad_inlist( slap_schema.si_ad_hasSubordinates, op->ors_attrs ) )
-                       {
-                               a->a_next = NULL;
-                               attr_free( a_hasSubordinate );
-                               a_hasSubordinate = NULL;
-                       }
+               if ( bsi.bsi_flags & BSQL_SF_FILTER_ENTRYCSN ) {
+                       a_entryCSN = backsql_operational_entryCSN( op );
+                       if ( a_entryUUID != NULL ) {
+                               for ( a = user_entry.e_attrs; 
+                                               a && a->a_next; 
+                                               a = a->a_next );
 
-                       if ( a_entryUUID && !( bsi.bsi_flags & BSQL_SF_ALL_OPER ) 
-                                       && !ad_inlist( slap_schema.si_ad_entryUUID, op->ors_attrs ) )
-                       {
-                               a->a_next = NULL;
-                               attr_free( a_hasSubordinate );
-                               a_hasSubordinate = NULL;
+                               a->a_next = a_entryCSN;
                        }
-#endif
+               }
 
+               if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
+               {
                        rs->sr_attrs = op->ors_attrs;
                        rs->sr_operational_attrs = NULL;
                        rs->sr_entry = e;
@@ -1981,3 +1987,90 @@ done:;
        return 0;
 }
 
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int
+backsql_entry_get(
+               Operation               *op,
+               struct berval           *ndn,
+               ObjectClass             *oc,
+               AttributeDescription    *at,
+               int                     rw,
+               Entry                   **ent )
+{
+       backsql_srch_info       bsi;
+       SQLHDBC                 dbh;
+       int                     rc;
+       SlapReply               rs = { 0 };
+       AttributeName           anlist[ 2 ];
+
+       rc = backsql_get_db_conn( op, &dbh );
+       if ( !dbh ) {
+               return LDAP_OTHER;
+       }
+
+       if ( at ) {
+               anlist[ 0 ].an_name = at->ad_cname;
+               anlist[ 0 ].an_desc = at;
+               BER_BVZERO( &anlist[ 1 ].an_name );
+       }
+
+       rc = backsql_init_search( &bsi,
+                       ndn,
+                       LDAP_SCOPE_BASE, 
+                       SLAP_NO_LIMIT, SLAP_NO_LIMIT, -1, NULL,
+                       dbh, op, &rs, at ? anlist : NULL, 1 );
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       bsi.bsi_e = ch_malloc( sizeof( Entry ) );
+       rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
+
+       if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
+               (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+
+#if 0 /* not supported at present */
+               /* find attribute values */
+               if ( is_entry_alias( bsi.bsi_e ) ) {
+                       Debug( LDAP_DEBUG_ACL,
+                               "<= backsql_entry_get: entry is an alias\n",
+                               0, 0, 0 );
+                       rc = LDAP_ALIAS_PROBLEM;
+                       goto return_results;
+               }
+#endif
+
+               if ( is_entry_referral( bsi.bsi_e ) ) {
+                       Debug( LDAP_DEBUG_ACL,
+                               "<= backsql_entry_get: entry is a referral\n",
+                               0, 0, 0 );
+                       rc = LDAP_REFERRAL;
+                       goto return_results;
+               }
+
+               if ( oc && !is_entry_objectclass( bsi.bsi_e, oc, 0 ) ) {
+                       Debug( LDAP_DEBUG_ACL,
+                                       "<= backsql_entry_get: "
+                                       "failed to find objectClass\n",
+                                       0, 0, 0 ); 
+                       rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       goto return_results;
+               }
+
+               *ent = bsi.bsi_e;
+       }
+
+return_results:;
+       if ( rc != LDAP_SUCCESS ) {
+               if ( bsi.bsi_e ) {
+                       entry_free( bsi.bsi_e );
+               }
+       }
+
+       return rc;
+}
+