]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/dn2id.c
error out when adding multiple olcIndex values for the same attribute (ITS#6196)
[openldap] / servers / slapd / back-bdb / dn2id.c
index a358fe0d668f167aab6ae44d7ec4dc72718895d4..2d1748c328585fa5ead21ab0487519e911e4155d 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2000-2008 The OpenLDAP Foundation.
+ * Copyright 2000-2009 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,8 +89,11 @@ bdb_dn2id_add(
        /* store it -- don't override */
        rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
        if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add 0x%lx: put failed: %s %d\n",
-                       e->e_id, db_strerror(rc), rc );
+               char buf[ SLAP_TEXT_BUFLEN ];
+               snprintf( buf, sizeof( buf ), "%s => bdb_dn2id_add dn=\"%s\" ID=0x%lx",
+                       op->o_log_prefix, e->e_name.bv_val, e->e_id );
+               Debug( LDAP_DEBUG_ANY, "%s: put failed: %s %d\n",
+                       buf, db_strerror(rc), rc );
                goto done;
        }
 
@@ -393,7 +396,8 @@ bdb_dn2idl(
 
 #ifndef        BDB_MULTIPLE_SUFFIXES
        if ( prefix == DN_SUBTREE_PREFIX
-               && ( ei->bei_id == 0 || ei->bei_parent->bei_id == 0 )) {
+               && ( ei->bei_id == 0 ||
+               ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) {
                BDB_IDL_ALL(bdb, ids);
                return 0;
        }
@@ -525,8 +529,8 @@ int hdb_fix_dn(
                }
        }
        BEI(e)->bei_modrdns = max;
-       ptr[-1] = '\0';
-       nptr[-1] = '\0';
+       if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0';
+       if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0';
 
        return 0;
 }
@@ -619,6 +623,11 @@ hdb_dn2id_add(
                                tmp[1] = eip->bei_id;
                                bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
                        }
+                       /* Handle DB with empty suffix */
+                       if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
+                               tmp[1] = eip->bei_id;
+                               bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
+                       }
                }
        }
 
@@ -718,6 +727,11 @@ func_leave:
                                tmp[1] = eip->bei_id;
                                bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
                        }
+                       /* Handle DB with empty suffix */
+                       if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
+                               tmp[1] = eip->bei_id;
+                               bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
+                       }
                }
        }
        Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
@@ -1088,7 +1102,7 @@ hdb_dn2idl_internal(
                cx->rc = cx->dbc->c_close( cx->dbc );
 done_one:
                bdb_cache_entryinfo_lock( cx->ei );
-               cx->ei->bei_state ^= CACHE_ENTRY_ONELEVEL;
+               cx->ei->bei_state &= ~CACHE_ENTRY_ONELEVEL;
                bdb_cache_entryinfo_unlock( cx->ei );
                if ( cx->rc )
                        return cx->rc;
@@ -1137,15 +1151,23 @@ gotit:
                                for ( cx->id = bdb_idl_first( save, &idcurs );
                                        cx->id != NOID;
                                        cx->id = bdb_idl_next( save, &idcurs )) {
-                                       cx->ei = bdb_cache_find_info( cx->bdb, cx->id );
-                                       if ( !cx->ei ||
-                                               ( cx->ei->bei_state & CACHE_ENTRY_NO_KIDS ))
+                                       EntryInfo *ei2;
+                                       cx->ei = NULL;
+                                       if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei,
+                                               ID_NOENTRY, NULL ))
                                                continue;
-
-                                       BDB_ID2DISK( cx->id, &cx->nid );
-                                       hdb_dn2idl_internal( cx );
-                                       if ( !BDB_IDL_IS_ZERO( cx->tmp ))
-                                               nokids = 0;
+                                       if ( cx->ei ) {
+                                               ei2 = cx->ei;
+                                               if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) {
+                                                       BDB_ID2DISK( cx->id, &cx->nid );
+                                                       hdb_dn2idl_internal( cx );
+                                                       if ( !BDB_IDL_IS_ZERO( cx->tmp ))
+                                                               nokids = 0;
+                                               }
+                                               bdb_cache_entryinfo_lock( ei2 );
+                                               ei2->bei_finders--;
+                                               bdb_cache_entryinfo_unlock( ei2 );
+                                       }
                                }
                                cx->depth--;
                                cx->op->o_tmpfree( save, cx->op->o_tmpmemctx );
@@ -1184,7 +1206,7 @@ hdb_dn2idl(
 #ifndef BDB_MULTIPLE_SUFFIXES
        if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && 
                ( ei->bei_id == 0 ||
-               ei->bei_parent->bei_id == 0 ))
+               ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len )))
        {
                BDB_IDL_ALL( bdb, ids );
                return 0;