]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/dds.c
ITS#5705
[openldap] / servers / slapd / overlays / dds.c
index b701e9e61124fc1eb98ac8f9bf0f55b8faef85f1..8230c1bbe5ec65ea7d48b655d95db6e7c9db6512 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2005-2006 The OpenLDAP Foundation.
+ * Copyright 2005-2008 The OpenLDAP Foundation.
  * Portions Copyright 2005-2006 SysNet s.n.c.
  * All rights reserved.
  *
@@ -123,7 +123,7 @@ dds_expire( void *ctx, dds_info_t *di )
        Connection      conn = { 0 };
        OperationBuffer opbuf;
        Operation       *op;
-       slap_callback   sc = { 0 }, sc2 = { 0 };
+       slap_callback   sc = { 0 };
        dds_cb_t        dc = { 0 };
        dds_expire_t    *de = NULL, **dep;
        SlapReply       rs = { REP_RESULT };
@@ -134,13 +134,16 @@ dds_expire( void *ctx, dds_info_t *di )
 
        int             ndeletes, ntotdeletes;
 
-       op = (Operation *)&opbuf;
-       connection_fake_init( &conn, op, ctx );
+       int             rc;
+       char            *extra = "";
+
+       connection_fake_init( &conn, &opbuf, ctx );
+       op = &opbuf.ob_op;
 
        op->o_tag = LDAP_REQ_SEARCH;
        memset( &op->oq_search, 0, sizeof( op->oq_search ) );
 
-       op->o_bd = select_backend( &di->di_nsuffix[ 0 ], 0, 0 );
+       op->o_bd = select_backend( &di->di_nsuffix[ 0 ], 0 );
 
        op->o_req_dn = op->o_bd->be_suffix[ 0 ];
        op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];
@@ -182,21 +185,30 @@ dds_expire( void *ctx, dds_info_t *di )
 
 done_search:;
        op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-       filter_free_x( op, op->ors_filter );
+       filter_free_x( op, op->ors_filter, 1 );
 
-       if ( rs.sr_err != LDAP_SUCCESS ) {
-               Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                       "DDS expired objects lookup failed err=%d\n",
-                       rs.sr_err );
+       rc = rs.sr_err;
+       switch ( rs.sr_err ) {
+       case LDAP_SUCCESS:
+               break;
+
+       case LDAP_NO_SUCH_OBJECT:
+               /* (ITS#5267) database not created yet? */
+               rs.sr_err = LDAP_SUCCESS;
+               extra = " (ignored)";
+               /* fallthru */
+
+       default:
+               Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+                       "DDS expired objects lookup failed err=%d%s\n",
+                       rc, extra );
                goto done;
        }
 
        op->o_tag = LDAP_REQ_DELETE;
        op->o_callback = &sc;
-       sc.sc_response = slap_replog_cb;
+       sc.sc_response = slap_null_cb;
        sc.sc_private = NULL;
-       sc.sc_next = &sc2;
-       sc2.sc_response = slap_null_cb;
 
        for ( ntotdeletes = 0, ndeletes = 1; dc.dc_ndnlist != NULL  && ndeletes > 0; ) {
                ndeletes = 0;
@@ -357,7 +369,6 @@ dds_op_add( Operation *op, SlapReply *rs )
                        slap_schema.si_oc_dynamicObject, NULL, 0, &e );
                if ( rc == LDAP_SUCCESS && e != NULL ) {
                        if ( !is_dynamicObject ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                /* return referral only if "disclose"
                                 * is granted on the object */
                                if ( ! access_allowed( op, e,
@@ -367,9 +378,7 @@ dds_op_add( Operation *op, SlapReply *rs )
                                        rc = rs->sr_err = LDAP_NO_SUCH_OBJECT;
                                        send_ldap_result( op, rs );
 
-                               } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                               {
+                               } else {
                                        rc = rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
                                        send_ldap_error( op, rs, rc, "no static subordinate entries allowed for dynamicObject" );
                                }
@@ -386,7 +395,7 @@ dds_op_add( Operation *op, SlapReply *rs )
        /* handle dynamic object operational attr(s) */
        if ( is_dynamicObject ) {
                time_t          ttl, expire;
-               char            ttlbuf[] = "31557600";
+               char            ttlbuf[STRLENOF("31557600") + 1];
                char            tsbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
                struct berval   bv;
 
@@ -405,10 +414,12 @@ dds_op_add( Operation *op, SlapReply *rs )
 
                ttl = DDS_DEFAULT_TTL( di );
 
+               /* assert because should be checked at configure */
                assert( ttl <= DDS_RF2589_MAX_TTL );
 
                bv.bv_val = ttlbuf;
                bv.bv_len = snprintf( ttlbuf, sizeof( ttlbuf ), "%ld", ttl );
+               assert( bv.bv_len < sizeof( ttlbuf ) );
 
                /* FIXME: apparently, values in op->ora_e are malloc'ed
                 * on the thread's slab; works fine by chance,
@@ -580,15 +591,12 @@ dds_op_modify( Operation *op, SlapReply *rs )
                                        if ( BER_BVISEMPTY( &bv_entryTtl ) 
                                                || !bvmatch( &bv_entryTtl, &mod->sml_values[ 0 ] ) )
                                        {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                                rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, 
                                                        slap_schema.si_ad_entry, NULL, ACL_DISCLOSE );
                                                if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) {
                                                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-                                               } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                                               {
+                                               } else {
                                                        rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
                                                }
                                                goto done;
@@ -609,15 +617,12 @@ dds_op_modify( Operation *op, SlapReply *rs )
                                assert( BER_BVISNULL( &mod->sml_values[ 1 ] ) );
 
                                if ( !BER_BVISEMPTY( &bv_entryTtl ) ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                        rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, 
                                                slap_schema.si_ad_entry, NULL, ACL_DISCLOSE );
                                        if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) {
                                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-                                       } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                                       {
+                                       } else {
                                                rs->sr_text = "attribute 'entryTtl' cannot have multiple values";
                                                rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
                                        }
@@ -649,15 +654,12 @@ dds_op_modify( Operation *op, SlapReply *rs )
 
                        case LDAP_MOD_INCREMENT:
                                if ( BER_BVISEMPTY( &bv_entryTtl ) ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                        rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn, 
                                                slap_schema.si_ad_entry, NULL, ACL_DISCLOSE );
                                        if ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) {
                                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-                                       } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                                       {
+                                       } else {
                                                rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
                                                rs->sr_text = "modify/increment: entryTtl: no such attribute";
                                        }
@@ -678,7 +680,6 @@ dds_op_modify( Operation *op, SlapReply *rs )
                                }
 
                                if ( rs->sr_err != LDAP_SUCCESS ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                        rc = backend_attribute( op, NULL, &op->o_req_ndn, 
                                                slap_schema.si_ad_entry, NULL, ACL_DISCLOSE );
                                        if ( rc == LDAP_INSUFFICIENT_ACCESS ) {
@@ -686,7 +687,6 @@ dds_op_modify( Operation *op, SlapReply *rs )
                                                rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
                                        }
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
                                        goto done;
                                }
 
@@ -708,7 +708,7 @@ done:;
        if ( rs->sr_err == LDAP_SUCCESS ) {
                int     rc;
 
-               /* FIXME: this could be allowed when manageDIT is used...
+               /* FIXME: this could be allowed when the Relax control is used...
                 * in that case:
                 *
                 * TODO
@@ -727,7 +727,7 @@ done:;
                rc = is_dynamicObject - was_dynamicObject;
                if ( rc ) {
 #if 0 /* fix subordinate issues first */
-                       if ( get_manageDIT( op ) ) {
+                       if ( get_relax( op ) ) {
                                switch ( rc ) {
                                case -1:
                                        /* need to delete entryTtl to have a consistent entry */
@@ -761,7 +761,6 @@ done:;
                                rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
                        }
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                        if ( rc != LDAP_SUCCESS ) {
                                rc = backend_attribute( op, NULL, &op->o_req_ndn, 
                                        slap_schema.si_ad_entry, NULL, ACL_DISCLOSE );
@@ -770,7 +769,6 @@ done:;
                                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
                                }
                        }
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
                }
        }
 
@@ -806,6 +804,7 @@ done:;
                        tmpmod->sml_op = LDAP_MOD_REPLACE;
                        value_add_one( &tmpmod->sml_values, &bv );
                        value_add_one( &tmpmod->sml_nvalues, &bv );
+                       tmpmod->sml_numvals = 1;
                }
        }
 
@@ -850,7 +849,6 @@ dds_op_rename( Operation *op, SlapReply *rs )
                        slap_schema.si_oc_dynamicObject, NULL, 0, &e );
                if ( rc == LDAP_SUCCESS && e != NULL ) {
                        if ( !is_dynamicObject ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                /* return referral only if "disclose"
                                 * is granted on the object */
                                if ( ! access_allowed( op, e,
@@ -860,9 +858,7 @@ dds_op_rename( Operation *op, SlapReply *rs )
                                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
                                        send_ldap_result( op, rs );
 
-                               } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                               {
+                               } else {
                                        send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION,
                                                "static entry cannot have dynamicObject as newSuperior" );
                                }
@@ -969,7 +965,7 @@ slap_parse_refresh(
 
        tag = ber_peek_tag( ber, &len );
 
-       if ( len != 0 ) {
+       if ( tag != LBER_DEFAULT || len != 0 ) {
 decoding_error:;
                Log1( LDAP_DEBUG_TRACE, LDAP_LEVEL_ERR,
                        "slap_parse_refresh: decoding error, len=%ld\n",
@@ -1008,10 +1004,9 @@ dds_op_extended( Operation *op, SlapReply *rs )
                SlapReply       rs2 = { REP_RESULT };
                Operation       op2 = *op;
                slap_callback   sc = { 0 };
-               slap_callback   sc2 = { 0 };
                Modifications   ttlmod = { { 0 } };
                struct berval   ttlvalues[ 2 ];
-               char            ttlbuf[] = "31557600";
+               char            ttlbuf[STRLENOF("31557600") + 1];
 
                rs->sr_err = slap_parse_refresh( op->ore_reqdata, NULL, &ttl,
                        &rs->sr_text, NULL );
@@ -1072,7 +1067,6 @@ dds_op_extended( Operation *op, SlapReply *rs )
                        rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn,
                                NULL, NULL, 0, &e );
                        if ( rs->sr_err == LDAP_SUCCESS && e != NULL ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
                                /* return referral only if "disclose"
                                 * is granted on the object */
                                if ( ! access_allowed( op, e,
@@ -1081,9 +1075,7 @@ dds_op_extended( Operation *op, SlapReply *rs )
                                {
                                        rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-                               } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-                               {
+                               } else {
                                        rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
                                        rs->sr_text = "refresh operation only applies to dynamic objects";
                                }
@@ -1099,21 +1091,20 @@ dds_op_extended( Operation *op, SlapReply *rs )
                }
 
                /* we require manage privileges on the entryTtl,
-                * and fake a manageDIT control */
+                * and fake a Relax control */
                op2.o_tag = LDAP_REQ_MODIFY;
                op2.o_bd = &db;
                db.bd_info = (BackendInfo *)on->on_info;
                op2.o_callback = &sc;
-               sc.sc_response = slap_replog_cb;
-               sc.sc_next = &sc2;
-               sc2.sc_response = slap_null_cb;
-               op2.o_managedit = SLAP_CONTROL_CRITICAL;
+               sc.sc_response = slap_null_cb;
+               op2.o_relax = SLAP_CONTROL_CRITICAL;
                op2.orm_modlist = &ttlmod;
 
                ttlmod.sml_op = LDAP_MOD_REPLACE;
                ttlmod.sml_flags = SLAP_MOD_MANAGING;
                ttlmod.sml_desc = slap_schema.si_ad_entryTtl;
                ttlmod.sml_values = ttlvalues;
+               ttlmod.sml_numvals = 1;
                ttlvalues[ 0 ].bv_val = ttlbuf;
                ttlvalues[ 0 ].bv_len = snprintf( ttlbuf, sizeof( ttlbuf ), "%ld", ttl );
                BER_BVZERO( &ttlvalues[ 1 ] );
@@ -1390,20 +1381,20 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_MAXTTL:
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg),
                                "DDS unable to parse dds-max-ttl \"%s\"",
                                c->argv[ 1 ] );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
                if ( t < DDS_RF2589_DEFAULT_TTL || t > DDS_RF2589_MAX_TTL ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-max-ttl=%ld; must be between %d and %d",
                                t, DDS_RF2589_DEFAULT_TTL, DDS_RF2589_MAX_TTL );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
@@ -1412,20 +1403,20 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_MINTTL:
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg),
                                "DDS unable to parse dds-min-ttl \"%s\"",
                                c->argv[ 1 ] );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
                if ( t < 0 || t > DDS_RF2589_MAX_TTL ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-min-ttl=%ld",
                                t );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
@@ -1439,20 +1430,20 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_DEFAULTTTL:
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg),
                                "DDS unable to parse dds-default-ttl \"%s\"",
                                c->argv[ 1 ] );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
                if ( t < 0 || t > DDS_RF2589_MAX_TTL ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-default-ttl=%ld",
                                t );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
@@ -1466,20 +1457,20 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_INTERVAL:
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg),
                                "DDS unable to parse dds-interval \"%s\"",
                                c->argv[ 1 ] );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
                if ( t <= 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-interval=%ld",
                                t );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
@@ -1503,20 +1494,20 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_TOLERANCE:
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg),
                                "DDS unable to parse dds-tolerance \"%s\"",
                                c->argv[ 1 ] );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
                if ( t < 0 || t > DDS_RF2589_MAX_TTL ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-tolerance=%ld",
                                t );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
 
@@ -1525,10 +1516,10 @@ dds_cfgen( ConfigArgs *c )
 
        case DDS_MAXDYNAMICOBJS:
                if ( c->value_int < 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ),
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "DDS invalid dds-max-dynamicObjects=%d", c->value_int );
                        Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                               "%s: %s.\n", c->log, c->msg );
+                               "%s: %s.\n", c->log, c->cr_msg );
                        return 1;
                }
                di->di_max_dynamicObjects = c->value_int;
@@ -1544,7 +1535,8 @@ dds_cfgen( ConfigArgs *c )
 
 static int
 dds_db_init(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr)
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        dds_info_t      *di;
@@ -1633,8 +1625,11 @@ dds_count( void *ctx, BackendDB *be )
        slap_callback   sc = { 0 };
        SlapReply       rs = { REP_RESULT };
 
-       op = (Operation *)&opbuf;
-       connection_fake_init( &conn, op, ctx );
+       int             rc;
+       char            *extra = "";
+
+       connection_fake_init( &conn, &opbuf, ctx );
+       op = &opbuf.ob_op;
 
        op->o_tag = LDAP_REQ_SEARCH;
        memset( &op->oq_search, 0, sizeof( op->oq_search ) );
@@ -1668,6 +1663,7 @@ dds_count( void *ctx, BackendDB *be )
        op->o_callback = &sc;
        sc.sc_response = dds_count_cb;
        sc.sc_private = &di->di_num_dynamicObjects;
+       di->di_num_dynamicObjects = 0;
 
        op->o_bd->bd_info = (BackendInfo *)on->on_info;
        (void)op->o_bd->bd_info->bi_op_search( op, &rs );
@@ -1675,17 +1671,27 @@ dds_count( void *ctx, BackendDB *be )
 
 done_search:;
        op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-       filter_free_x( op, op->ors_filter );
+       filter_free_x( op, op->ors_filter, 1 );
 
-       if ( rs.sr_err == LDAP_SUCCESS ) {
+       rc = rs.sr_err;
+       switch ( rs.sr_err ) {
+       case LDAP_SUCCESS:
                Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
                        "DDS non-expired=%d\n",
                        di->di_num_dynamicObjects );
+               break;
 
-       } else {
-               Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
-                       "DDS non-expired objects lookup failed err=%d\n",
-                       rs.sr_err );
+       case LDAP_NO_SUCH_OBJECT:
+               /* (ITS#5267) database not created yet? */
+               rs.sr_err = LDAP_SUCCESS;
+               extra = " (ignored)";
+               /* fallthru */
+
+       default:
+               Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+                       "DDS non-expired objects lookup failed err=%d%s\n",
+                       rc, extra );
+               break;
        }
 
        return rs.sr_err;
@@ -1693,7 +1699,8 @@ done_search:;
 
 static int
 dds_db_open(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        dds_info_t      *di = on->on_bi.bi_private;
@@ -1752,14 +1759,14 @@ dds_db_open(
        rc = entry_info_register( dds_entry_info, (void *)di );
 
 done:;
-       ldap_pvt_thread_pool_context_reset( thrctx );
 
        return rc;
 }
 
 static int
 dds_db_close(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        dds_info_t      *di = on->on_bi.bi_private;
@@ -1781,7 +1788,8 @@ dds_db_close(
 
 static int
 dds_db_destroy(
-       BackendDB       *be )
+       BackendDB       *be,
+       ConfigReply     *cr )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        dds_info_t      *di = on->on_bi.bi_private;
@@ -1813,7 +1821,7 @@ slap_exop_refresh(
                op->o_log_prefix, op->o_req_ndn.bv_val );
        op->o_req_dn = op->o_req_ndn;
 
-       op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
+       op->o_bd = select_backend( &op->o_req_ndn, 0 );
        if ( !SLAP_DYNAMIC( op->o_bd ) ) {
                send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
                        "backend does not support dynamic directory services" );
@@ -1859,18 +1867,17 @@ dds_initialize()
 {
        int             rc = 0;
        int             i, code;
-       const char      *err;
 
        /* Make sure we don't exceed the bits reserved for userland */
        config_check_userland( DDS_LAST );
 
        if ( !do_not_load_schema ) {
                static struct {
-                       char                    *name;
                        char                    *desc;
+                       slap_mask_t             flags;
                        AttributeDescription    **ad;
                }               s_at[] = {
-                       { "entryExpireTimestamp", "( 1.3.6.1.4.1.4203.666.1.57 "
+                       { "( 1.3.6.1.4.1.4203.666.1.57 "
                                "NAME ( 'entryExpireTimestamp' ) "
                                "DESC 'RFC2589 OpenLDAP extension: expire time of a dynamic object, "
                                        "computed as now + entryTtl' "
@@ -1880,39 +1887,19 @@ dds_initialize()
                                "SINGLE-VALUE "
                                "NO-USER-MODIFICATION "
                                "USAGE dSAOperation )",
+                               SLAP_AT_HIDE,
                                &ad_entryExpireTimestamp },
                        { NULL }
                };
 
-               for ( i = 0; s_at[ i ].name != NULL; i++ ) {
-                       LDAPAttributeType       *at;
-
-                       at = ldap_str2attributetype( s_at[ i ].desc,
-                               &code, &err, LDAP_SCHEMA_ALLOW_ALL );
-                       if ( !at ) {
-                               fprintf( stderr, "dds_initialize: "
-                                       "AttributeType load failed: %s %s\n",
-                                       ldap_scherr2str( code ), err );
-                               return code;
-                       }
-
-                       code = at_add( at, 0, NULL, &err );
-                       ldap_memfree( at );
-                       if ( code != LDAP_SUCCESS ) {
-                               fprintf( stderr, "dds_initialize: "
-                                       "AttributeType load failed: %s %s\n",
-                                       scherr2str( code ), err );
+               for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
+                       code = register_at( s_at[ i ].desc, s_at[ i ].ad, 0 );
+                       if ( code ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "dds_initialize: register_at failed\n", 0, 0, 0 );
                                return code;
                        }
-
-                       code = slap_str2ad( s_at[ i ].name, s_at[ i ].ad, &err );
-                       if ( code != LDAP_SUCCESS ) {
-                               fprintf( stderr, "dds_initialize: "
-                                       "unable to find AttributeDescription "
-                                       "\"%s\": %d (%s)\n",
-                                       s_at[ i ].name, code, err );
-                               return 1;
-                       }
+                       (*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
                }
        }
 
@@ -1976,7 +1963,7 @@ init_module( int argc, char *argv[] )
                        do_not_load_schema = no;
 
                } else {
-                       Log( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+                       Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
                                "DDS unknown module arg[#%d]=\"%s\".\n",
                                i, argv[ i ] );
                        return 1;