- // If doing a search for all records, skip the db blob added by the CSPDL
- if (dbAttributes.recordType() == CSSM_DL_DB_RECORD_METADATA &&
- mDbCursor->recordType() == CSSM_DL_DB_RECORD_ANY)
+ Keychain &kc = *mCurrent;
+
+ Mutex* mutex = kc->getKeychainMutex();
+ StLock<Mutex> _(*mutex);
+
+ bool gotRecord;
+ try
+ {
+ // Clear out existing attributes first!
+ // (the previous iteration may have left attributes from a different schema)
+ dbAttributes.clear();
+
+ gotRecord = mDbCursor->next(&dbAttributes, NULL, uniqueId);
+ mAllFailed = false;
+ }
+ catch(const CommonError &err)
+ {
+ // Catch the last error we get and move on to the next keychain
+ // This error will be returned when we reach the end of our keychain list
+ // iff all calls to KCCursorImpl::next failed
+ status = err.osStatus();
+ gotRecord = false;
+ dbAttributes.invalidate();
+ }
+ catch(...)
+ {
+ // Catch all other errors
+ status = errSecItemNotFound;
+ gotRecord = false;
+ }
+
+ // If we did not get a record from the current keychain or the current
+ // keychain did not exist skip to the next keychain in the list.
+ if (!gotRecord)
+ {
+ ++mCurrent;
+ mDbCursor = DbCursor();
+ // we'd like to call newKeychain(mCurrent) here, but to avoid deadlock
+ // we need to drop the current keychain's mutex first. Use this silly
+ // hack to void the stack Mutex object.
+ mIsNewKeychain = true;