]> git.sur5r.net Git - openldap/commitdiff
Bring in LDBM error handling fixes
authorKurt Zeilenga <kurt@openldap.org>
Sun, 22 Jul 2001 04:28:28 +0000 (04:28 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sun, 22 Jul 2001 04:28:28 +0000 (04:28 +0000)
20 files changed:
CHANGES
servers/slapd/Makefile.in
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/cache.c
servers/slapd/back-ldbm/dn2id.c
servers/slapd/back-ldbm/filterindex.c
servers/slapd/back-ldbm/id2entry.c
servers/slapd/back-ldbm/idl.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/back-ldbm/nextid.c
servers/slapd/back-ldbm/passwd.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-ldbm/tools.c
servers/slapd/dn.c
servers/slapd/libslapd.dsp
servers/slapd/modify.c
servers/slapd/mods.c [new file with mode: 0644]
servers/slapd/monitor.c [deleted file]
servers/slapd/proto-slap.h
servers/slapd/tools/mimic.c

diff --git a/CHANGES b/CHANGES
index 43b96a7e10afd82d22c8082e8535eced7e84ec73..a8a7b89760d6f3c7e07e65d49eaec343d5ebe46d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,12 +6,14 @@ OpenLDAP 2.0.12 Engineering
        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
index b2468a28a9bc7f7ce73bbf439417157b6dc04809..2e42c9f1e57a7f8e7138f0e49a248d48f73a0c70 100644 (file)
@@ -17,8 +17,9 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                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 \
@@ -28,8 +29,9 @@ OBJS  = main.o daemon.o connection.o search.o filter.o add.o charray.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
index a844bf90ce53598bd6bb26b4a76ba0a1228a4bc7..1d1951913cd4f7c8e801e15a6e9a64d9b9739b96 100644 (file)
@@ -28,7 +28,8 @@ ldbm_back_add(
        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];
@@ -36,12 +37,15 @@ ldbm_back_add(
 
        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 );
        }
@@ -54,6 +58,7 @@ ldbm_back_add(
                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 );
@@ -94,8 +99,10 @@ ldbm_back_add(
                        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 );
@@ -119,6 +126,7 @@ ldbm_back_add(
 
                        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 );
 
@@ -135,6 +143,7 @@ ldbm_back_add(
                        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 );
 
@@ -153,6 +162,7 @@ ldbm_back_add(
 
                        Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
                            0, 0 );
+
                        send_ldap_result( conn, op, LDAP_REFERRAL,
                            matched_dn, NULL, refs, NULL );
 
@@ -175,6 +185,7 @@ ldbm_back_add(
                                        pdn == NULL ? "suffix" : "entry at root",
                                        0, 0 );
 
+
                        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                            NULL, NULL, NULL, NULL );
 
@@ -190,9 +201,7 @@ ldbm_back_add(
                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 ); 
@@ -206,6 +215,7 @@ ldbm_back_add(
                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 );
 
@@ -231,6 +241,7 @@ ldbm_back_add(
                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 );
@@ -244,6 +255,7 @@ ldbm_back_add(
        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 );
 
@@ -254,6 +266,8 @@ ldbm_back_add(
        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 );
 
@@ -264,7 +278,10 @@ ldbm_back_add(
        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 );
 
@@ -273,7 +290,12 @@ ldbm_back_add(
 
        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) {
@@ -287,7 +309,8 @@ return_results:;
        }
 
        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 );
        }
 
index c1ad17102017dafd92da45b292a15c5d6ec41020..10f2d7061caa2608f4584f20616c9d3959073d58 100644 (file)
@@ -29,9 +29,10 @@ typedef struct ldbm_entry_info {
        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;
@@ -113,6 +114,23 @@ cache_entry_private_init( Entry*e )
        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 )
 {
@@ -129,7 +147,7 @@ void
 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 );
@@ -141,7 +159,18 @@ cache_return_entry_rw( Cache *cache, Entry *e, int rw )
        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 */
@@ -162,7 +191,9 @@ cache_return_entry_rw( Cache *cache, Entry *e, int rw )
 
                } 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 );
@@ -439,14 +470,33 @@ cache_find_entry_dn2id(
     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 */
@@ -481,7 +531,7 @@ try_again:
 
                        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;
@@ -496,7 +546,7 @@ 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 */
@@ -505,8 +555,6 @@ try_again:
                id = NOID;
        }
 
-       free(e.e_ndn);
-
        return( id );
 }
 
index 81f1154a855a2f0e4d29843313e8663c5e23ea0f..0430a3f64b88dd55d5b7841b0722724eeac9868b 100644 (file)
@@ -95,31 +95,38 @@ dn2id_add(
        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 );
@@ -136,37 +143,42 @@ dn2id(
 
        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 );
@@ -175,13 +187,13 @@ dn2idl(
        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 );
 }
 
 
@@ -287,13 +299,16 @@ dn2entry_rw(
                *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);
index dea9d89f353361535ca3c1bdc841f32be491a41a..04c1890670ce98534e0a73bdad85525028ad11df 100644 (file)
@@ -44,12 +44,24 @@ filter_candidates(
        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:
index f38802126deecc62dc63e000b8e4529a1d81c2d0..40aaa60cb33b4d7fb513c7121bc7da98381700ff 100644 (file)
@@ -176,5 +176,9 @@ id2entry_rw( Backend *be, ID id, int rw )
        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 );
 }
index e189a5bd6bbc1f6f1dbddcae976524a2d626bdde..81f1954f57be0d1b285aba8b645422ad092bd2f0 100644 (file)
@@ -65,10 +65,14 @@ ID_BLOCK    *
 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 );
 }
index ac78abf6b1893266e55d6f5439e697c0b9ede950..249c7f94aa7428f18ffb12f11c8448aa9684944a 100644 (file)
@@ -51,27 +51,25 @@ ldbm_back_modrdn(
        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",
@@ -121,7 +119,7 @@ ldbm_back_modrdn(
        }
 
        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,
@@ -129,8 +127,7 @@ ldbm_back_modrdn(
                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.
                 */
@@ -138,6 +135,7 @@ ldbm_back_modrdn(
                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 );
 
@@ -150,6 +148,7 @@ ldbm_back_modrdn(
                {
                        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;
@@ -158,18 +157,18 @@ ldbm_back_modrdn(
                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;
@@ -181,7 +180,6 @@ ldbm_back_modrdn(
                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 */
@@ -200,12 +198,12 @@ ldbm_back_modrdn(
                        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? */
 
@@ -213,6 +211,7 @@ ldbm_back_modrdn(
                        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;
@@ -221,7 +220,7 @@ ldbm_back_modrdn(
                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 ) )
@@ -229,6 +228,7 @@ ldbm_back_modrdn(
                        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;
@@ -239,6 +239,7 @@ ldbm_back_modrdn(
                        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 );
 
@@ -265,10 +266,8 @@ ldbm_back_modrdn(
        }
        
        /* 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 );
 
@@ -283,8 +282,10 @@ ldbm_back_modrdn(
        }
 
        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;
        }
@@ -293,144 +294,136 @@ ldbm_back_modrdn(
               "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 );
@@ -477,6 +470,7 @@ ldbm_back_modrdn(
            
            goto return_results;
        }
+       rc = -1;
        
        (void) cache_update_entry( &li->li_cache, e );
 
@@ -486,7 +480,6 @@ ldbm_back_modrdn(
 
        /* 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;
@@ -495,6 +488,7 @@ ldbm_back_modrdn(
        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 );
@@ -504,12 +498,15 @@ return_results:
        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 );
@@ -532,5 +529,10 @@ return_results:
 
        /* 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 );
 }
index 2ea984a852eafe51c3cacba92c49ca91385ecf52..76bd0e0a15b9d0e59691c4d9d671d0941a12278d 100644 (file)
 #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 );
@@ -78,49 +80,58 @@ next_id_write( Backend *be, ID id )
 
        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 );
 }
index 563e2c89c2f51fb17167e8c1f1d87c329c4c6f06..4f2e9065374413b9189f22ad99474e407a03c54a 100644 (file)
@@ -135,12 +135,14 @@ ldbm_back_exop_passwd(
                        *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:
index 6ac74e95f9d5105b0e621ca6bea2081677769a69..3d3e22b87e4ee73c9c26dba75869b5391b47b0e1 100644 (file)
@@ -51,8 +51,10 @@ int cache_update_entry LDAP_P(( Cache *cache, Entry *e ));
 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 ));
@@ -69,14 +71,15 @@ void ldbm_cache_flush_all LDAP_P(( Backend *be ));
 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 ));
@@ -208,9 +211,9 @@ int ldbm_modify_internal LDAP_P((Backend *be,
  * 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
index c630e3e58086d613dadfe28913e4c67a66029bfe..b5f31005ca70d4227ccbefa2b0aa3c644c246df3 100644 (file)
@@ -156,7 +156,7 @@ ID ldbm_tool_entry_put(
        assert( slapMode & SLAP_TOOL_MODE );
        assert( id2entry != NULL );
 
-       if( next_id_get( be ) == NOID ) {
+       if ( next_id_get( be, &id ) || id == NOID ) {
                return NOID;
        }
 
@@ -165,7 +165,11 @@ ID ldbm_tool_entry_put(
        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",
@@ -246,7 +250,9 @@ int ldbm_tool_sync( BackendDB *be )
        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;
index a5ff45d71b808bde10fccca58a1c7ac20506117b..2fe6ca18686161e8a7303fcafaf44182084d45b4 100644 (file)
@@ -460,10 +460,121 @@ rdn_attr_value( const char * rdn )
 }
 
 
-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 );
 }
 
 
index 700b29c4bc44c1ea9a3736772c088a259a06bdcb..28c189e59b6d8b1143b0e10cbd9bd5f9caa0b221 100644 (file)
@@ -184,10 +184,6 @@ SOURCE=.\config.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\configinfo.c
-# End Source File
-# Begin Source File
-
 SOURCE=.\connection.c
 # End Source File
 # Begin Source File
@@ -248,7 +244,7 @@ SOURCE=.\modrdn.c
 # End Source File
 # Begin Source File
 
-SOURCE=.\monitor.c
+SOURCE=.\mods.c
 # End Source File
 # Begin Source File
 
index 6334a7679cc951bfa60cc58d3092ee6e02c1f23e..7e3c90890c3fb438090d32bf24a8008de7531c9c 100644 (file)
@@ -511,53 +511,3 @@ int slap_mods_opattrs(
        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 );
-       }
-}
diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c
new file mode 100644 (file)
index 0000000..7b59cc5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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 );
+       }
+}
diff --git a/servers/slapd/monitor.c b/servers/slapd/monitor.c
deleted file mode 100644 (file)
index 1c337c5..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/* $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( &currenttime );
-       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 */
index c0e9a5f6f9a179fd667e0fc4030b4a770f8f25b5..64c8018925c1464f3138c3a91a4769572c8c9920 100644 (file)
@@ -231,11 +231,15 @@ LDAP_SLAPD_F (void) ch_free LDAP_P(( void * ));
  */
 
 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
@@ -306,6 +310,7 @@ LDAP_SLAPD_F (int) dn_issuffix LDAP_P(( const char *dn, const char *suffix ));
 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,
index 0ac35c990d025e783ddac397c22ffe8617d95055..3f18906061f7017ffb6cf2b5d7b6d92e6dba6e4e 100644 (file)
@@ -17,6 +17,9 @@
 time_t starttime;
 #endif
 
+/* because Versionstr is used in back-monitor */
+const char Versionstr[] = "";
+
 /* bogus ../results.c */
 int str2result(
        char* s,
@@ -155,3 +158,13 @@ void connection2anonymous( Connection *c )
 {
        assert(0);
 }
+
+void replog( Backend *be, Operation *op, char *dn, void *change)
+{
+       assert(0);
+}
+
+void slap_mods_free( Modifications *ml )
+{
+       assert(0);
+}