]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/idl.c
Don't mask DB_KEYEXIST errors in bdb_idl_insert_key, let dn2id see them.
[openldap] / servers / slapd / back-bdb / idl.c
index 09f86a7ccffd1c8507975c940ef42af46d70de77..f9b99a5f63cb86cd8a98e7041fd3465029422cec 100644 (file)
@@ -248,7 +248,13 @@ bdb_idl_fetch_key(
 #ifdef BDB_IDL_MULTI
        {
                DBC *cursor;
-               ID buf[BDB_PAGESIZE*4];
+               /* buf must be large enough to grab the entire IDL in one
+                * get(), otherwise BDB 4 will leak resources on subsequent
+                * get's. We can safely call get() twice - once for the data,
+                * and once to get the DB_NOTFOUND result meaning there's
+                * no more data. See ITS#2040 for details.
+                */
+               ID buf[BDB_IDL_DB_SIZE*5];
                ID *i;
                void *ptr;
                size_t len;
@@ -444,7 +450,7 @@ bdb_idl_insert_key(
                                        err = "c_count";
                                        goto fail;
                                }
-                               if ( count >= BDB_IDL_DB_SIZE ) {
+                               if ( count >= BDB_IDL_DB_MAX ) {
                                /* No room, convert to a range */
                                        DBT key2 = *key;
 
@@ -651,9 +657,7 @@ fail:
        /* store the key */
        rc = db->put( db, tid, key, &data, 0 );
 #endif
-       if( rc == DB_KEYEXIST ) rc = 0;
-
-       if( rc != 0 ) {
+       if( rc != 0 && rc != DB_KEYEXIST ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( INDEX, ERR, 
                        "bdb_idl_insert_key: put failed: %s (%d)\n", 
@@ -1014,8 +1018,11 @@ bdb_idl_union(
        }
 
        if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) {
-over:          a[1] = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
-               a[2] = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );
+over:          ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
+               idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );
+               a[0] = NOID;
+               a[1] = ida;
+               a[2] = idb;
                return 0;
        }
 
@@ -1028,7 +1035,6 @@ over:             a[1] = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
        while( ida != NOID || idb != NOID ) {
                if ( ida < idb ) {
                        if( ++cursorc > BDB_IDL_UM_MAX ) {
-                               a[0] = NOID;
                                goto over;
                        }
                        b[cursorc] = ida;
@@ -1051,7 +1057,7 @@ over:             a[1] = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
                        idb = NOID;
                else
                        idb = b[cursorc];
-               if (b[cursorb] < idb)
+               if (cursorb <= b[0] && b[cursorb] < idb)
                        a[cursora++] = b[cursorb++];
                else {
                        a[cursora++] = idb;