]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/DatabaseSession.cpp
Security-54.1.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / DatabaseSession.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 //
20 // DatabaseSession.cpp - DL Session.
21 //
22 #ifdef __MWERKS__
23 #define _CPP_DATABASESESSION
24 #endif
25 #include <Security/DatabaseSession.h>
26
27 #include <Security/Database.h>
28 #include <Security/DbContext.h>
29 #include <memory>
30 #include <Security/debugging.h>
31
32 /* log open/close events */
33 #define DOCDebug(args...) debug("DBOpen", ## args)
34
35
36 using namespace std;
37
38 //
39 // Session constructor
40 //
41 DatabaseSession::DatabaseSession(DatabaseManager &inDatabaseManager)
42 : mDatabaseManager(inDatabaseManager)
43 {
44 }
45
46 DatabaseSession::~DatabaseSession()
47 {
48 }
49
50
51 // Utility functions
52 void
53 DatabaseSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList)
54 {
55 outNameList = mDatabaseManager.getDbNames (*this);
56 }
57
58
59 void
60 DatabaseSession::FreeNameList(CSSM_NAME_LIST &inNameList)
61 {
62 mDatabaseManager.freeNameList (*this, inNameList);
63 }
64
65
66 void
67 DatabaseSession::DbDelete(const char *inDbName,
68 const CSSM_NET_ADDRESS *inDbLocation,
69 const AccessCredentials *inAccessCred)
70 {
71 // The databaseManager will notify all its DbContext instances
72 // that the database is question is being deleted.
73 mDatabaseManager.dbDelete(*this, DbName(inDbName, CssmNetAddress::optional(inDbLocation)), inAccessCred);
74 }
75
76 // DbContext creation and destruction.
77 void
78 DatabaseSession::DbCreate(const char *inDbName,
79 const CSSM_NET_ADDRESS *inDbLocation,
80 const CSSM_DBINFO &inDBInfo,
81 CSSM_DB_ACCESS_TYPE inAccessRequest,
82 const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
83 const void *inOpenParameters,
84 CSSM_DB_HANDLE &outDbHandle)
85 {
86 outDbHandle = CSSM_INVALID_HANDLE; // CDSA 2.0 says to set this if we fail
87 outDbHandle = insertDbContext(mDatabaseManager.dbCreate(*this,
88 DbName(inDbName, CssmNetAddress::optional(inDbLocation)),
89 inDBInfo,
90 inAccessRequest,
91 inCredAndAclEntry,
92 inOpenParameters));
93
94 }
95
96 void
97 DatabaseSession::DbOpen(const char *inDbName,
98 const CSSM_NET_ADDRESS *inDbLocation,
99 CSSM_DB_ACCESS_TYPE inAccessRequest,
100 const AccessCredentials *inAccessCred,
101 const void *inOpenParameters,
102 CSSM_DB_HANDLE &outDbHandle)
103 {
104 DOCDebug("DatabaseSession::DbOpen: dbName %s", inDbName);
105 outDbHandle = CSSM_INVALID_HANDLE; // CDSA 2.0 says to set this if we fail
106 outDbHandle = insertDbContext(mDatabaseManager.dbOpen(*this,
107 DbName(inDbName, CssmNetAddress::optional(inDbLocation)),
108 inAccessRequest,
109 inAccessCred,
110 inOpenParameters));
111 }
112
113 CSSM_DB_HANDLE
114 DatabaseSession::insertDbContext(DbContext &inDbContext)
115 {
116 CSSM_DB_HANDLE aDbHandle;
117 try
118 {
119 aDbHandle = inDbContext.handle ();
120 StLock<Mutex> _(mDbContextMapLock);
121 mDbContextMap.insert(DbContextMap::value_type(aDbHandle, &inDbContext));
122 }
123 catch (...)
124 {
125 // Close the context
126 mDatabaseManager.dbClose(inDbContext);
127 throw;
128 }
129
130 return aDbHandle;
131 }
132
133 DbContext &
134 DatabaseSession::findDbContext(CSSM_DB_HANDLE inDbHandle)
135 {
136 StLock<Mutex> _(mDbContextMapLock);
137 DbContextMap::iterator it = mDbContextMap.find(inDbHandle);
138 if (it == mDbContextMap.end())
139 CssmError::throwMe(CSSM_ERRCODE_INVALID_DB_HANDLE);
140 return *it->second;
141 }
142
143 void
144 DatabaseSession::closeAll()
145 {
146 StLock<Mutex> _(mDbContextMapLock);
147 for (DbContextMap::iterator it = mDbContextMap.begin();
148 it != mDbContextMap.end();
149 it++)
150 {
151 DbContext *aDbContext = it->second;
152 try
153 {
154 mDatabaseManager.dbClose(*aDbContext);
155 // This is done by the database itself which owns the context.
156 //delete aDbContext;
157 }
158 catch (...)
159 {
160 // Ignore exceptions since we want to close as many DBs as possible.
161 // XXX @@@ log an error or something.
162 }
163 }
164
165 mDbContextMap.clear();
166 }
167
168 // Operations using DbContext instances.
169 void
170 DatabaseSession::DbClose(CSSM_DB_HANDLE inDbHandle)
171 {
172 StLock<Mutex> _(mDbContextMapLock);
173 DOCDebug("DatabaseSession::Close");
174 DbContextMap::iterator it = mDbContextMap.find(inDbHandle);
175 if (it == mDbContextMap.end())
176 CssmError::throwMe(CSSM_ERRCODE_INVALID_DB_HANDLE);
177 auto_ptr<DbContext> aDbContext(it->second);
178 mDbContextMap.erase(it);
179 mDatabaseManager.dbClose(*aDbContext);
180 }
181
182 void
183 DatabaseSession::CreateRelation(CSSM_DB_HANDLE inDbHandle,
184 CSSM_DB_RECORDTYPE inRelationID,
185 const char *inRelationName,
186 uint32 inNumberOfAttributes,
187 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
188 uint32 inNumberOfIndexes,
189 const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
190 {
191 DbContext &aDbContext = findDbContext(inDbHandle);
192 return aDbContext.mDatabase.createRelation(aDbContext, inRelationID, inRelationName,
193 inNumberOfAttributes, inAttributeInfo,
194 inNumberOfIndexes, inIndexInfo);
195 }
196
197 void
198 DatabaseSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle,
199 CSSM_DB_RECORDTYPE inRelationID)
200 {
201 DbContext &aDbContext = findDbContext(inDbHandle);
202 return aDbContext.mDatabase.destroyRelation(aDbContext, inRelationID);
203 }
204
205 void
206 DatabaseSession::Authenticate(CSSM_DB_HANDLE inDbHandle,
207 CSSM_DB_ACCESS_TYPE inAccessRequest,
208 const AccessCredentials &inAccessCred)
209 {
210 DbContext &aDbContext = findDbContext(inDbHandle);
211 aDbContext.mDatabase.authenticate(aDbContext, inAccessRequest, inAccessCred);
212 }
213
214
215 void
216 DatabaseSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle,
217 const CSSM_STRING *inSelectionTag,
218 uint32 &outNumberOfAclInfos,
219 CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
220 {
221 DbContext &aDbContext = findDbContext(inDbHandle);
222 aDbContext.mDatabase.getDbAcl(aDbContext, inSelectionTag, outNumberOfAclInfos, outAclInfos);
223 }
224
225 void
226 DatabaseSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle,
227 const AccessCredentials &inAccessCred,
228 const CSSM_ACL_EDIT &inAclEdit)
229 {
230 DbContext &aDbContext = findDbContext(inDbHandle);
231 aDbContext.mDatabase.changeDbAcl(aDbContext, inAccessCred, inAclEdit);
232 }
233
234 void
235 DatabaseSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle,
236 CSSM_ACL_OWNER_PROTOTYPE &outOwner)
237 {
238 DbContext &aDbContext = findDbContext(inDbHandle);
239 aDbContext.mDatabase.getDbOwner(aDbContext, outOwner);
240 }
241
242 void
243 DatabaseSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle,
244 const AccessCredentials &inAccessCred,
245 const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
246 {
247 DbContext &aDbContext = findDbContext(inDbHandle);
248 aDbContext.mDatabase.changeDbOwner(aDbContext, inAccessCred, inNewOwner);
249 }
250
251 void
252 DatabaseSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle,
253 char **outDbName)
254 {
255 DbContext &aDbContext = findDbContext(inDbHandle);
256 Required(outDbName) = aDbContext.mDatabase.getDbNameFromHandle(aDbContext);
257 }
258
259 void
260 DatabaseSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
261 CSSM_DB_RECORDTYPE inRecordType,
262 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
263 const CssmData *inData,
264 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
265 {
266 DbContext &aDbContext = findDbContext(inDbHandle);
267 outUniqueId = aDbContext.mDatabase.dataInsert(aDbContext, inRecordType, inAttributes, inData);
268 }
269
270
271 void
272 DatabaseSession::DataDelete(CSSM_DB_HANDLE inDbHandle,
273 const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
274 {
275 DbContext &aDbContext = findDbContext(inDbHandle);
276 aDbContext.mDatabase.dataDelete(aDbContext, inUniqueRecordIdentifier);
277 }
278
279
280 void
281 DatabaseSession::DataModify(CSSM_DB_HANDLE inDbHandle,
282 CSSM_DB_RECORDTYPE inRecordType,
283 CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
284 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
285 const CssmData *inDataToBeModified,
286 CSSM_DB_MODIFY_MODE inModifyMode)
287 {
288 DbContext &aDbContext = findDbContext(inDbHandle);
289 aDbContext.mDatabase.dataModify(aDbContext, inRecordType, inoutUniqueRecordIdentifier,
290 inAttributesToBeModified, inDataToBeModified, inModifyMode);
291 }
292
293 CSSM_HANDLE
294 DatabaseSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle,
295 const DLQuery *inQuery,
296 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
297 CssmData *inoutData,
298 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
299 {
300 DbContext &aDbContext = findDbContext(inDbHandle);
301
302 return aDbContext.mDatabase.dataGetFirst(aDbContext, inQuery,
303 inoutAttributes, inoutData, outUniqueId);
304 }
305
306 bool
307 DatabaseSession::DataGetNext(CSSM_DB_HANDLE inDbHandle,
308 CSSM_HANDLE inResultsHandle,
309 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
310 CssmData *inoutData,
311 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
312 {
313 DbContext &aDbContext = findDbContext(inDbHandle);
314
315 return aDbContext.mDatabase.dataGetNext(aDbContext, inResultsHandle, inoutAttributes,
316 inoutData, outUniqueRecord);
317 }
318
319 void
320 DatabaseSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle,
321 CSSM_HANDLE inResultsHandle)
322 {
323 DbContext &aDbContext = findDbContext(inDbHandle);
324 aDbContext.mDatabase.dataAbortQuery(aDbContext, inResultsHandle);
325 }
326
327 void
328 DatabaseSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle,
329 const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
330 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
331 CssmData *inoutData)
332 {
333 DbContext &aDbContext = findDbContext(inDbHandle);
334 aDbContext.mDatabase.dataGetFromUniqueRecordId(aDbContext, inUniqueRecord,
335 inoutAttributes, inoutData);
336 }
337
338 void
339 DatabaseSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle,
340 CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
341 {
342 DbContext &aDbContext = findDbContext(inDbHandle);
343 aDbContext.mDatabase.freeUniqueRecord(aDbContext, inUniqueRecordIdentifier);
344 }
345
346 void
347 DatabaseSession::PassThrough(CSSM_DB_HANDLE inDbHandle,
348 uint32 passThroughId,
349 const void *inputParams,
350 void **outputParams)
351 {
352 DbContext &aDbContext = findDbContext(inDbHandle);
353 aDbContext.mDatabase.passThrough(aDbContext, passThroughId, inputParams, outputParams);
354 }