]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/Database.cpp
Security-29.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / Database.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 #ifdef __MWERKS__
20 #define _CPP_DATABASE
21 #endif
22 #include <Security/Database.h>
23
24 #include <Security/cssmerr.h>
25 #include <Security/DbContext.h>
26 #include <memory>
27
28 DatabaseManager::DatabaseManager ()
29 {
30 }
31
32 DatabaseManager::~DatabaseManager ()
33 {
34 }
35
36 Database *
37 DatabaseManager::get (const DbName &inDbName)
38 {
39 StLock<Mutex> _(mDatabaseMapLock);
40 DatabaseMap::iterator anIterator = mDatabaseMap.find (inDbName);
41 if (anIterator == mDatabaseMap.end())
42 {
43 auto_ptr<Database> aDatabase(make(inDbName));
44 mDatabaseMap.insert(DatabaseMap::value_type(aDatabase->mDbName, aDatabase.get()));
45 return aDatabase.release();
46 }
47
48 return anIterator->second;
49 }
50
51 void
52 DatabaseManager::removeIfUnused(Database &inDatabase)
53 {
54 StLock<Mutex> _(mDatabaseMapLock);
55 if (!inDatabase.hasDbContexts())
56 mDatabaseMap.erase(inDatabase.mDbName);
57 }
58
59 DbContext &
60 DatabaseManager::dbOpen(DatabaseSession &inDatabaseSession,
61 const DbName &inDbName,
62 CSSM_DB_ACCESS_TYPE inAccessRequest,
63 const AccessCredentials *inAccessCred,
64 const void *inOpenParameters)
65 {
66 Database &aDatabase = *get(inDbName);
67 try
68 {
69 return aDatabase._dbOpen(inDatabaseSession, inAccessRequest, inAccessCred, inOpenParameters);
70 }
71 catch (...)
72 {
73 removeIfUnused(aDatabase);
74 throw;
75 }
76 }
77
78 DbContext &
79 DatabaseManager::dbCreate(DatabaseSession &inDatabaseSession,
80 const DbName &inDbName,
81 const CSSM_DBINFO &inDBInfo,
82 CSSM_DB_ACCESS_TYPE inAccessRequest,
83 const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
84 const void *inOpenParameters)
85 {
86 Database &aDatabase = *get(inDbName);
87 try
88 {
89 return aDatabase._dbCreate(inDatabaseSession, inDBInfo, inAccessRequest,
90 inCredAndAclEntry, inOpenParameters);
91 }
92 catch (...)
93 {
94 removeIfUnused(aDatabase);
95 throw;
96 }
97 }
98
99 // Delete a DbContext instance created by calling dbOpen or dbCreate.
100 void
101 DatabaseManager::dbClose(DbContext &inDbContext)
102 {
103 Database &aDatabase = inDbContext.mDatabase;
104 aDatabase._dbClose(inDbContext);
105 removeIfUnused(aDatabase);
106 }
107
108 // Delete a database.
109 void
110 DatabaseManager::dbDelete(DatabaseSession &inDatabaseSession,
111 const DbName &inDbName,
112 const AccessCredentials *inAccessCred)
113 {
114 Database &aDatabase = *get(inDbName);
115 try
116 {
117 aDatabase.dbDelete(inDatabaseSession, inAccessCred);
118 }
119 catch (...)
120 {
121 removeIfUnused(aDatabase);
122 throw;
123 }
124
125 removeIfUnused(aDatabase);
126 }
127
128 // List all available databases.
129 CSSM_NAME_LIST_PTR
130 DatabaseManager::getDbNames(DatabaseSession &inDatabaseSession)
131 {
132 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
133 }
134
135 void
136 DatabaseManager::freeNameList(DatabaseSession &inDatabaseSession,
137 CSSM_NAME_LIST &inNameList)
138 {
139 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
140 }
141
142 // Start of Database implementation.
143
144 Database::Database (const DbName &inDbName)
145 : mDbName(inDbName)
146 {
147 }
148
149 Database::~Database ()
150 {
151 }
152
153 bool
154 Database::hasDbContexts()
155 {
156 StLock<Mutex> _(mDbContextSetLock);
157 return !mDbContextSet.empty();
158 }
159
160 DbContext &
161 Database::_dbOpen(DatabaseSession &inDatabaseSession,
162 CSSM_DB_ACCESS_TYPE inAccessRequest,
163 const AccessCredentials *inAccessCred,
164 const void *inOpenParameters)
165 {
166 auto_ptr<DbContext>aDbContext(makeDbContext(inDatabaseSession,
167 inAccessRequest,
168 inAccessCred,
169 inOpenParameters));
170 {
171 StLock<Mutex> _(mDbContextSetLock);
172 mDbContextSet.insert(aDbContext.get());
173 // Release the mDbContextSetLock
174 }
175
176 try
177 {
178 dbOpen(*aDbContext);
179 }
180 catch (...)
181 {
182 StLock<Mutex> _(mDbContextSetLock);
183 mDbContextSet.erase(aDbContext.get());
184 throw;
185 }
186
187 return *aDbContext.release();
188 }
189
190 DbContext &
191 Database::_dbCreate(DatabaseSession &inDatabaseSession,
192 const CSSM_DBINFO &inDBInfo,
193 CSSM_DB_ACCESS_TYPE inAccessRequest,
194 const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
195 const void *inOpenParameters)
196 {
197 auto_ptr<DbContext>aDbContext(makeDbContext(inDatabaseSession,
198 inAccessRequest,
199 (inCredAndAclEntry
200 ? AccessCredentials::optional(inCredAndAclEntry->AccessCred)
201 : NULL),
202 inOpenParameters));
203 {
204 StLock<Mutex> _(mDbContextSetLock);
205 mDbContextSet.insert(aDbContext.get());
206 // Release the mDbContextSetLock
207 }
208
209 try
210 {
211 dbCreate(*aDbContext, inDBInfo,
212 inCredAndAclEntry ? &inCredAndAclEntry->InitialAclEntry : NULL);
213 }
214 catch (...)
215 {
216 StLock<Mutex> _(mDbContextSetLock);
217 mDbContextSet.erase(aDbContext.get());
218 throw;
219 }
220
221 return *aDbContext.release();
222 }
223
224 void
225 Database::_dbClose(DbContext &dbContext)
226 {
227 StLock<Mutex> _(mDbContextSetLock);
228 mDbContextSet.erase(&dbContext);
229 if (mDbContextSet.empty())
230 dbClose();
231 }