Fixed slapd empty rootdn bug (ITS#1172)
Fixed slapd numericString empty value bug (ITS#1182)
Fixed slapd acl default clause bug (ITS#1187)
+ Fixed slapd passwd modify replication
Added slapadd already exists check (ITS#1191)
Added slapd modrdn children check (ITS#1053,1192)
Added slapd sb_max_incoming_auth support (ITS#1181)
Added slapd crypt salt format support (ITS#1202)
Updated slapd schema check handling
Updated ldbm to use BerkeleyDB's CDB (ITS#1176)
+ Updated ldbm error handling
Updated slapd filter checks
Updated ldaptcl API (contrib)
Build environment
repl.c lock.c controls.c extended.c kerberos.c passwd.c \
schema.c schema_check.c schema_init.c schema_prep.c \
schemaparse.c ad.c at.c mr.c syntax.c oc.c \
- monitor.c configinfo.c starttls.c index.c sets.c\
- root_dse.c sasl.c module.c suffixalias.c $(@PLAT@_SRCS)
+ configinfo.c starttls.c index.c sets.c \
+ root_dse.c sasl.c module.c suffixalias.c mods.c \
+ $(@PLAT@_SRCS)
OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
attr.o entry.o config.o backend.o result.o operation.o \
repl.o lock.o controls.o extended.o kerberos.o passwd.o \
schema.o schema_check.o schema_init.o schema_prep.o \
schemaparse.o ad.o at.o mr.o syntax.o oc.o \
- monitor.o configinfo.o starttls.o index.o sets.o\
- root_dse.o sasl.o module.o suffixalias.o $(@PLAT@_OBJS)
+ configinfo.o starttls.o index.o sets.o \
+ root_dse.o sasl.o module.o suffixalias.o mods.o \
+ $(@PLAT@_OBJS)
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
char *pdn;
Entry *p = NULL;
int rootlock = 0;
- int rc;
+ int rc;
+ ID id = NOID;
const char *text = NULL;
AttributeDescription *children = slap_schema.si_ad_children;
char textbuf[SLAP_TEXT_BUFLEN];
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
+
/* nobody else can add until we lock our parent */
ldap_pvt_thread_mutex_lock(&li->li_add_mutex);
- if ( ( dn2id( be, e->e_ndn ) ) != NOID ) {
+ if ( ( rc = dn2id( be, e->e_ndn, &id ) ) || id != NOID ) {
+ /* if (rc) something bad happened to ldbm cache */
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
- send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
+ send_ldap_result( conn, op,
+ rc ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS,
NULL, NULL, NULL, NULL );
return( -1 );
}
Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n",
text, 0, 0 );
+
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
return( -1 );
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
0, 0, 0 );
- send_ldap_result( conn, op, LDAP_REFERRAL,
- matched_dn, NULL, refs, NULL );
+
+ send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn,
+ refs == NULL ? "parent does not exist" : "parent is referral",
+ refs, NULL );
if( matched != NULL ) {
ber_bvecfree( refs );
Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, "no write access to parent", NULL, NULL );
Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, "parent is an alias", NULL, NULL );
Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
pdn == NULL ? "suffix" : "entry at root",
0, 0 );
+
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
}
- e->e_id = next_id( be );
-
- if( e->e_id == NOID ) {
+ if ( next_id( be, &e->e_id ) ) {
if( p != NULL) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
Debug( LDAP_DEBUG_ANY, "ldbm_add: next_id failed\n",
0, 0, 0 );
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "next_id add failed", NULL, NULL );
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
0 );
+
send_ldap_result( conn, op,
rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OTHER,
NULL, rc > 0 ? NULL : "cache add failed", NULL, NULL );
if ( index_entry_add( be, e, e->e_attrs ) != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "index_entry_add failed\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "index generation failed", NULL, NULL );
if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0,
0, 0 );
+ /* FIXME: delete attr indices? */
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "DN index generation failed", NULL, NULL );
if ( id2entry_add( be, e ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "id2entry_add failed\n", 0,
0, 0 );
+
+ /* FIXME: delete attr indices? */
(void) dn2id_delete( be, e->e_ndn, e->e_id );
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "entry store failed", NULL, NULL );
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
+
+ /* marks the entry as committed, so it is added to the cache;
+ * otherwise it is removed from the cache, but not destroyed;
+ * it will be destroyed by the caller */
rc = 0;
+ cache_entry_commit( e );
return_results:;
if (p != NULL) {
}
if ( rc ) {
- /* free entry and writer lock */
+ /* in case of error, writer lock is freed
+ * and entry's private data is destroyed */
cache_return_entry_w( &li->li_cache, e );
}
int lei_state; /* for the cache */
#define CACHE_ENTRY_UNDEFINED 0
#define CACHE_ENTRY_CREATING 1
-#define CACHE_ENTRY_READY 2
-#define CACHE_ENTRY_DELETED 3
-
+#define CACHE_ENTRY_READY 2
+#define CACHE_ENTRY_DELETED 3
+#define CACHE_ENTRY_COMMITTED 4
+
int lei_refcnt; /* # threads ref'ing this entry */
Entry *lei_lrunext; /* for cache lru list */
Entry *lei_lruprev;
return 0;
}
+/*
+ * marks an entry in CREATING state as committed, so it is really returned
+ * to the cache. Otherwise an entry in CREATING state is removed.
+ * Makes e_private be destroyed at the following cache_return_entry_w,
+ * but lets the entry untouched (owned by someone else)
+ */
+void
+cache_entry_commit( Entry *e )
+{
+ assert( e );
+ assert( e->e_private );
+ assert( LEI(e)->lei_state == CACHE_ENTRY_CREATING );
+ /* assert( LEI(e)->lei_refcnt == 1 ); */
+
+ LEI(e)->lei_state = CACHE_ENTRY_COMMITTED;
+}
+
static int
cache_entry_private_destroy( Entry*e )
{
cache_return_entry_rw( Cache *cache, Entry *e, int rw )
{
ID id;
- int refcnt;
+ int refcnt, freeit = 1;
/* set cache mutex */
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
id = e->e_id;
refcnt = --LEI(e)->lei_refcnt;
- if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {
+ /*
+ * if the entry is returned when in CREATING state, it is deleted
+ * but not freed because it may belong to someone else (do_add,
+ * for instance)
+ */
+ if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {
+ cache_delete_entry_internal( cache, e );
+ freeit = 0;
+ /* now the entry is in DELETED state */
+ }
+
+ if ( LEI(e)->lei_state == CACHE_ENTRY_COMMITTED ) {
LEI(e)->lei_state = CACHE_ENTRY_READY;
/* free cache mutex */
} else {
cache_entry_private_destroy( e );
- entry_free( e );
+ if ( freeit ) {
+ entry_free( e );
+ }
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
Cache *cache,
const char *dn
)
+{
+ char *ndn;
+ ID id;
+
+ ndn = ch_strdup( dn );
+ (void) dn_normalize( ndn );
+
+ id = cache_find_entry_ndn2id( be, cache, ndn );
+
+ free( ndn );
+
+ return ( id );
+}
+
+ID
+cache_find_entry_ndn2id(
+ Backend *be,
+ Cache *cache,
+ const char *ndn
+)
{
Entry e, *ep;
ID id;
int count = 0;
- e.e_dn = (char *) dn;
- e.e_ndn = ch_strdup( dn );
- (void) dn_normalize( e.e_ndn );
+ /* this function is always called with normalized DN */
+ e.e_ndn = (char *)ndn;
try_again:
/* set cache mutex */
Debug(LDAP_DEBUG_TRACE,
"====> cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n",
- dn, id, state);
+ ndn, id, state);
ldap_pvt_thread_yield();
goto try_again;
Debug(LDAP_DEBUG_TRACE,
"====> cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n",
- dn, id, count);
+ ndn, id, count);
} else {
/* free cache mutex */
id = NOID;
}
- free(e.e_ndn);
-
return( id );
}
return( rc );
}
-ID
+int
dn2id(
Backend *be,
- const char *dn
+ const char *dn,
+ ID *idp
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
DBCache *db;
- ID id;
Datum key, data;
Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
+ assert( idp );
+
/* first check the cache */
- if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
- Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
+ if ( (*idp = cache_find_entry_ndn2id( be, &li->li_cache, dn )) != NOID ) {
+ Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", *idp,
0, 0 );
- return( id );
+ return( 0 );
}
if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
LDBM_SUFFIX, 0, 0 );
- return( NOID );
+ /*
+ * return code !0 if ldbm cache open failed;
+ * callers should handle this
+ */
+ *idp = NOID;
+ return( -1 );
}
ldbm_datum_init( key );
if ( data.dptr == NULL ) {
Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
- return( NOID );
+ *idp = NOID;
+ return( 0 );
}
- AC_MEMCPY( (char *) &id, data.dptr, sizeof(ID) );
+ AC_MEMCPY( (char *) idp, data.dptr, sizeof(ID) );
- assert( id != NOID );
+ assert( *idp != NOID );
ldbm_datum_free( db->dbc_db, data );
- Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
- return( id );
+ Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", *idp, 0, 0 );
+
+ return( 0 );
}
-ID_BLOCK *
+int
dn2idl(
Backend *be,
const char *dn,
- int prefix
+ int prefix,
+ ID_BLOCK **idlp
)
{
DBCache *db;
Datum key;
- ID_BLOCK *idl;
Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
+ assert( idlp != NULL );
+ *idlp = NULL;
+
if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
LDBM_SUFFIX, 0, 0 );
- return NULL;
+ return -1;
}
ldbm_datum_init( key );
key.dptr = ch_malloc( key.dsize );
sprintf( key.dptr, "%c%s", prefix, dn );
- idl = idl_fetch( be, db, key );
+ *idlp = idl_fetch( be, db, key );
ldbm_cache_close( be, db );
free( key.dptr );
- return( idl );
+ return( 0 );
}
*matched = NULL;
}
- if ( (id = dn2id( be, dn )) != NOID &&
- (e = id2entry_rw( be, id, rw )) != NULL )
- {
- return( e );
- }
+ if ( dn2id( be, dn, &id ) ) {
+ /* something bad happened to ldbm cache */
+ return( NULL );
+
+ } else if ( id != NOID ) {
+ /* try to return the entry */
+ if ((e = id2entry_rw( be, id, rw )) != NULL ) {
+ return( e );
+ }
- if ( id != NOID ) {
Debug(LDAP_DEBUG_ANY,
"dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
rw ? "w" : "r", id, dn);
switch ( f->f_choice ) {
case SLAPD_FILTER_DN_ONE:
Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
- result = dn2idl( be, f->f_dn, DN_ONE_PREFIX );
+
+ /* an error is treated as an empty list */
+ if ( dn2idl( be, f->f_dn, DN_ONE_PREFIX, &result ) != 0
+ && result != NULL ) {
+ idl_free( result );
+ result = NULL;
+ }
break;
case SLAPD_FILTER_DN_SUBTREE:
Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
- result = dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
+
+ /* an error is treated as an empty list */
+ if ( dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX, &result ) != 0
+ && result != NULL ) {
+ idl_free( result );
+ result = NULL;
+ }
break;
case LDAP_FILTER_PRESENT:
Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (disk)\n",
rw ? "w" : "r", id, (unsigned long) e );
+ /* marks the entry as committed, so it will get added to the cache
+ * when the lock is released */
+ cache_entry_commit( e );
+
return( e );
}
idl_allids( Backend *be )
{
ID_BLOCK *idl;
+ ID id;
idl = idl_alloc( 0 );
ID_BLOCK_NMAX(idl) = ID_BLOCK_ALLIDS_VALUE;
- ID_BLOCK_NIDS(idl) = next_id_get( be );
+ if ( next_id_get( be, &id ) ) {
+ return NULL;
+ }
+ ID_BLOCK_NIDS(idl) = id;
return( idl );
}
Entry *e, *p = NULL;
Entry *matched;
int rootlock = 0;
- int rc = -1;
+ int rc = -1, rc_id = 0;
+ ID id = NOID;
const char *text = NULL;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
/* Added to support LDAP v2 correctly (deleteoldrdn thing) */
- char *new_rdn_val = NULL; /* Val of new rdn */
- char *new_rdn_type = NULL; /* Type of new rdn */
- char *old_rdn = NULL; /* Old rdn's attr type & val */
- char *old_rdn_type = NULL; /* Type of old rdn attr. */
- char *old_rdn_val = NULL; /* Old rdn attribute value */
+ char **new_rdn_vals = NULL; /* Vals of new rdn */
+ char **new_rdn_types = NULL; /* Types of new rdn */
+ int a_cnt, d_cnt;
+ char *old_rdn = NULL; /* Old rdn's attr type & val */
+ char **old_rdn_types = NULL; /* Types of old rdn attrs. */
+ char **old_rdn_vals = NULL; /* Old rdn attribute values */
/* Added to support newSuperior */
Entry *np = NULL; /* newSuperior Entry */
- char *np_dn = NULL; /* newSuperior dn */
+ char *np_dn = NULL; /* newSuperior dn */
char *np_ndn = NULL; /* newSuperior ndn */
char *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */
/* Used to interface with ldbm_modify_internal() */
- struct berval add_bv; /* Stores new rdn att */
- struct berval *add_bvals[2]; /* Stores new rdn att */
- struct berval del_bv; /* Stores old rdn att */
- struct berval *del_bvals[2]; /* Stores old rdn att */
- Modifications mod[2]; /* Used to delete old rdn */
+ Modifications *mod = NULL; /* Used to delete old/add new rdn */
int manageDSAit = get_manageDSAit( op );
Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
}
if ( has_children( be, e ) ) {
- Debug( LDAP_DEBUG_TRACE, "entry %s referral\n", 0,
+ Debug( LDAP_DEBUG_TRACE, "entry %s referral\n", e->e_dn,
0, 0 );
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
goto return_results;
}
- if ( (p_ndn = dn_parent( be, e->e_ndn )) != NULL ) {
-
+ if ( (p_ndn = dn_parent( be, e->e_ndn )) != NULL && p_ndn[0] != '\0' ) {
/* Make sure parent entry exist and we can write its
* children.
*/
if( (p = dn2entry_w( be, p_ndn, NULL )) == NULL) {
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
0, 0, 0);
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "parent entry does not exist", NULL, NULL );
{
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
goto return_results;
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: wr to children of entry %s OK\n",
p_ndn, 0, 0 );
-
+
p_dn = dn_parent( be, e->e_dn );
-
Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
p_dn, 0, 0 );
} else {
/* no parent, modrdn entry directly under root */
- if( ! be_isroot( be, op->o_ndn ) ) {
+ if( ! be_isroot( be, op->o_ndn ) && ! be_issuffix( be, "" ) ) {
Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
0, 0, 0);
+
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
goto return_results;
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: no parent, locked root\n",
0, 0, 0 );
-
}
new_parent_dn = p_dn; /* New Parent unless newSuperior given */
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: new parent \"%s\" seems to be the same as old parent \"%s\"...\n",
newSuperior, p_dn, 0 );
+
newSuperior = NULL; /* ignore newSuperior */
}
}
if ( newSuperior != NULL ) {
-
/* newSuperior == entry being moved?, if so ==> ERROR */
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
np_ndn, 0, 0);
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "newSuperior not found", NULL, NULL );
goto return_results;
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: wr to new parent OK np=%p, id=%ld\n",
np, np->e_id, 0 );
-
+
/* check newSuperior for "children" acl */
if ( !access_allowed( be, conn, op, np, children, NULL,
ACL_WRITE ) )
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: no wr to newSup children\n",
0, 0, 0 );
+
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
goto return_results;
Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
0, 0 );
+
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, "newSuperior is an alias", NULL, NULL );
}
/* Build target dn and make sure target entry doesn't exist already. */
-
build_new_dn( &new_dn, e->e_dn, new_parent_dn, newrdn );
-
new_ndn = ch_strdup(new_dn);
(void) dn_normalize( new_ndn );
}
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
- if (dn2id ( be, new_ndn ) != NOID) {
- send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
+ if ( ( rc_id = dn2id ( be, new_ndn, &id ) ) || id != NOID ) {
+ /* if (rc_id) something bad happened to ldbm cache */
+ send_ldap_result( conn, op,
+ rc_id ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS,
NULL, NULL, NULL, NULL );
goto return_results;
}
"ldbm_back_modrdn: new ndn=%s does not exist\n",
new_ndn, 0, 0 );
- /* Get attribute type and attribute value of our new rdn, we will
+
+ /* Get attribute types and values of our new rdn, we will
* need to add that to our new entry
*/
-
- if ( (new_rdn_type = rdn_attr_type( newrdn )) == NULL ) {
-
+ if ( rdn_attrs( newrdn, &new_rdn_types, &new_rdn_vals ) ) {
Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: can't figure out type of newrdn\n",
+ "ldbm_back_modrdn: can't figure out type(s)/value(s) of newrdn\n",
0, 0, 0 );
- send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
- NULL, "unknown type used in RDN", NULL, NULL );
- goto return_results;
- }
-
- if ( (new_rdn_val = rdn_attr_value( newrdn )) == NULL ) {
-
- Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: can't figure out val of newrdn\n",
- 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
- NULL, "could not parse RDN value", NULL, NULL );
+ NULL, "unable to parse type(s)/value(s) used in RDN", NULL, NULL );
goto return_results;
-
}
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: new_rdn_val=\"%s\", new_rdn_type=\"%s\"\n",
- new_rdn_val, new_rdn_type, 0 );
+ new_rdn_vals[0], new_rdn_types[0], 0 );
/* Retrieve the old rdn from the entry's dn */
-
if ( (old_rdn = dn_rdn( be, dn )) == NULL ) {
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: can't figure out old_rdn from dn\n",
0, 0, 0 );
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "could not parse old DN", NULL, NULL );
goto return_results;
}
- if ( (old_rdn_type = rdn_attr_type( old_rdn )) == NULL ) {
+ if ( rdn_attrs( old_rdn, &old_rdn_types, &old_rdn_vals ) ) {
Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: can't figure out the old_rdn type\n",
+ "ldbm_back_modrdn: can't figure out the old_rdn type(s)/value(s)\n",
0, 0, 0 );
+
send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "count parse RDN from old DN", NULL, NULL );
+ NULL, "unable to parse type(s)/value(s) used in RDN from old DN", NULL, NULL );
goto return_results;
}
if ( newSuperior == NULL
- && strcasecmp( old_rdn_type, new_rdn_type ) != 0 )
+ && charray_strcasecmp( (const char **)old_rdn_types, (const char **)new_rdn_types ) != 0 )
{
/* Not a big deal but we may say something */
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: old_rdn_type=%s, new_rdn_type=%s!\n",
- old_rdn_type, new_rdn_type, 0 );
+ old_rdn_types[0], new_rdn_types[0], 0 );
}
- Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
- 0, 0, 0 );
-
- /* Add new attribute value to the entry.
- */
+ Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
+ 0, 0, 0 );
- add_bvals[0] = &add_bv; /* Array of bervals */
- add_bvals[1] = NULL;
+ mod = NULL;
+ for ( a_cnt = 0; new_rdn_types[a_cnt]; a_cnt++ ) {
+ int rc;
+ Modifications *mod_tmp;
- add_bv.bv_val = new_rdn_val;
- add_bv.bv_len = strlen(new_rdn_val);
-
- {
+ mod_tmp = (Modifications *)ch_malloc( sizeof( Modifications ) );
+
+ mod_tmp->sml_desc = NULL;
+ rc = slap_str2ad( new_rdn_types[a_cnt],
+ &mod_tmp->sml_desc, &text );
+
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "ldbm_back_modrdn: %s: %s (new)\n",
+ text, new_rdn_types[a_cnt], 0 );
+
+ send_ldap_result( conn, op, rc,
+ NULL, text, NULL, NULL );
+
+ goto return_results;
+ }
+
+ mod_tmp->sml_bvalues = (struct berval **)ch_malloc( 2 * sizeof(struct berval *) );
+ mod_tmp->sml_bvalues[0] = ber_bvstrdup( new_rdn_vals[a_cnt] );
+ mod_tmp->sml_bvalues[1] = NULL;
+ mod_tmp->sml_op = SLAP_MOD_SOFTADD;
+ mod_tmp->sml_next = mod;
+ mod = mod_tmp;
+ }
+
+ /* Remove old rdn value if required */
+ if ( deleteoldrdn ) {
+ /* Get value of old rdn */
+ if ( old_rdn_vals == NULL ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "ldbm_back_modrdn: can't figure out oldRDN value(s) from old RDN\n",
+ 0, 0, 0 );
+
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "could not parse value(s) from old RDN", NULL, NULL );
+ goto return_results;
+ }
+
+ for ( d_cnt = 0; old_rdn_types[d_cnt]; d_cnt++ ) {
int rc;
+ Modifications *mod_tmp;
+
+ mod_tmp = (Modifications *)ch_malloc( sizeof( Modifications ) );
+
- mod[0].sml_desc = NULL;
- rc = slap_str2ad( new_rdn_type, &mod[0].sml_desc, &text );
+ mod_tmp->sml_desc = NULL;
+ rc = slap_str2ad( old_rdn_types[d_cnt],
+ &mod_tmp->sml_desc, &text );
- if( rc != LDAP_SUCCESS ) {
+ if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: %s: %s (new)\n",
- text, new_rdn_type, 0 );
+ "ldbm_back_modrdn: %s: %s (old)\n",
+ text, old_rdn_types[d_cnt], 0 );
+
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
- goto return_results;
- }
- }
- mod[0].sml_bvalues = add_bvals;
- mod[0].sml_op = SLAP_MOD_SOFTADD;
- mod[0].sml_next = NULL;
-
- /* Remove old rdn value if required */
- if (deleteoldrdn) {
- /* Get value of old rdn */
-
- if ((old_rdn_val = rdn_attr_value( old_rdn ))
- == NULL) {
-
- Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: can't figure out old_rdn_val from old_rdn\n",
- 0, 0, 0 );
- send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "could not parse value from old RDN", NULL, NULL );
- goto return_results;
+ goto return_results;
}
- del_bvals[0] = &del_bv; /* Array of bervals */
- del_bvals[1] = NULL;
-
/* Remove old value of rdn as an attribute. */
-
- del_bv.bv_val = old_rdn_val;
- del_bv.bv_len = strlen(old_rdn_val);
-
- {
- int rc;
-
- mod[1].sml_desc = NULL;
- rc = slap_str2ad( old_rdn_type, &mod[1].sml_desc, &text );
-
- if( rc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE,
- "ldbm_back_modrdn: %s: %s (old)\n",
- text, old_rdn_type, 0 );
- send_ldap_result( conn, op, rc,
- NULL, text, NULL, NULL );
- goto return_results;
- }
- }
- mod[0].sml_next = &mod[1];
- mod[1].sml_bvalues = del_bvals;
- mod[1].sml_op = LDAP_MOD_DELETE;
- mod[1].sml_next = NULL;
+ mod_tmp->sml_bvalues = (struct berval **)ch_malloc( 2 * sizeof(struct berval *) );
+ mod_tmp->sml_bvalues[0] = ber_bvstrdup( old_rdn_vals[d_cnt] );
+ mod_tmp->sml_bvalues[1] = NULL;
+ mod_tmp->sml_op = LDAP_MOD_DELETE;
+ mod_tmp->sml_next = mod;
+ mod = mod_tmp;
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: removing old_rdn_val=%s\n",
- old_rdn_val, 0, 0 );
+ old_rdn_vals[0], 0, 0 );
}
+ }
+
/* check for abandon */
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
goto return_results;
}
+ rc = -1;
(void) cache_update_entry( &li->li_cache, e );
/* id2entry index */
if ( id2entry_add( be, e ) != 0 ) {
- entry_free( e );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "entry update failed", NULL, NULL );
goto return_results;
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
rc = 0;
+ cache_entry_commit( e );
return_results:
if( new_dn != NULL ) free( new_dn );
if( p_ndn != NULL ) free( p_ndn );
/* LDAP v2 supporting correct attribute handling. */
- if( new_rdn_type != NULL ) free(new_rdn_type);
- if( new_rdn_val != NULL ) free(new_rdn_val);
+ if( new_rdn_types != NULL ) charray_free( new_rdn_types );
+ if( new_rdn_vals != NULL ) charray_free( new_rdn_vals );
if( old_rdn != NULL ) free(old_rdn);
- if( old_rdn_type != NULL ) free(old_rdn_type);
- if( old_rdn_val != NULL ) free(old_rdn_val);
+ if( old_rdn_types != NULL ) charray_free( old_rdn_types );
+ if( old_rdn_vals != NULL ) charray_free( old_rdn_vals );
+ if ( mod != NULL ) {
+ slap_mods_free( mod );
+ }
/* LDAP v3 Support */
if ( np_dn != NULL ) free( np_dn );
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
+ if ( rc ) {
+ /* if rc != 0 the entry is uncached and its private data
+ * is destroyed; the entry must be freed */
+ entry_free( e );
+ }
return( rc );
}
#include "slap.h"
#include "back-ldbm.h"
-static ID
-next_id_read( Backend *be )
+static int
+next_id_read( Backend *be, ID *idp )
{
- ID id = NOID;
Datum key, data;
DBCache *db;
+ *idp = NOID;
+
if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "Could not open/create nextid" LDBM_SUFFIX "\n",
0, 0, 0 );
- return( NOID );
+
+ return( -1 );
}
ldbm_datum_init( key );
- key.dptr = (char *) &id;
+ key.dptr = (char *) idp;
key.dsize = sizeof(ID);
data = ldbm_cache_fetch( db, key );
if( data.dptr != NULL ) {
- AC_MEMCPY( &id, data.dptr, sizeof( ID ) );
+ AC_MEMCPY( idp, data.dptr, sizeof( ID ) );
ldbm_datum_free( db->dbc_db, data );
} else {
- id = 1;
+ *idp = 1;
}
ldbm_cache_close( be, db );
- return id;
+ return( 0 );
}
-ID
+int
next_id_write( Backend *be, ID id )
{
- struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Datum key, data;
DBCache *db;
ID noid = NOID;
- int flags;
+ int flags, rc = 0;
if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "Could not open/create nextid" LDBM_SUFFIX "\n",
0, 0, 0 );
- return( NOID );
+
+ return( -1 );
}
ldbm_datum_init( key );
flags = LDBM_REPLACE;
if ( ldbm_cache_store( db, key, data, flags ) != 0 ) {
- id = NOID;
+ rc = -1;
}
ldbm_cache_close( be, db );
- return id;
+ return( rc );
}
-ID
-next_id_get( Backend *be )
+int
+next_id_get( Backend *be, ID *idp )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- ID id = NOID;
+ int rc = 0;
+
+ *idp = NOID;
ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
if ( li->li_nextid == NOID ) {
- li->li_nextid = next_id_read( be );
+ if ( ( rc = next_id_read( be, idp ) ) ) {
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
+ return( rc );
+ }
+ li->li_nextid = *idp;
}
- id = li->li_nextid;
+ *idp = li->li_nextid;
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
- return id;
+ return( rc );
}
-ID
-next_id( Backend *be )
+int
+next_id( Backend *be, ID *idp )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- ID id = NOID;
+ int rc = 0;
ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
if ( li->li_nextid == NOID ) {
- li->li_nextid = next_id_read( be );
+ if ( ( rc = next_id_read( be, idp ) ) ) {
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
+ return( rc );
+ }
+ li->li_nextid = *idp;
}
- if ( li->li_nextid != NOID ) {
- id = li->li_nextid++;
-
- (void) next_id_write( be, li->li_nextid );
+ *idp = li->li_nextid++;
+ if ( next_id_write( be, li->li_nextid ) ) {
+ rc = -1;
}
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
- return id;
+ return( rc );
}
*text = "entry modify failed";
goto done;
}
- }
- /* change the entry itself */
- if( id2entry_add( be, e ) != 0 ) {
- *text = "entry update failed";
- rc = LDAP_OTHER;
+ /* change the entry itself */
+ if( id2entry_add( be, e ) != 0 ) {
+ *text = "entry update failed";
+ rc = LDAP_OTHER;
+ }
+
+ replog( be, op, e->e_dn, &ml );
}
done:
void cache_return_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw ));
#define cache_return_entry_r(c, e) cache_return_entry_rw((c), (e), 0)
#define cache_return_entry_w(c, e) cache_return_entry_rw((c), (e), 1)
+void cache_entry_commit LDAP_P(( Entry *e ));
ID cache_find_entry_dn2id LDAP_P(( Backend *be, Cache *cache, const char *dn ));
+ID cache_find_entry_ndn2id LDAP_P(( Backend *be, Cache *cache, const char *ndn ));
Entry * cache_find_entry_id LDAP_P(( Cache *cache, ID id, int rw ));
int cache_delete_entry LDAP_P(( Cache *cache, Entry *e ));
void cache_release_all LDAP_P(( Cache *cache ));
Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key ));
int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags ));
int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key ));
+void *ldbm_cache_sync_daemon LDAP_P(( void *));
/*
* dn2id.c
*/
int dn2id_add LDAP_P(( Backend *be, const char *dn, ID id ));
-ID dn2id LDAP_P(( Backend *be, const char *dn ));
-ID_BLOCK *dn2idl LDAP_P(( Backend *be, const char *dn, int prefix ));
+int dn2id LDAP_P(( Backend *be, const char *dn, ID *idp ));
+int dn2idl LDAP_P(( Backend *be, const char *dn, int prefix, ID_BLOCK **idlp ));
int dn2id_delete LDAP_P(( Backend *be, const char *dn, ID id ));
Entry * dn2entry_rw LDAP_P(( Backend *be, const char *dn, Entry **matched, int rw ));
* nextid.c
*/
-ID next_id LDAP_P(( Backend *be ));
-ID next_id_get LDAP_P(( Backend *be ));
-ID next_id_write LDAP_P(( Backend *be, ID id ));
+int next_id LDAP_P(( Backend *be, ID *idp ));
+int next_id_get LDAP_P(( Backend *be, ID *idp ));
+int next_id_write LDAP_P(( Backend *be, ID id ));
LDAP_END_DECL
#endif
assert( slapMode & SLAP_TOOL_MODE );
assert( id2entry != NULL );
- if( next_id_get( be ) == NOID ) {
+ if ( next_id_get( be, &id ) || id == NOID ) {
return NOID;
}
Debug( LDAP_DEBUG_TRACE, "=> ldbm_tool_entry_put( %ld, \"%s\" )\n",
e->e_id, e->e_dn, 0 );
- id = dn2id( be, e->e_ndn );
+ if ( dn2id( be, e->e_ndn, &id ) ) {
+ /* something bad happened to ldbm cache */
+ return NOID;
+ }
+
if( id != NOID ) {
Debug( LDAP_DEBUG_TRACE,
"<= ldbm_tool_entry_put: \"%s\" already exists (id=%ld)\n",
assert( slapMode & SLAP_TOOL_MODE );
if ( li->li_nextid != NOID ) {
- next_id_write( be, li->li_nextid );
+ if ( next_id_write( be, li->li_nextid ) ) {
+ return( -1 );
+ }
}
return 0;
}
-int rdn_validate( const char * rdn )
+/* rdn_attrs:
+ *
+ * Given a string (i.e. an rdn) of the form:
+ * "attribute_type=attribute_value[+attribute_type=attribute_value[...]]"
+ * this function stores the types of the attributes in ptypes, that is the
+ * array of strings "attribute_type" which is placed in newly allocated
+ * memory, and the values of the attributes in pvalues, that is the
+ * array of strings "attribute_value" which is placed in newly allocated
+ * memory. Returns 0 on success, -1 on failure.
+ *
+ * note: got part of the code from dn_validate
+ */
+
+int
+rdn_attrs( const char * rdn_in, char ***ptypes, char ***pvalues)
+{
+ char **parts, **p;
+
+ *ptypes = NULL;
+ *pvalues = NULL;
+
+ /*
+ * explode the rdn in parts
+ */
+ parts = ldap_explode_rdn( rdn_in, 0 );
+
+ if ( parts == NULL ) {
+ return( -1 );
+ }
+
+ for ( p = parts; p[0]; p++ ) {
+ char *s, *e, *d;
+
+ /* split each rdn part in type value */
+ s = strchr( p[0], '=' );
+ if ( s == NULL ) {
+ charray_free( *ptypes );
+ charray_free( *pvalues );
+ charray_free( parts );
+ return( -1 );
+ }
+
+ /* type should be fine */
+ charray_add_n( ptypes, p[0], ( s-p[0] ) );
+
+ /* value needs to be unescaped
+ * (maybe this should be moved to ldap_explode_rdn?) */
+ for ( e = d = s + 1; e[0]; e++ ) {
+ if ( *e != '\\' ) {
+ *d++ = *e;
+ }
+ }
+ d[0] = '\0';
+ charray_add( pvalues, s + 1 );
+ }
+
+ /* free array */
+ charray_free( parts );
+
+ return( 0 );
+}
+
+
+/* rdn_validate:
+ *
+ * 1 if rdn is a legal rdn;
+ * 0 otherwise (including a sequence of rdns)
+ *
+ * note: got it from dn_rdn; it should be rewritten
+ * according to dn_validate
+ */
+int
+rdn_validate( const char * rdn )
{
- /* just a simple check for now */
- return strchr( rdn, '=' ) != NULL;
+ int inquote;
+
+ if ( rdn == NULL ) {
+ return( 0 );
+ }
+
+ if ( strchr( rdn, '=' ) == NULL ) {
+ return( 0 );
+ }
+
+ while ( *rdn && ASCII_SPACE( *rdn ) ) {
+ rdn++;
+ }
+
+ if( *rdn == '\0' ) {
+ return( 0 );
+ }
+
+ inquote = 0;
+
+ for ( ; *rdn; rdn++ ) {
+ if ( *rdn == '\\' ) {
+ if ( *(rdn + 1) ) {
+ rdn++;
+ }
+ continue;
+ }
+ if ( inquote ) {
+ if ( *rdn == '"' ) {
+ inquote = 0;
+ }
+ } else {
+ if ( *rdn == '"' ) {
+ inquote = 1;
+ } else if ( DN_SEPARATOR( *rdn ) ) {
+ return( 0 );
+ }
+ }
+ }
+
+ return( 1 );
}
# End Source File
# Begin Source File
-SOURCE=.\configinfo.c
-# End Source File
-# Begin Source File
-
SOURCE=.\connection.c
# End Source File
# Begin Source File
# End Source File
# Begin Source File
-SOURCE=.\monitor.c
+SOURCE=.\mods.c
# End Source File
# Begin Source File
return LDAP_SUCCESS;
}
-
-void
-slap_mod_free(
- Modification *mod,
- int freeit
-)
-{
- ad_free( mod->sm_desc, 1 );
-
- if ( mod->sm_bvalues != NULL )
- ber_bvecfree( mod->sm_bvalues );
-
- if( freeit )
- free( mod );
-}
-
-void
-slap_mods_free(
- Modifications *ml
-)
-{
- Modifications *next;
-
- for ( ; ml != NULL; ml = next ) {
- next = ml->sml_next;
-
- slap_mod_free( &ml->sml_mod, 0 );
- free( ml );
- }
-}
-
-void
-slap_modlist_free(
- LDAPModList *ml
-)
-{
- LDAPModList *next;
-
- for ( ; ml != NULL; ml = next ) {
- next = ml->ml_next;
-
- if (ml->ml_type)
- free( ml->ml_type );
-
- if ( ml->ml_bvalues != NULL )
- ber_bvecfree( ml->ml_bvalues );
-
- free( ml );
- }
-}
--- /dev/null
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#include "portable.h"
+
+#include "slap.h"
+
+void
+slap_mod_free(
+ Modification *mod,
+ int freeit
+)
+{
+ ad_free( mod->sm_desc, 1 );
+
+ if ( mod->sm_bvalues != NULL )
+ ber_bvecfree( mod->sm_bvalues );
+
+ if( freeit )
+ free( mod );
+}
+
+void
+slap_mods_free(
+ Modifications *ml
+)
+{
+ Modifications *next;
+
+ for ( ; ml != NULL; ml = next ) {
+ next = ml->sml_next;
+
+ slap_mod_free( &ml->sml_mod, 0 );
+ free( ml );
+ }
+}
+
+void
+slap_modlist_free(
+ LDAPModList *ml
+)
+{
+ LDAPModList *next;
+
+ for ( ; ml != NULL; ml = next ) {
+ next = ml->ml_next;
+
+ if (ml->ml_type)
+ free( ml->ml_type );
+
+ if ( ml->ml_bvalues != NULL )
+ ber_bvecfree( ml->ml_bvalues );
+
+ free( ml );
+ }
+}
+++ /dev/null
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/*
- * Copyright (c) 1995 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "slap.h"
-
-#if defined( SLAPD_MONITOR_DN )
-
-int
-monitor_info(
- Entry **entry,
- const char **text )
-{
- Entry *e;
- char buf[BUFSIZ];
- struct berval val;
- struct berval *vals[2];
- int nconns, nwritewaiters, nreadwaiters;
- struct tm *ltm;
- char *p;
- char buf2[22];
- char buf3[22];
- Connection *c;
- int connindex;
- time_t currenttime;
-
- vals[0] = &val;
- vals[1] = NULL;
-
- e = (Entry *) ch_calloc( 1, sizeof(Entry) );
- e->e_attrs = NULL;
- e->e_dn = ch_strdup( SLAPD_MONITOR_DN );
- e->e_ndn = ch_strdup(SLAPD_MONITOR_DN);
- (void) dn_normalize( e->e_ndn );
- e->e_private = NULL;
-
- val.bv_val = "top";
- val.bv_len = sizeof("top")-1;
- attr_merge( e, "objectClass", vals );
-
- val.bv_val = "LDAPsubentry";
- val.bv_len = sizeof("LDAPsubentry")-1;
- attr_merge( e, "objectClass", vals );
-
- val.bv_val = "extensibleObject";
- val.bv_len = sizeof("extensibleObject")-1;
- attr_merge( e, "objectClass", vals );
-
- {
- char *rdn = ch_strdup( SLAPD_MONITOR_DN );
- val.bv_val = strchr( rdn, '=' );
-
- if( val.bv_val != NULL ) {
- *val.bv_val = '\0';
- val.bv_len = strlen( ++val.bv_val );
-
- attr_merge( e, rdn, vals );
- }
-
- free( rdn );
- }
-
- val.bv_val = (char *) Versionstr;
- if (( p = strchr( Versionstr, '\n' )) == NULL ) {
- val.bv_len = strlen( Versionstr );
- } else {
- val.bv_len = p - Versionstr;
- }
- attr_merge( e, "version", vals );
-
- sprintf( buf, "%d",
- ldap_pvt_thread_pool_backload( &connection_pool) );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "threads", vals );
-
- nconns = 0;
- nwritewaiters = 0;
- nreadwaiters = 0;
-
- /* loop through the connections */
- for ( c = connection_first( &connindex );
- c != NULL;
- c = connection_next( c, &connindex ))
- {
- nconns++;
- if ( c->c_writewaiter ) {
- nwritewaiters++;
- }
- if ( c->c_currentber != NULL ) {
- nreadwaiters++;
- }
-
- ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-
- ltm = gmtime( &c->c_starttime );
- strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
-
- ltm = gmtime( &c->c_activitytime );
- strftime( buf3, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
-
- ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
-
- sprintf( buf,
- "%ld : %ld "
- ": %ld/%ld/%ld/%ld "
- ": %ld/%ld/%ld "
- ": %s%s%s%s%s%s "
- ": %s : %s : %s "
- ": %s : %s : %s : %s ",
-
- c->c_connid,
- (long) c->c_protocol,
-
- c->c_n_ops_received, c->c_n_ops_executing,
- c->c_n_ops_pending, c->c_n_ops_completed,
-
- /* add low-level counters here */
- c->c_n_get, c->c_n_read, c->c_n_write,
-
- c->c_currentber ? "r" : "",
- c->c_writewaiter ? "w" : "",
- c->c_ops != NULL ? "x" : "",
- c->c_pending_ops != NULL ? "p" : "",
- connection_state2str( c->c_conn_state ),
- c->c_sasl_bind_in_progress ? "S" : "",
-
- c->c_cdn ? c->c_cdn : SLAPD_ANONYMOUS,
-
- c->c_listener_url,
- c->c_peer_domain,
- c->c_peer_name,
- c->c_sock_name,
-
- buf2,
- buf3
- );
-
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "connection", vals );
- }
- connection_done(c);
-
- sprintf( buf, "%d", nconns );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "currentConnections", vals );
-
- sprintf( buf, "%ld", connections_nextid() );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "totalConnections", vals );
-
- sprintf( buf, "%ld", (long) dtblsize );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "dTableSize", vals );
-
- sprintf( buf, "%d", nwritewaiters );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "writeWaiters", vals );
-
- sprintf( buf, "%d", nreadwaiters );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "readWaiters", vals );
-
- ldap_pvt_thread_mutex_lock(&num_ops_mutex);
- sprintf( buf, "%ld", num_ops_initiated );
- ldap_pvt_thread_mutex_unlock(&num_ops_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "opsInitiated", vals );
-
- ldap_pvt_thread_mutex_lock(&num_ops_mutex);
- sprintf( buf, "%ld", num_ops_completed );
- ldap_pvt_thread_mutex_unlock(&num_ops_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "opsCompleted", vals );
-
- ldap_pvt_thread_mutex_lock(&num_sent_mutex);
- sprintf( buf, "%ld", num_entries_sent );
- ldap_pvt_thread_mutex_unlock(&num_sent_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "entriesSent", vals );
-
- ldap_pvt_thread_mutex_lock(&num_sent_mutex);
- sprintf( buf, "%ld", num_refs_sent );
- ldap_pvt_thread_mutex_unlock(&num_sent_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "referencesSent", vals );
-
- ldap_pvt_thread_mutex_lock(&num_sent_mutex);
- sprintf( buf, "%ld", num_pdu_sent );
- ldap_pvt_thread_mutex_unlock(&num_sent_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "pduSent", vals );
-
- ldap_pvt_thread_mutex_lock(&num_sent_mutex);
- sprintf( buf, "%ld", num_bytes_sent );
- ldap_pvt_thread_mutex_unlock(&num_sent_mutex);
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "bytesSent", vals );
-
- currenttime = slap_get_time();
-
- ldap_pvt_thread_mutex_lock( &gmtime_mutex );
- ltm = gmtime( ¤ttime );
- strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "currenttime", vals );
-
- ltm = gmtime( &starttime );
- strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
- ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
-
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "starttime", vals );
-
- sprintf( buf, "%d", nbackends );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "nbackends", vals );
-
-#ifdef HAVE_THREAD_CONCURRENCY
- sprintf( buf, "%d", ldap_pvt_thread_get_concurrency() );
- val.bv_val = buf;
- val.bv_len = strlen( buf );
- attr_merge( e, "concurrency", vals );
-#endif
-
- *entry = e;
- return LDAP_SUCCESS;
-}
-
-#endif /* slapd_monitor_dn */
*/
LDAP_SLAPD_F (void) charray_add LDAP_P(( char ***a, const char *s ));
+LDAP_SLAPD_F (void) charray_add_n LDAP_P(( char ***a, const char *s, int l ));
LDAP_SLAPD_F (void) charray_merge LDAP_P(( char ***a, char **s ));
LDAP_SLAPD_F (void) charray_free LDAP_P(( char **array ));
LDAP_SLAPD_F (int) charray_inlist LDAP_P(( char **a, const char *s ));
LDAP_SLAPD_F (char **) charray_dup LDAP_P(( char **a ));
LDAP_SLAPD_F (char **) str2charray LDAP_P(( const char *str, const char *brkstr ));
+LDAP_SLAPD_F (int) charray_strcmp LDAP_P(( const char **a1, const char **a2 ));
+LDAP_SLAPD_F (int) charray_strcasecmp LDAP_P(( const char **a1, const char **a2 ));
+
/*
* controls.c
LDAP_SLAPD_F (int) rdn_validate LDAP_P(( const char* str ));
LDAP_SLAPD_F (char *) rdn_attr_value LDAP_P(( const char * rdn ));
LDAP_SLAPD_F (char *) rdn_attr_type LDAP_P(( const char * rdn ));
+LDAP_SLAPD_F (int) rdn_attrs LDAP_P(( const char * rdn, char ***ptypes, char ***pvals ));
LDAP_SLAPD_F (void) build_new_dn LDAP_P(( char ** new_dn,
const char *e_dn,
time_t starttime;
#endif
+/* because Versionstr is used in back-monitor */
+const char Versionstr[] = "";
+
/* bogus ../results.c */
int str2result(
char* s,
{
assert(0);
}
+
+void replog( Backend *be, Operation *op, char *dn, void *change)
+{
+ assert(0);
+}
+
+void slap_mods_free( Modifications *ml )
+{
+ assert(0);
+}