X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_cdsa_plugin/lib/Database.cpp diff --git a/libsecurity_cdsa_plugin/lib/Database.cpp b/libsecurity_cdsa_plugin/lib/Database.cpp new file mode 100644 index 00000000..2343108b --- /dev/null +++ b/libsecurity_cdsa_plugin/lib/Database.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +#ifdef __MWERKS__ +#define _CPP_DATABASE +#endif +#include +#include +#include +#include + +DatabaseManager::DatabaseManager () +{ +} + +DatabaseManager::~DatabaseManager () +{ +} + +Database * +DatabaseManager::get (const DbName &inDbName) +{ + StLock _(mDatabaseMapLock); + DatabaseMap::iterator anIterator = mDatabaseMap.find (inDbName); + if (anIterator == mDatabaseMap.end()) + { + auto_ptr aDatabase(make(inDbName)); + mDatabaseMap.insert(DatabaseMap::value_type(aDatabase->mDbName, aDatabase.get())); + return aDatabase.release(); + } + + return anIterator->second; +} + +void +DatabaseManager::removeIfUnused(Database &inDatabase) +{ + StLock _(mDatabaseMapLock); + if (!inDatabase.hasDbContexts()) { + mDatabaseMap.erase(inDatabase.mDbName); + delete &inDatabase; + } +} + +DbContext & +DatabaseManager::dbOpen(DatabaseSession &inDatabaseSession, + const DbName &inDbName, + CSSM_DB_ACCESS_TYPE inAccessRequest, + const AccessCredentials *inAccessCred, + const void *inOpenParameters) +{ + Database &aDatabase = *get(inDbName); + try + { + return aDatabase._dbOpen(inDatabaseSession, inAccessRequest, inAccessCred, inOpenParameters); + } + catch (...) + { + removeIfUnused(aDatabase); + throw; + } +} + +DbContext & +DatabaseManager::dbCreate(DatabaseSession &inDatabaseSession, + const DbName &inDbName, + const CSSM_DBINFO &inDBInfo, + CSSM_DB_ACCESS_TYPE inAccessRequest, + const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry, + const void *inOpenParameters) +{ + Database &aDatabase = *get(inDbName); + try + { + return aDatabase._dbCreate(inDatabaseSession, inDBInfo, inAccessRequest, + inCredAndAclEntry, inOpenParameters); + } + catch (...) + { + removeIfUnused(aDatabase); + throw; + } +} + +// Delete a DbContext instance created by calling dbOpen or dbCreate. +void +DatabaseManager::dbClose(DbContext &inDbContext) +{ + Database &aDatabase = inDbContext.mDatabase; + aDatabase._dbClose(inDbContext); + removeIfUnused(aDatabase); +} + +// Delete a database. +void +DatabaseManager::dbDelete(DatabaseSession &inDatabaseSession, + const DbName &inDbName, + const AccessCredentials *inAccessCred) +{ + Database &aDatabase = *get(inDbName); + try + { + aDatabase.dbDelete(inDatabaseSession, inAccessCred); + } + catch (...) + { + removeIfUnused(aDatabase); + throw; + } + + removeIfUnused(aDatabase); +} + +// List all available databases. +CSSM_NAME_LIST_PTR +DatabaseManager::getDbNames(DatabaseSession &inDatabaseSession) +{ + CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); +} + +void +DatabaseManager::freeNameList(DatabaseSession &inDatabaseSession, + CSSM_NAME_LIST &inNameList) +{ + CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); +} + +// Start of Database implementation. + +Database::Database (const DbName &inDbName) +: mDbName(inDbName) +{ +} + +Database::~Database () +{ +} + +bool +Database::hasDbContexts() +{ + StLock _(mDbContextSetLock); + return !mDbContextSet.empty(); +} + +DbContext & +Database::_dbOpen(DatabaseSession &inDatabaseSession, + CSSM_DB_ACCESS_TYPE inAccessRequest, + const AccessCredentials *inAccessCred, + const void *inOpenParameters) +{ + auto_ptraDbContext(makeDbContext(inDatabaseSession, + inAccessRequest, + inAccessCred, + inOpenParameters)); + { + StLock _(mDbContextSetLock); + mDbContextSet.insert(aDbContext.get()); + // Release the mDbContextSetLock + } + + try + { + dbOpen(*aDbContext); + } + catch (...) + { + StLock _(mDbContextSetLock); + mDbContextSet.erase(aDbContext.get()); + throw; + } + + return *aDbContext.release(); +} + +DbContext & +Database::_dbCreate(DatabaseSession &inDatabaseSession, + const CSSM_DBINFO &inDBInfo, + CSSM_DB_ACCESS_TYPE inAccessRequest, + const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry, + const void *inOpenParameters) +{ + auto_ptraDbContext(makeDbContext(inDatabaseSession, + inAccessRequest, + (inCredAndAclEntry + ? AccessCredentials::optional(inCredAndAclEntry->AccessCred) + : NULL), + inOpenParameters)); + { + StLock _(mDbContextSetLock); + mDbContextSet.insert(aDbContext.get()); + // Release the mDbContextSetLock + } + + try + { + dbCreate(*aDbContext, inDBInfo, + inCredAndAclEntry ? &inCredAndAclEntry->InitialAclEntry : NULL); + } + catch (...) + { + StLock _(mDbContextSetLock); + mDbContextSet.erase(aDbContext.get()); + throw; + } + + return *aDbContext.release(); +} + +void +Database::_dbClose(DbContext &dbContext) +{ + StLock _(mDbContextSetLock); + mDbContextSet.erase(&dbContext); + if (mDbContextSet.empty()) + dbClose(); +}