2  * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 
   4  * The contents of this file constitute Original Code as defined in and are 
   5  * subject to the Apple Public Source License Version 1.2 (the 'License'). 
   6  * You may not use this file except in compliance with the License. Please obtain 
   7  * a copy of the License at http://www.apple.com/publicsource and read it before 
  10  * This Original Code and all software distributed under the License are 
  11  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 
  12  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 
  13  * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
  14  * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 
  15  * specific language governing rights and limitations under the License. 
  22 #include <security_cdsa_plugin/Database.h> 
  23 #include <Security/cssmerr.h> 
  24 #include <security_cdsa_plugin/DbContext.h> 
  27 DatabaseManager::DatabaseManager () 
  31 DatabaseManager::~DatabaseManager () 
  36 DatabaseManager::get (const DbName 
&inDbName
) 
  38     StLock
<Mutex
> _(mDatabaseMapLock
); 
  39     DatabaseMap::iterator anIterator 
= mDatabaseMap
.find (inDbName
); 
  40     if (anIterator 
== mDatabaseMap
.end()) 
  42         auto_ptr
<Database
> aDatabase(make(inDbName
)); 
  43         mDatabaseMap
.insert(DatabaseMap::value_type(aDatabase
->mDbName
, aDatabase
.get())); 
  44         return aDatabase
.release(); 
  47     return anIterator
->second
; 
  51 DatabaseManager::removeIfUnused(Database 
&inDatabase
) 
  53     StLock
<Mutex
> _(mDatabaseMapLock
); 
  54     if (!inDatabase
.hasDbContexts()) { 
  55         mDatabaseMap
.erase(inDatabase
.mDbName
); 
  61 DatabaseManager::dbOpen(DatabaseSession 
&inDatabaseSession
, 
  62                         const DbName 
&inDbName
, 
  63                         CSSM_DB_ACCESS_TYPE inAccessRequest
, 
  64                         const AccessCredentials 
*inAccessCred
, 
  65                         const void *inOpenParameters
) 
  67     Database 
&aDatabase 
= *get(inDbName
); 
  70         return aDatabase
._dbOpen(inDatabaseSession
, inAccessRequest
, inAccessCred
, inOpenParameters
); 
  74         removeIfUnused(aDatabase
); 
  80 DatabaseManager::dbCreate(DatabaseSession 
&inDatabaseSession
, 
  81                           const DbName 
&inDbName
, 
  82                           const CSSM_DBINFO 
&inDBInfo
, 
  83                           CSSM_DB_ACCESS_TYPE inAccessRequest
, 
  84                           const CSSM_RESOURCE_CONTROL_CONTEXT 
*inCredAndAclEntry
, 
  85                           const void *inOpenParameters
) 
  87     Database 
&aDatabase 
= *get(inDbName
); 
  90         return aDatabase
._dbCreate(inDatabaseSession
, inDBInfo
, inAccessRequest
, 
  91                                    inCredAndAclEntry
, inOpenParameters
); 
  95         removeIfUnused(aDatabase
); 
 100 // Delete a DbContext instance created by calling dbOpen or dbCreate. 
 102 DatabaseManager::dbClose(DbContext 
&inDbContext
) 
 104     Database 
&aDatabase 
= inDbContext
.mDatabase
; 
 105     aDatabase
._dbClose(inDbContext
); 
 106     removeIfUnused(aDatabase
); 
 109 // Delete a database. 
 111 DatabaseManager::dbDelete(DatabaseSession 
&inDatabaseSession
, 
 112                           const DbName 
&inDbName
, 
 113                           const AccessCredentials 
*inAccessCred
) 
 115     Database 
&aDatabase 
= *get(inDbName
); 
 118         aDatabase
.dbDelete(inDatabaseSession
, inAccessCred
); 
 122         removeIfUnused(aDatabase
); 
 126     removeIfUnused(aDatabase
); 
 129 // List all available databases. 
 131 DatabaseManager::getDbNames(DatabaseSession 
&inDatabaseSession
) 
 133     CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
); 
 137 DatabaseManager::freeNameList(DatabaseSession 
&inDatabaseSession
, 
 138                   CSSM_NAME_LIST 
&inNameList
) 
 140     CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
); 
 143 // Start of Database implementation. 
 145 Database::Database (const DbName 
&inDbName
) 
 150 Database::~Database () 
 155 Database::hasDbContexts() 
 157     StLock
<Mutex
> _(mDbContextSetLock
); 
 158     return !mDbContextSet
.empty(); 
 162 Database::_dbOpen(DatabaseSession 
&inDatabaseSession
, 
 163                   CSSM_DB_ACCESS_TYPE inAccessRequest
, 
 164                   const AccessCredentials 
*inAccessCred
, 
 165                   const void *inOpenParameters
) 
 167     auto_ptr
<DbContext
>aDbContext(makeDbContext(inDatabaseSession
, 
 172         StLock
<Mutex
> _(mDbContextSetLock
); 
 173         mDbContextSet
.insert(aDbContext
.get()); 
 174         // Release the mDbContextSetLock 
 183         StLock
<Mutex
> _(mDbContextSetLock
); 
 184         mDbContextSet
.erase(aDbContext
.get()); 
 188     return *aDbContext
.release(); 
 192 Database::_dbCreate(DatabaseSession 
&inDatabaseSession
, 
 193                     const CSSM_DBINFO 
&inDBInfo
, 
 194                     CSSM_DB_ACCESS_TYPE inAccessRequest
, 
 195                     const CSSM_RESOURCE_CONTROL_CONTEXT 
*inCredAndAclEntry
, 
 196                     const void *inOpenParameters
) 
 198     auto_ptr
<DbContext
>aDbContext(makeDbContext(inDatabaseSession
, 
 201                                                                                                  ? AccessCredentials::optional(inCredAndAclEntry
->AccessCred
) 
 205         StLock
<Mutex
> _(mDbContextSetLock
); 
 206         mDbContextSet
.insert(aDbContext
.get()); 
 207         // Release the mDbContextSetLock 
 212         dbCreate(*aDbContext
, inDBInfo
, 
 213                  inCredAndAclEntry 
? &inCredAndAclEntry
->InitialAclEntry 
: NULL
); 
 217         StLock
<Mutex
> _(mDbContextSetLock
); 
 218         mDbContextSet
.erase(aDbContext
.get()); 
 222     return *aDbContext
.release(); 
 226 Database::_dbClose(DbContext 
&dbContext
) 
 228     StLock
<Mutex
> _(mDbContextSetLock
); 
 229     mDbContextSet
.erase(&dbContext
); 
 230     if (mDbContextSet
.empty())