specification. The search specification includes {{EX:searchbase}},
{{EX:scope}}, {{EX:filter}}, {{EX:attrs}}, {{EX:attrsonly}},
{{EX:sizelimit}}, and {{EX:timelimit}} parameters as in the normal
-search specification. The syncrepl search specification has
-the same value syntax and the same default values as in the
-{{ldapsearch}}(1) client search tool.
+search specification. The {{EX:searchbase}} parameter has no
+default value and must always be specified. The {{EX:scope}} defaults
+to {{EX:sub}}, the {{EX:filter}} defaults to {{EX:(objectclass=*)}},
+{{EX:attrs}} defaults to {{EX:"*,+"}} to replicate all user and operational
+attributes, and {{EX:attrsonly}} is unset by default. Both {{EX:sizelimit}}
+and {{EX:timelimit}} default to "unlimited", and only positive integers
+or "unlimited" may be specified.
The LDAP Content Synchronization protocol has two operation
types: {{EX:refreshOnly}} and {{EX:refreshAndPersist}}.
specification. The search specification includes {{EX:searchbase}},
{{EX:scope}}, {{EX:filter}}, {{EX:attrs}}, {{EX:attrsonly}},
{{EX:sizelimit}}, and {{EX:timelimit}} parameters as in the normal
-search specification. The syncrepl search specification has
-the same value syntax and the same default values as in the
-{{ldapsearch}}(1) client search tool.
+search specification. The {{EX:searchbase}} parameter has no
+default value and must always be specified. The {{EX:scope}} defaults
+to {{EX:sub}}, the {{EX:filter}} defaults to {{EX:(objectclass=*)}},
+{{EX:attrs}} defaults to {{EX:"*,+"}} to replicate all user and operational
+attributes, and {{EX:attrsonly}} is unset by default. Both {{EX:sizelimit}}
+and {{EX:timelimit}} default to "unlimited", and only integers
+or "unlimited" may be specified.
The LDAP Content Synchronization protocol has two operation
types: {{EX:refreshOnly}} and {{EX:refreshAndPersist}}.
.B bind_simple
disables simple (bind) authentication.
.B tls_2_anon
-disables Start TLS from forcing session to anonymous status (see also
-.BR tls_authc ).
+disables forcing session to anonymous status (see also
+.BR tls_authc ) upon StartTLS operation receipt.
.B tls_authc
-disables StartTLS if authenticated (see also
+dissallow the StartTLS operation if authenticated (see also
.BR tls_2_anon ).
.HP
.hy 0
.B searchbase, scope, filter, attrs, attrsonly, sizelimit,
and
.B timelimit
-parameters as in the normal search specification.
-The search specification for the LDAP Content Synchronization operation
-has the same value syntax and the same default values as in the
-.BR ldapsearch (1)
-client search tool.
+parameters as in the normal search specification.
+The \fBscope\fP defaults to \fBsub\fP, the \fBfilter\fP defaults to
+\fB(objectclass=*)\fP, and there is no default \fBsearchbase\fP. The
+\fBattrs\fP list defaults to \fB"*,+"\fP to return all user and operational
+attributes, and \fBattrsonly\fP is unset by default.
+The \fBsizelimit\fP and \fBtimelimit\fP only
+accept "unlimited" and positive integers, and both default to "unlimited".
The LDAP Content Synchronization protocol has two operation types.
In the
.B refreshOnly
alock_slot_t slot_data;
int res;
+ if ( !info->al_slot )
+ return ALOCK_CLEAN;
+
(void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
res = alock_grab_lock (info->al_fd, 0);
addlru = 0;
}
- if ( addlru ) {
- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
- LRU_ADD( &bdb->bi_cache, ein );
- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
- }
- addlru = 1;
/* If this is the first time, save this node
* to be returned later.
bdb->bi_cache.c_leaves++;
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
+ if ( addlru ) {
+ ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
+ LRU_ADD( &bdb->bi_cache, ein );
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
+ }
+ addlru = 1;
+
/* Got the parent, link in and we're done. */
if ( ei2 ) {
bdb_cache_entryinfo_lock( ei2 );
#endif
{
buf[0] = DN_SUBTREE_PREFIX;
- rc = db->del( db, txn, &key, 0 );
+ rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
"=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
static int bdb_idl_delete( ID *ids, ID id )
{
- unsigned x = bdb_idl_search( ids, id );
+ unsigned x;
#if IDL_DEBUG > 1
Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x, 0 );
idl_check( ids );
#endif
+ if (BDB_IDL_IS_RANGE( ids )) {
+ /* If deleting a range boundary, adjust */
+ if ( ids[1] == id )
+ ids[1]++;
+ else if ( ids[2] == id )
+ ids[2]--;
+ /* deleting from inside a range is a no-op */
+
+ /* If the range has collapsed, re-adjust */
+ if ( ids[1] > ids[2] )
+ ids[0] = 0;
+ else if ( ids[1] == ids[2] )
+ ids[1] = 1;
+ return 0;
+ }
+
+ x = bdb_idl_search( ids, id );
assert( x > 0 );
if( x <= 0 ) {
op->o_req_dn = op->o_bd->be_suffix[0];
op->o_req_ndn = op->o_bd->be_nsuffix[0];
rs->sr_err = op->o_bd->be_search(op, rs);
+ if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
+ gs.err = LDAP_SUCCESS;
+ }
} else if (scope0 == LDAP_SCOPE_SUBTREE &&
dn_match(&op->o_bd->be_nsuffix[0], &ndn))
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
gs.err = LDAP_SUCCESS;
}
+ op->o_req_dn = dn;
+ op->o_req_ndn = ndn;
} else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) {
rs->sr_err = op->o_bd->be_search( op, rs );
return SLAP_CB_CONTINUE;
}
a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN );
+ if ( a == NULL && rs->sr_operational_attrs != NULL ) {
+ a = attr_find( rs->sr_operational_attrs, slap_schema.si_ad_entryCSN );
+ }
if ( a ) {
/* Make sure entry is less than the snaphot'd contextCSN */
if ( ber_bvcmp( &a->a_nvals[0], &ss->ss_ctxcsn ) > 0 )
slap_overinst *on = (slap_overinst *) be->bd_info;
syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
- Connection conn;
- OperationBuffer opbuf;
+ Connection conn = { 0 };
+ OperationBuffer opbuf = { 0 };
char ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
Operation *op = (Operation *) &opbuf;
Entry *e;
strcpy( ctxcsnbuf, si->si_ctxcsnbuf );
}
be_entry_release_rw( op, e, 0 );
- op->o_bd->bd_info = (BackendInfo *)on;
- op->o_req_dn = be->be_suffix[0];
- op->o_req_ndn = be->be_nsuffix[0];
- op->ors_scope = LDAP_SCOPE_SUBTREE;
- ldap_pvt_thread_create( &tid, 0, syncprov_db_otask, op );
- ldap_pvt_thread_join( tid, NULL );
+ if ( !BER_BVISEMPTY( &si->si_ctxcsn ) ) {
+ op->o_bd->bd_info = (BackendInfo *)on;
+ op->o_req_dn = be->be_suffix[0];
+ op->o_req_ndn = be->be_nsuffix[0];
+ op->ors_scope = LDAP_SCOPE_SUBTREE;
+ ldap_pvt_thread_create( &tid, 0, syncprov_db_otask, op );
+ ldap_pvt_thread_join( tid, NULL );
+ }
} else if ( SLAP_SYNC_SHADOW( op->o_bd )) {
/* If we're also a consumer, and we didn't find the context entry,
* then don't generate anything, wait for our provider to send it
syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
if ( si ) {
+ if ( si->si_logs ) {
+ ch_free( si->si_logs );
+ }
ldap_pvt_thread_mutex_destroy( &si->si_mods_mutex );
ldap_pvt_thread_mutex_destroy( &si->si_ops_mutex );
ldap_pvt_thread_mutex_destroy( &si->si_csn_mutex );
int rc;
rc = register_supported_control( LDAP_CONTROL_SYNC,
- SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
+ SLAP_CTRL_SEARCH, NULL,
syncprov_parseCtrl, &slap_cids.sc_LDAPsync );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
nop->o_bd = on->on_info->oi_origdb;
rc = nop->o_bd->be_search(nop, &nrs);
filter_free_x(nop, nop->ors_filter);
- ch_free( key );
+ op->o_tmpfree( key, op->o_tmpmemctx );
if(rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) {
op->o_bd->bd_info = (BackendInfo *) on->on_info;
return(SLAP_CB_CONTINUE);
}
+#define ALLOC_EXTRA 16 /* extra slop */
+
static int unique_add(
Operation *op,
SlapReply *rs
Attribute *a;
char *key, *kp;
- int ks = 16;
+ int ks = 0;
Debug(LDAP_DEBUG_TRACE, "==> unique_add <%s>\n", op->o_req_dn.bv_val, 0, 0);
ks = count_filter_len(ud, a->a_desc, a->a_vals, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
Modifications *m;
char *key, *kp;
- int ks = 16; /* a handful of extra bytes */
+ int ks = 0;
Debug(LDAP_DEBUG_TRACE, "==> unique_modify <%s>\n", op->o_req_dn.bv_val, 0, 0);
ks = count_filter_len(ud, m->sml_desc, m->sml_values, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
Operation nop = *op;
char *key, *kp;
- int i, ks = 16; /* a handful of extra bytes */
+ int i, ks = 0;
LDAPRDN newrdn;
struct berval bv[2];
ks = count_filter_len(ud, newrdn[i]->la_private, bv, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
for(i = 0; newrdn[i]; i++) {