]> git.saurik.com Git - apple/security.git/blame - AppleCSPDL/SSDLSession.cpp
Security-163.tar.gz
[apple/security.git] / AppleCSPDL / SSDLSession.cpp
CommitLineData
bac41a7b
A
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// SSDLSession.h - DL session for security server CSP/DL.
21//
22#include "SSDLSession.h"
23
24#include "CSPDLPlugin.h"
25#include "SSKey.h"
26
27using namespace CssmClient;
28using namespace SecurityServer;
29using namespace std;
30
31//
32// SSDLSession -- Security Server DL session
33//
34SSDLSession::SSDLSession(CSSM_MODULE_HANDLE handle,
35 CSPDLPlugin &plug,
36 const CSSM_VERSION &version,
37 uint32 subserviceId,
38 CSSM_SERVICE_TYPE subserviceType,
39 CSSM_ATTACH_FLAGS attachFlags,
40 const CSSM_UPCALLS &upcalls,
41 DatabaseManager &databaseManager,
42 SSCSPDLSession &ssCSPDLSession)
43: DLPluginSession(handle, plug, version, subserviceId, subserviceType,
44 attachFlags, upcalls, databaseManager),
45 mSSCSPDLSession(ssCSPDLSession),
29654253
A
46 mDL(Module(gGuidAppleFileDL, Cssm::standard())),
47 mClientSession(CssmAllocator::standard(), static_cast<PluginSession &>(*this))
bac41a7b
A
48{
49 // @@@ mDL.allocator(*static_cast<DatabaseSession *>(this));
50 mDL->allocator(allocator());
51 mDL->version(version);
52 mDL->subserviceId(subserviceId);
53 mDL->flags(attachFlags);
54}
55
56SSDLSession::~SSDLSession()
57{
58 // @@@ What about a catch?
59 StLock<Mutex> _1(mSSUniqueRecordLock);
60 mSSUniqueRecordMap.clear();
61
62 StLock<Mutex> _2(mDbHandleLock);
63 DbHandleMap::iterator end = mDbHandleMap.end();
64 for (DbHandleMap::iterator it = mDbHandleMap.begin(); it != end; ++it)
65 it->second->close();
66
67 mDbHandleMap.clear();
68 mDL->detach();
69}
70
71// Utility functions
72void
73SSDLSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList)
74{
75 // @@@ Fix client lib
76 CSSM_DL_GetDbNames(mDL->handle(), &outNameList);
77}
78
79
80void
81SSDLSession::FreeNameList(CSSM_NAME_LIST &inNameList)
82{
83 // @@@ Fix client lib
84 CSSM_DL_FreeNameList(mDL->handle(), &inNameList);
85}
86
87
88void
89SSDLSession::DbDelete(const char *inDbName,
90 const CSSM_NET_ADDRESS *inDbLocation,
91 const AccessCredentials *inAccessCred)
92{
29654253 93 SSDatabase db(mClientSession, mDL, inDbName, inDbLocation);
bac41a7b
A
94 db->accessCredentials(inAccessCred);
95 db->deleteDb();
96}
97
98// DbContext creation and destruction.
99void
100SSDLSession::DbCreate(const char *inDbName,
101 const CSSM_NET_ADDRESS *inDbLocation,
102 const CSSM_DBINFO &inDBInfo,
103 CSSM_DB_ACCESS_TYPE inAccessRequest,
104 const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
105 const void *inOpenParameters,
106 CSSM_DB_HANDLE &outDbHandle)
107{
29654253 108 SSDatabase db(mClientSession, mDL, inDbName, inDbLocation);
bac41a7b
A
109 db->dbInfo(&inDBInfo);
110 db->accessRequest(inAccessRequest);
111 db->resourceControlContext(inCredAndAclEntry);
112 db->openParameters(inOpenParameters);
113 db->create(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(),
114 CSSM_SERVICE_DL | CSSM_SERVICE_CSP),
115 inDbName, inDbLocation));
116 db->dbInfo(NULL);
117 outDbHandle = makeDbHandle(db);
118}
119
120void
121SSDLSession::DbOpen(const char *inDbName,
122 const CSSM_NET_ADDRESS *inDbLocation,
123 CSSM_DB_ACCESS_TYPE inAccessRequest,
124 const AccessCredentials *inAccessCred,
125 const void *inOpenParameters,
126 CSSM_DB_HANDLE &outDbHandle)
127{
29654253 128 SSDatabase db(mClientSession, mDL, inDbName, inDbLocation);
bac41a7b
A
129 db->accessRequest(inAccessRequest);
130 db->accessCredentials(inAccessCred);
131 db->openParameters(inOpenParameters);
132 db->open(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(),
133 CSSM_SERVICE_DL | CSSM_SERVICE_CSP),
134 inDbName, inDbLocation));
135 outDbHandle = makeDbHandle(db);
136}
137
138// Operations using DbContext instances.
139void
140SSDLSession::DbClose(CSSM_DB_HANDLE inDbHandle)
141{
142 killDbHandle(inDbHandle)->close();
143}
144
145void
146SSDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle,
147 CSSM_DB_RECORDTYPE inRelationID,
148 const char *inRelationName,
149 uint32 inNumberOfAttributes,
150 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO &inAttributeInfo,
151 uint32 inNumberOfIndexes,
152 const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo)
153{
154 SSDatabase db = findDbHandle(inDbHandle);
155 // @@@ Fix inAttributeInfo and inIndexInfo arguments (might be NULL if NumberOf = 0)
156 db->createRelation(inRelationID, inRelationName,
157 inNumberOfAttributes, &inAttributeInfo,
158 inNumberOfIndexes, &inIndexInfo);
159}
160
161void
162SSDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle,
163 CSSM_DB_RECORDTYPE inRelationID)
164{
165 // @@@ Check credentials.
166 SSDatabase db = findDbHandle(inDbHandle);
167 db->destroyRelation(inRelationID);
168}
169
170void
171SSDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle,
172 CSSM_DB_ACCESS_TYPE inAccessRequest,
173 const AccessCredentials &inAccessCred)
174{
bac41a7b
A
175 SSDatabase db = findDbHandle(inDbHandle);
176 db->authenticate(inAccessRequest, &inAccessCred);
177}
178
179
180void
181SSDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle,
182 const CSSM_STRING *inSelectionTag,
183 uint32 &outNumberOfAclInfos,
184 CSSM_ACL_ENTRY_INFO_PTR &outAclInfos)
185{
186 SSDatabase db = findDbHandle(inDbHandle);
187 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
188}
189
190void
191SSDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle,
192 const AccessCredentials &inAccessCred,
193 const CSSM_ACL_EDIT &inAclEdit)
194{
195 SSDatabase db = findDbHandle(inDbHandle);
196 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
197}
198
199void
200SSDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle,
201 CSSM_ACL_OWNER_PROTOTYPE &outOwner)
202{
203 SSDatabase db = findDbHandle(inDbHandle);
204 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
205}
206
207void
208SSDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle,
209 const AccessCredentials &inAccessCred,
210 const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner)
211{
212 SSDatabase db = findDbHandle(inDbHandle);
213 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
214}
215
216void
217SSDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle,
218 char **outDbName)
219{
220 SSDatabase db = findDbHandle(inDbHandle);
221 // @@@ Fix this functions signature.
222 db->name(*outDbName);
223}
224
225void
226SSDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle,
227 CSSM_DB_RECORDTYPE inRecordType,
228 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
229 const CssmData *inData,
230 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId)
231{
232 SSDatabase db = findDbHandle(inDbHandle);
233 // @@@ Fix client lib.
234 SSUniqueRecord uniqueId = db->insert(inRecordType, inAttributes, inData, true); // @@@ Fix me
235 outUniqueId = makeSSUniqueRecord(uniqueId);
236 // @@@ If this is a key do the right thing.
237}
238
239void
240SSDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle,
241 const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
242{
243 SSDatabase db = findDbHandle(inDbHandle);
244 SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecordIdentifier);
245 uniqueId->deleteRecord();
246 // @@@ If this is a key do the right thing.
247}
248
249
250void
251SSDLSession::DataModify(CSSM_DB_HANDLE inDbHandle,
252 CSSM_DB_RECORDTYPE inRecordType,
253 CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
254 const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
255 const CssmData *inDataToBeModified,
256 CSSM_DB_MODIFY_MODE inModifyMode)
257{
258 SSDatabase db = findDbHandle(inDbHandle);
259 SSUniqueRecord uniqueId = findSSUniqueRecord(inoutUniqueRecordIdentifier);
260 uniqueId->modify(inRecordType, inAttributesToBeModified, inDataToBeModified, inModifyMode);
261 // @@@ If this is a key do the right thing.
262}
263
264CSSM_HANDLE
265SSDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle,
266 const DLQuery *inQuery,
267 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
268 CssmData *inoutData,
269 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
270{
271 SSDatabase db = findDbHandle(inDbHandle);
272 CSSM_HANDLE resultsHandle = CSSM_INVALID_HANDLE;
273 SSUniqueRecord uniqueId(db);
274
275 // Setup so we always retrive the attributes even if the client
276 // doesn't want them so we can figure out if we just retrived a key.
277 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes;
278 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes;
279 if (inoutAttributes)
280 pAttributes = inoutAttributes;
281 else
282 {
283 pAttributes = &attributes;
284 memset(pAttributes, 0, sizeof(attributes));
285 }
286
287 // Retrive the record.
288 CSSM_RETURN result = CSSM_DL_DataGetFirst(db->handle(), inQuery, &resultsHandle,
289 pAttributes, inoutData, uniqueId);
290 if (result)
291 {
292 if (result == CSSMERR_DL_ENDOFDATA)
293 return CSSM_INVALID_HANDLE;
294
295 CssmError::throwMe(result);
296 }
297
298 uniqueId->activate();
299
300 // If we the client didn't ask for data then it doesn't matter
301 // if this record is a key or not, just return it.
302 if (inoutData)
303 {
304 if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY
305 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY
306 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
307 {
308 // This record is a key, do the right thing (tm).
309 // Allocate storage for the key.
310 CssmKey *outKey = allocator().alloc<CssmKey>();
311 new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData);
312
313 // Free the data we retrived (keyblob)
314 allocator().free(inoutData->Data);
315
316 // Set the length and data on the data we return to the client
317 inoutData->Length = sizeof(*outKey);
318 inoutData->Data = reinterpret_cast<uint8 *>(outKey);
319 }
320 }
321
322 outUniqueRecord = makeSSUniqueRecord(uniqueId);
323 return resultsHandle;
324}
325
326bool
327SSDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle,
328 CSSM_HANDLE inResultsHandle,
329 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
330 CssmData *inoutData,
331 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord)
332{
333 // @@@ If this is a key do the right thing.
334 SSDatabase db = findDbHandle(inDbHandle);
335 SSUniqueRecord uniqueId(db);
336
337 // Setup so we always retrive the attributes even if the client
338 // doesn't want them so we can figure out if we just retrived a key.
339 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes;
340 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes;
341 if (inoutAttributes)
342 pAttributes = inoutAttributes;
343 else
344 {
345 pAttributes = &attributes;
346 memset(pAttributes, 0, sizeof(attributes));
347 }
348
349 CSSM_RETURN result = CSSM_DL_DataGetNext(db->handle(), inResultsHandle,
350 inoutAttributes, inoutData, uniqueId);
351 if (result)
352 {
353 if (result == CSSMERR_DL_ENDOFDATA)
354 return false;
355
356 CssmError::throwMe(result);
357 }
358
359 uniqueId->activate();
360
361 // If we the client didn't ask for data then it doesn't matter
362 // if this record is a key or not, just return it.
363 if (inoutData)
364 {
365 if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY
366 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY
367 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
368 {
369 // This record is a key, do the right thing (tm).
370 // Allocate storage for the key.
371 CssmKey *outKey = allocator().alloc<CssmKey>();
372 new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData);
373
374 // Free the data we retrived (keyblob)
375 allocator().free(inoutData->Data);
376
377 // Set the length and data on the data we return to the client
378 inoutData->Length = sizeof(*outKey);
379 inoutData->Data = reinterpret_cast<uint8 *>(outKey);
380 }
381 }
382
383 outUniqueRecord = makeSSUniqueRecord(uniqueId);
384
385 return true;
386}
387
388void
389SSDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle,
390 CSSM_HANDLE inResultsHandle)
391{
392 // @@@ If this is a key do the right thing.
393 SSDatabase db = findDbHandle(inDbHandle);
394 CSSM_RETURN result = CSSM_DL_DataAbortQuery(db->handle(), inResultsHandle);
395 if (result)
396 CssmError::throwMe(result);
397}
398
399void
400SSDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle,
401 const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
402 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
403 CssmData *inoutData)
404{
405 SSDatabase db = findDbHandle(inDbHandle);
406 const SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecord);
29654253
A
407
408 // Setup so we always retrive the attributes even if the client
409 // doesn't want them so we can figure out if we just retrived a key.
410 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes;
411 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes;
412 if (inoutAttributes)
413 pAttributes = inoutAttributes;
414 else
415 {
416 pAttributes = &attributes;
417 memset(pAttributes, 0, sizeof(attributes));
418 }
419
420 CSSM_RETURN result = CSSM_DL_DataGetFromUniqueRecordId(db->handle(),
421 uniqueId, pAttributes, inoutData);
bac41a7b
A
422 if (result)
423 CssmError::throwMe(result);
29654253
A
424
425 if (inoutData)
426 {
427 if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY
428 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY
429 || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
430 {
431 // This record is a key, do the right thing (tm).
432 // Allocate storage for the key.
433 CssmKey *outKey = allocator().alloc<CssmKey>();
434 new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData);
435
436 // Free the data we retrived (keyblob)
437 allocator().free(inoutData->Data);
438
439 // Set the length and data on the data we return to the client
440 inoutData->Length = sizeof(*outKey);
441 inoutData->Data = reinterpret_cast<uint8 *>(outKey);
442 }
443 }
bac41a7b
A
444}
445
446void
447SSDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle,
448 CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier)
449{
450 killSSUniqueRecord(inUniqueRecordIdentifier);
451}
452
453void
454SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle,
455 uint32 inPassThroughId,
456 const void *inInputParams,
457 void **outOutputParams)
458{
459 SSDatabase db = findDbHandle(inDbHandle);
460 switch (inPassThroughId)
461 {
462 case CSSM_APPLECSPDL_DB_LOCK:
463 db->lock();
464 break;
465 case CSSM_APPLECSPDL_DB_UNLOCK:
466 if (inInputParams)
467 db->unlock(*reinterpret_cast<const CSSM_DATA *>(inInputParams));
468 else
469 db->unlock();
470 break;
471 case CSSM_APPLECSPDL_DB_GET_SETTINGS:
472 {
473 if (!outOutputParams)
474 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
475
476 CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR params =
477 allocator().alloc<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS>();
478 try
479 {
480 uint32 idleTimeout;
481 bool lockOnSleep;
482 db->getSettings(idleTimeout, lockOnSleep);
483 params->idleTimeout = idleTimeout;
484 params->lockOnSleep = lockOnSleep;
485 }
486 catch(...)
487 {
488 allocator().free(params);
489 throw;
490 }
491 *reinterpret_cast<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR *>(outOutputParams) = params;
492 break;
493 }
494 case CSSM_APPLECSPDL_DB_SET_SETTINGS:
495 {
496 if (!inInputParams)
497 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
498
499 const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS *params =
500 reinterpret_cast<const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS *>(inInputParams);
501 db->setSettings(params->idleTimeout, params->lockOnSleep);
502 break;
503 }
504 case CSSM_APPLECSPDL_DB_IS_LOCKED:
505 {
506 if (!outOutputParams)
507 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
508
509 CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params =
510 allocator().alloc<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS>();
511 try
512 {
513 params->isLocked = db->isLocked();
514 }
515 catch(...)
516 {
517 allocator().free(params);
518 throw;
519 }
520 *reinterpret_cast<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR *>(outOutputParams) = params;
521 break;
522 }
523 case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD:
524 {
525 if (!inInputParams)
526 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
527
528 const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *params =
529 reinterpret_cast<const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *>(inInputParams);
530 db->changePassphrase(params->accessCredentials);
531 break;
532 }
df0e469f
A
533 case CSSM_APPLECSPDL_DB_GET_HANDLE:
534 {
535 using SecurityServer::DbHandle;
536 Required(outOutputParams, CSSM_ERRCODE_INVALID_OUTPUT_POINTER);
537 DbHandle &dbHandle = *(DbHandle *)outOutputParams;
538 dbHandle = db->dbHandle();
539 break;
540 }
bac41a7b
A
541 default:
542 {
543 CSSM_RETURN result = CSSM_DL_PassThrough(db->handle(), inPassThroughId, inInputParams, outOutputParams);
544 if (result)
545 CssmError::throwMe(result);
546 break;
547 }
548 }
549}
550
551CSSM_DB_HANDLE
552SSDLSession::makeDbHandle(SSDatabase &inDb)
553{
554 StLock<Mutex> _(mDbHandleLock);
555 CSSM_DB_HANDLE aDbHandle = inDb->handle().DBHandle;
df0e469f 556 IFDEBUG(bool inserted =) mDbHandleMap.insert(DbHandleMap::value_type(aDbHandle, inDb)).second;
bac41a7b
A
557 assert(inserted);
558 return aDbHandle;
559}
560
561SSDatabase
562SSDLSession::killDbHandle(CSSM_DB_HANDLE inDbHandle)
563{
564 StLock<Mutex> _(mDbHandleLock);
565 DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle);
566 if (it == mDbHandleMap.end())
567 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE);
568
569 SSDatabase db = it->second;
570 mDbHandleMap.erase(it);
571 return db;
572}
573
574SSDatabase
575SSDLSession::findDbHandle(CSSM_DB_HANDLE inDbHandle)
576{
577 StLock<Mutex> _(mDbHandleLock);
578 DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle);
579 if (it == mDbHandleMap.end())
580 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE);
581
582 return it->second;
583}
584
585CSSM_DB_UNIQUE_RECORD_PTR
586SSDLSession::makeSSUniqueRecord(SSUniqueRecord &uniqueId)
587{
588 StLock<Mutex> _(mSSUniqueRecordLock);
589 CSSM_HANDLE ref = CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD *>(uniqueId));
df0e469f 590 IFDEBUG(bool inserted =) mSSUniqueRecordMap.insert(SSUniqueRecordMap::value_type(ref, uniqueId)).second;
bac41a7b
A
591 assert(inserted);
592 return createUniqueRecord(ref);
593}
594
595SSUniqueRecord
596SSDLSession::killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
597{
598 CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord);
599 StLock<Mutex> _(mSSUniqueRecordLock);
600 SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref);
601 if (it == mSSUniqueRecordMap.end())
602 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
603
604 SSUniqueRecord uniqueRecord = it->second;
605 mSSUniqueRecordMap.erase(it);
606 freeUniqueRecord(inUniqueRecord);
607 return uniqueRecord;
608}
609
610SSUniqueRecord
611SSDLSession::findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
612{
613 CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord);
614 StLock<Mutex> _(mSSUniqueRecordLock);
615 SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref);
616 if (it == mSSUniqueRecordMap.end())
617 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
618
619 return it->second;
620}
621
622CSSM_DB_UNIQUE_RECORD_PTR
623SSDLSession::createUniqueRecord(CSSM_HANDLE ref)
624{
625 CSSM_DB_UNIQUE_RECORD *aUniqueRecord = allocator().alloc<CSSM_DB_UNIQUE_RECORD>();
626 memset(aUniqueRecord, 0, sizeof(CSSM_DB_UNIQUE_RECORD));
627 aUniqueRecord->RecordIdentifier.Length = sizeof(CSSM_HANDLE);
628 try
629 {
630 aUniqueRecord->RecordIdentifier.Data = allocator().alloc<uint8>(sizeof(CSSM_HANDLE));
631 *reinterpret_cast<CSSM_HANDLE *>(aUniqueRecord->RecordIdentifier.Data) = ref;
632 }
633 catch(...)
634 {
635 free(aUniqueRecord);
636 throw;
637 }
638
639 return aUniqueRecord;
640}
641
642CSSM_HANDLE
643SSDLSession::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
644{
645 if (inUniqueRecord.RecordIdentifier.Length != sizeof(CSSM_HANDLE))
646 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID);
647
648 return *reinterpret_cast<CSSM_HANDLE *>(inUniqueRecord.RecordIdentifier.Data);
649}
650
651void
652SSDLSession::freeUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord)
653{
654 if (inUniqueRecord.RecordIdentifier.Length != 0
655 && inUniqueRecord.RecordIdentifier.Data != NULL)
656 {
657 inUniqueRecord.RecordIdentifier.Length = 0;
658 allocator().free(inUniqueRecord.RecordIdentifier.Data);
659 }
660 allocator().free(&inUniqueRecord);
661}