Maybe I haven't described the situation correctly: The database was used for managing user accounts (via nss_ldap). The database seems to had three corrupted entries in the middle (good entries were following after that). The command "getent passwd" i.e. still listed all users except those three with corrupted entries, but export via slapcat and reimport of the data would have led to loss of many more accounts. Lossing half your data is not the expected behaviour for a tool, which should list all the existing (or at least somehow readable) database entries.
I'm not questioning the importance of the data slapcat couldn't export.
The important point is that slapcat cancelled the export at the first corrupted database entry and didn't even try to get to the non-corrupted database entries (which were seen by the other LDAP-tools).
This is not correct. Slapcat tries. It asks the underlying backend to provide the subsequent entries. If the underlying database fails, there's little slapcat can do.
It didn't even try in "continuation" mode, so there was no way to rescue all the readable data via slapcat.
I've tested slapcat in continuation mode by forcibly having be_entry_get() return NULL, and it works as expected: it continues to the next one, as soon as be_entry_next() is able to return a valid ID. if it can't, then anything you'd get from be_entry_next() with an arbitrary ID is unreliable.
For slapcat all entries occuring after the first corrupt entry were lost. As the remaining good entries were still accessible and visible via the other tools communicating with slapd via the port 389, the expected behaviour for slapcat would have been to try harder to ignore the damaged entries and to recover the remaining readable entries after them. Maybe slapcat really failed to extract the next entries id, but in "continuation"-mode it should try hard to workaround any errors caused by non-readable entries. In case of an non-readable entry my patch continues stupidly incrementing the id by 1 and trying to read that entry. As soon as it can extract an entry, it continues processing.
If by "try hard" you mean that any garbage coming out of a corrupted database would be fine for you, then you can fix your patch by having it stop when id == NOID. To me, it sounds a bit too hard. What about recovering the database first, did you try?
p.