X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..84aacf34eae6543be9f0280b2015385f91e5c2c6:/OSX/libsecurity_cdsa_client/lib/dlclient.cpp diff --git a/OSX/libsecurity_cdsa_client/lib/dlclient.cpp b/OSX/libsecurity_cdsa_client/lib/dlclient.cpp index 882fde1e..3fb96df8 100644 --- a/OSX/libsecurity_cdsa_client/lib/dlclient.cpp +++ b/OSX/libsecurity_cdsa_client/lib/dlclient.cpp @@ -24,6 +24,7 @@ #include #include #include +#include using namespace CssmClient; @@ -194,6 +195,7 @@ DbImpl::close() void DbImpl::activate() { + StLock _(mActivateMutex); if (!mActive) { if (mDbInfo) @@ -472,6 +474,88 @@ void DbImpl::setBatchMode(Boolean mode, Boolean rollback) } } +uint32 DbImpl::dbBlobVersion() { + uint32 dbBlobVersion = 0; + uint32* dbBlobVersionPtr = &dbBlobVersion; + + // We only have a blob version if we're an apple CSPDL + if(dl()->guid() == gGuidAppleCSPDL) { + check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_GET_BLOB_VERSION, NULL, (void**) &dbBlobVersionPtr)); + } else { + secnotice("integrity", "Non-Apple CSPDL keychains don't have keychain versions"); + } + return dbBlobVersion; +} + +uint32 DbImpl::recodeDbToVersion(uint32 version) { + uint32 newDbVersion; + uint32* newDbVersionPtr = &newDbVersion; + check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_RECODE_TO_BLOB_VERSION, &version, (void**) &newDbVersionPtr)); + return newDbVersion; +} + +void DbImpl::recodeFinished() { + check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_RECODE_FINISHED, NULL, NULL)); +} + +void DbImpl::takeFileLock() { + passThrough(CSSM_APPLECSPDL_DB_TAKE_FILE_LOCK, NULL, NULL); +} + +void DbImpl::releaseFileLock(bool success) { + passThrough(CSSM_APPLECSPDL_DB_RELEASE_FILE_LOCK, &success, NULL); +} + +void DbImpl::makeBackup() { + passThrough(CSSM_APPLECSPDL_DB_MAKE_BACKUP, NULL, NULL); +} + +void DbImpl::makeCopy(const char* path) { + passThrough(CSSM_APPLECSPDL_DB_MAKE_COPY, path, NULL); +} + +void DbImpl::deleteFile() { + passThrough(CSSM_APPLECSPDL_DB_DELETE_FILE, NULL, NULL); +} + +void DbImpl::transferTo(const DLDbIdentifier& dldbidentifier) { + if (dldbidentifier.ssuid().subserviceType() & CSSM_SERVICE_CSP) { + // if we're an Apple CSPDL, do the fancy transfer: + // clone the file, clone the db, remove the original file + string oldPath = name(); + + CSSM_DB_HANDLE dbhandle; + passThrough(CSSM_APPLECSPDL_DB_CLONE, &dldbidentifier, &dbhandle); + + mDbName = dldbidentifier.dbName(); + mHandle.DBHandle = dbhandle; + + unlink(oldPath.c_str()); + + // Don't cache this name + if (mNameFromHandle) { + allocator().free(mNameFromHandle); + mNameFromHandle = NULL; + } + } else { + // if we're not an Apple CSPDL, just call rename + this->rename(dldbidentifier.dbName()); + } +} + + +// cloneTo only makes sense if you're on an Apple CSPDL +Db DbImpl::cloneTo(const DLDbIdentifier& dldbidentifier) { + CSSM_DB_HANDLE dbhandle; + passThrough(CSSM_APPLECSPDL_DB_CLONE, &dldbidentifier, &dbhandle); + + // This is the only reasonable way to make a SSDbImpl at this layer. + CssmClient::Db db(dl(), dldbidentifier.dbName(), dldbidentifier.dbLocation()); + db->mHandle.DBHandle = dbhandle; + + return db; +} + // // DbCursorMaker // @@ -544,7 +628,6 @@ CSSM_HANDLE Db::dlGetFirst(const CSSM_QUERY &query, CSSM_DB_RECORD_ATTRIBUTE_DAT return CSSM_INVALID_HANDLE; default: CssmError::throwMe(rc); - return CSSM_INVALID_HANDLE; // placebo } } @@ -559,7 +642,6 @@ bool Db::dlGetNext(CSSM_HANDLE query, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, return false; default: CssmError::throwMe(rc); - return false; // placebo } } @@ -903,3 +985,34 @@ DbAttributes::DbAttributes(const Db &db, uint32 capacity, Allocator &allocator) : CssmAutoDbRecordAttributeData(capacity, db->allocator(), allocator) { } + +void DbAttributes::updateWithDbAttributes(DbAttributes* newValues) { + if(!newValues) { + return; + } + + canonicalize(); + newValues->canonicalize(); + + updateWith(newValues); +} + +void +DbAttributes::canonicalize() { + for(int i = 0; i < size(); i++) { + CssmDbAttributeData& data = attributes()[i]; + CssmDbAttributeInfo& datainfo = data.info(); + + // Calling Schema::attributeInfo is the best way to canonicalize. + // There's no way around the try-catch structure, since it throws if it + // can't find something. + + try { + if(datainfo.nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER) { + data.info() = Security::KeychainCore::Schema::attributeInfo(datainfo.intName()); + } + } catch(...) { + // Don't worry about it + } + } +}