]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2004,2008,2011-2012 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // SDDLSession.h - DL session for security server CSP/DL. | |
27 | // | |
28 | #include "SDDLSession.h" | |
29 | ||
30 | #include "SDCSPDLPlugin.h" | |
31 | #include "SDKey.h" | |
32 | #include <security_cdsa_utilities/cssmbridge.h> | |
33 | #include <security_utilities/trackingallocator.h> | |
34 | #include <Security/cssmapplePriv.h> | |
35 | ||
36 | using namespace CssmClient; | |
37 | using namespace SecurityServer; | |
38 | using namespace std; | |
39 | ||
40 | // | |
41 | // SDDLSession -- Security Server DL session | |
42 | // | |
43 | SDDLSession::SDDLSession(CSSM_MODULE_HANDLE handle, | |
44 | SDCSPDLPlugin &plug, | |
45 | const CSSM_VERSION &version, | |
46 | uint32 subserviceId, | |
47 | CSSM_SERVICE_TYPE subserviceType, | |
48 | CSSM_ATTACH_FLAGS attachFlags, | |
49 | const CSSM_UPCALLS &upcalls, | |
50 | DatabaseManager &databaseManager, | |
51 | SDCSPDLSession &ssCSPDLSession) : | |
52 | DLPluginSession(handle, plug, version, subserviceId, subserviceType, | |
53 | attachFlags, upcalls, databaseManager), | |
54 | mSDCSPDLSession(ssCSPDLSession), | |
55 | mClientSession(Allocator::standard(), static_cast<PluginSession &>(*this)) | |
56 | //mAttachment(mClientSession.attach(version, subserviceId, subserviceType, attachFlags)) | |
57 | { | |
58 | } | |
59 | ||
60 | SDDLSession::~SDDLSession() | |
61 | { | |
62 | } | |
63 | ||
64 | // Utility functions | |
65 | void | |
66 | SDDLSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList) | |
67 | { | |
68 | outNameList->String = this->PluginSession::alloc<char *>(); | |
69 | outNameList->NumStrings = 1; | |
70 | outNameList->String[0] = (char*) ""; // empty name will trigger dynamic lookup | |
71 | } | |
72 | ||
73 | ||
74 | void | |
75 | SDDLSession::FreeNameList(CSSM_NAME_LIST &inNameList) | |
76 | { | |
77 | this->PluginSession::free(inNameList.String); | |
78 | } | |
79 | ||
80 | ||
81 | void | |
82 | SDDLSession::DbDelete(const char *inDbName, | |
83 | const CSSM_NET_ADDRESS *inDbLocation, | |
84 | const AccessCredentials *inAccessCred) | |
85 | { | |
86 | unimplemented(); | |
87 | } | |
88 | ||
89 | // DbContext creation and destruction. | |
90 | void | |
91 | SDDLSession::DbCreate(const char *inDbName, | |
92 | const CSSM_NET_ADDRESS *inDbLocation, | |
93 | const CSSM_DBINFO &inDBInfo, | |
94 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
95 | const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry, | |
96 | const void *inOpenParameters, | |
97 | CSSM_DB_HANDLE &outDbHandle) | |
98 | { | |
99 | unimplemented(); | |
100 | } | |
101 | ||
102 | void | |
103 | SDDLSession::DbOpen(const char *inDbName, | |
104 | const CSSM_NET_ADDRESS *inDbLocation, | |
105 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
106 | const AccessCredentials *inAccessCred, | |
107 | const void *inOpenParameters, | |
108 | CSSM_DB_HANDLE &outDbHandle) | |
109 | { | |
110 | outDbHandle = mClientSession.openToken(subserviceId(), inAccessCred, inDbName); | |
111 | } | |
112 | ||
113 | // Operations using DbContext instances. | |
114 | void | |
115 | SDDLSession::DbClose(CSSM_DB_HANDLE inDbHandle) | |
116 | { | |
117 | mClientSession.releaseDb(ClientSession::toIPCHandle(inDbHandle)); | |
118 | } | |
119 | ||
120 | void | |
121 | SDDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle, | |
122 | CSSM_DB_RECORDTYPE inRelationID, | |
123 | const char *inRelationName, | |
124 | uint32 inNumberOfAttributes, | |
125 | const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, | |
126 | uint32 inNumberOfIndexes, | |
127 | const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo) | |
128 | { | |
129 | unimplemented(); | |
130 | } | |
131 | ||
132 | void | |
133 | SDDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle, | |
134 | CSSM_DB_RECORDTYPE inRelationID) | |
135 | { | |
136 | unimplemented(); | |
137 | } | |
138 | ||
139 | void | |
140 | SDDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle, | |
141 | CSSM_DB_ACCESS_TYPE inAccessRequest, | |
142 | const AccessCredentials &inAccessCred) | |
143 | { | |
427c49bc | 144 | mClientSession.authenticateDb((DbHandle)inDbHandle, inAccessRequest, &inAccessCred); |
b1ab9ed8 A |
145 | } |
146 | ||
147 | ||
148 | void | |
149 | SDDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle, | |
150 | const CSSM_STRING *inSelectionTag, | |
151 | uint32 &outNumberOfAclInfos, | |
152 | CSSM_ACL_ENTRY_INFO_PTR &outAclInfos) | |
153 | { | |
154 | // @@@ inSelectionTag shouldn't be a CSSM_STRING * but just a CSSM_STRING. | |
155 | mClientSession.getDbAcl(ClientSession::toIPCHandle(inDbHandle), *inSelectionTag, outNumberOfAclInfos, | |
156 | AclEntryInfo::overlayVar(outAclInfos)); | |
157 | } | |
158 | ||
159 | void | |
160 | SDDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle, | |
161 | const AccessCredentials &inAccessCred, | |
162 | const CSSM_ACL_EDIT &inAclEdit) | |
163 | { | |
164 | mClientSession.changeDbAcl(ClientSession::toIPCHandle(inDbHandle), inAccessCred, AclEdit::overlay(inAclEdit)); | |
165 | } | |
166 | ||
167 | void | |
168 | SDDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle, | |
169 | CSSM_ACL_OWNER_PROTOTYPE &outOwner) | |
170 | { | |
171 | mClientSession.getDbOwner(ClientSession::toIPCHandle(inDbHandle), AclOwnerPrototype::overlay(outOwner)); | |
172 | } | |
173 | ||
174 | void | |
175 | SDDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle, | |
176 | const AccessCredentials &inAccessCred, | |
177 | const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner) | |
178 | { | |
179 | mClientSession.changeDbOwner(ClientSession::toIPCHandle(inDbHandle), inAccessCred, AclOwnerPrototype::overlay(inNewOwner)); | |
180 | } | |
181 | ||
182 | void | |
183 | SDDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle, | |
184 | char **outDbName) | |
185 | { | |
186 | string name; | |
187 | mClientSession.getDbName(ClientSession::toIPCHandle(inDbHandle), name); | |
188 | memcpy(Required(outDbName) = static_cast<char *>(this->malloc(name.length() + 1)), | |
189 | name.c_str(), name.length() + 1); | |
190 | } | |
191 | ||
192 | void | |
193 | SDDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle, | |
194 | CSSM_DB_RECORDTYPE inRecordType, | |
195 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, | |
196 | const CssmData *inData, | |
197 | CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId) | |
198 | { | |
199 | RecordHandle record; | |
200 | record = mClientSession.insertRecord(ClientSession::toIPCHandle(inDbHandle), | |
201 | inRecordType, | |
202 | CssmDbRecordAttributeData::overlay(inAttributes), | |
203 | inData); | |
204 | outUniqueId = makeDbUniqueRecord(record); | |
205 | } | |
206 | ||
207 | void | |
208 | SDDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle, | |
209 | const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) | |
210 | { | |
211 | RecordHandle record = ClientSession::toIPCHandle(findDbUniqueRecord(inUniqueRecordIdentifier)); | |
212 | mClientSession.deleteRecord(ClientSession::toIPCHandle(inDbHandle), record); | |
213 | } | |
214 | ||
215 | ||
216 | void | |
217 | SDDLSession::DataModify(CSSM_DB_HANDLE inDbHandle, | |
218 | CSSM_DB_RECORDTYPE inRecordType, | |
219 | CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier, | |
220 | const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified, | |
221 | const CssmData *inDataToBeModified, | |
222 | CSSM_DB_MODIFY_MODE inModifyMode) | |
223 | { | |
224 | RecordHandle record = ClientSession::toIPCHandle(findDbUniqueRecord(inoutUniqueRecordIdentifier)); | |
225 | mClientSession.modifyRecord(ClientSession::toIPCHandle(inDbHandle), record, inRecordType, | |
226 | CssmDbRecordAttributeData::overlay(inAttributesToBeModified), | |
227 | inDataToBeModified, inModifyMode); | |
228 | //@@@ make a (new) unique record out of possibly modified "record"... | |
229 | } | |
230 | ||
231 | void | |
232 | SDDLSession::postGetRecord(RecordHandle record, U32HandleObject::Handle resultsHandle, | |
233 | CSSM_DB_HANDLE db, | |
234 | CssmDbRecordAttributeData *pAttributes, | |
235 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
236 | CssmData *inoutData, KeyHandle hKey) | |
237 | { | |
238 | // If the client didn't ask for data then it doesn't matter | |
239 | // if this record is a key or not, just return it. | |
240 | if (inoutData) | |
241 | { | |
242 | CSSM_DB_RECORDTYPE recordType = pAttributes->DataRecordType; | |
243 | if (!inoutAttributes) | |
244 | { | |
245 | // @@@ Free pAttributes | |
246 | } | |
247 | ||
248 | if (recordType == CSSM_DL_DB_RECORD_PUBLIC_KEY | |
249 | || recordType == CSSM_DL_DB_RECORD_PRIVATE_KEY | |
250 | || recordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY) | |
251 | { | |
252 | // This record is a key. The data returned is a CSSM_KEY | |
253 | // (with empty key data) with the header filled in. | |
254 | try | |
255 | { | |
256 | if (hKey == noKey) // tokend error - should have returned key handle | |
257 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); | |
258 | // Allocate storage for the key. | |
259 | CssmKey *outKey = inoutData->interpretedAs<CssmKey>(); | |
260 | new SDKey(*this, *outKey, hKey, db, record, recordType, *inoutData); | |
261 | } | |
262 | catch (...) | |
263 | { | |
264 | try { mClientSession.releaseRecord(record); } | |
265 | catch(...) { secdebug("ssCrypt", "releaseRecord threw during catch"); } | |
266 | if (resultsHandle != CSSM_INVALID_HANDLE) | |
267 | { | |
268 | try { mClientSession.releaseSearch(resultsHandle); } | |
269 | catch(...) { secdebug("ssCrypt", "releaseSearch threw during catch"); } | |
270 | } | |
271 | throw; | |
272 | } | |
273 | } else { // not a key | |
274 | if (hKey != noKey) { | |
275 | try { mClientSession.releaseRecord(record); } | |
276 | catch(...) { secdebug("ssCrypt", "failed releasing bogus key handle"); } | |
277 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); | |
278 | } | |
279 | } | |
280 | } | |
281 | } | |
282 | ||
283 | CSSM_HANDLE | |
284 | SDDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle, | |
285 | const CssmQuery *inQuery, | |
286 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
287 | CssmData *inoutData, | |
288 | CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) | |
289 | { | |
290 | // Setup so we always retrieve the attributes if the client asks for data, | |
291 | // even if the client doesn't want them so we can figure out if we just | |
292 | // retrieved a key. | |
293 | CssmDbRecordAttributeData attributes; | |
294 | CssmDbRecordAttributeData *pAttributes; | |
295 | if (inoutAttributes) | |
296 | pAttributes = CssmDbRecordAttributeData::overlay(inoutAttributes); | |
297 | else | |
298 | { | |
299 | pAttributes = &attributes; | |
300 | memset(pAttributes, 0, sizeof(attributes)); | |
301 | } | |
302 | ||
303 | RecordHandle record; | |
304 | SearchHandle resultsHandle = noSearch; | |
305 | KeyHandle keyId = noKey; | |
306 | record = mClientSession.findFirst(ClientSession::toIPCHandle(inDbHandle), | |
307 | CssmQuery::required(inQuery), | |
308 | resultsHandle, | |
309 | pAttributes, | |
310 | inoutData, keyId); | |
311 | if (!record) | |
312 | return CSSM_INVALID_HANDLE; | |
313 | ||
314 | postGetRecord(record, resultsHandle, inDbHandle, pAttributes, inoutAttributes, inoutData, keyId); | |
315 | outUniqueRecord = makeDbUniqueRecord(record); | |
316 | return resultsHandle; | |
317 | } | |
318 | ||
319 | bool | |
320 | SDDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle, | |
321 | CSSM_HANDLE inResultsHandle, | |
322 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
323 | CssmData *inoutData, | |
324 | CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) | |
325 | { | |
326 | // Setup so we always retrieve the attributes if the client asks for data, | |
327 | // even if the client doesn't want them so we can figure out if we just | |
328 | // retrieved a key. | |
329 | CssmDbRecordAttributeData attributes; | |
330 | CssmDbRecordAttributeData *pAttributes; | |
331 | if (inoutAttributes) | |
332 | pAttributes = CssmDbRecordAttributeData::overlay(inoutAttributes); | |
333 | else | |
334 | { | |
335 | pAttributes = &attributes; | |
336 | memset(pAttributes, 0, sizeof(attributes)); | |
337 | } | |
338 | ||
339 | RecordHandle record; | |
340 | KeyHandle keyId = noKey; | |
341 | record = mClientSession.findNext(ClientSession::toIPCHandle(inResultsHandle), | |
342 | pAttributes, | |
343 | inoutData, keyId); | |
344 | if (!record) | |
345 | return false; | |
346 | ||
347 | postGetRecord(record, CSSM_INVALID_HANDLE, inDbHandle, pAttributes, | |
348 | inoutAttributes, inoutData, keyId); | |
349 | outUniqueRecord = makeDbUniqueRecord(record); | |
350 | return true; | |
351 | } | |
352 | ||
353 | void | |
354 | SDDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle, | |
355 | CSSM_HANDLE inResultsHandle) | |
356 | { | |
357 | mClientSession.releaseSearch(ClientSession::toIPCHandle(inResultsHandle)); | |
358 | } | |
359 | ||
360 | void | |
361 | SDDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle, | |
362 | const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, | |
363 | CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, | |
364 | CssmData *inoutData) | |
365 | { | |
366 | // Setup so we always retrieve the attributes if the client asks for data, | |
367 | // even if the client doesn't want them so we can figure out if we just | |
368 | // retrieved a key. | |
369 | CssmDbRecordAttributeData attributes; | |
370 | CssmDbRecordAttributeData *pAttributes; | |
371 | if (inoutAttributes) | |
372 | pAttributes = CssmDbRecordAttributeData::overlay(inoutAttributes); | |
373 | else | |
374 | { | |
375 | pAttributes = &attributes; | |
376 | memset(pAttributes, 0, sizeof(attributes)); | |
377 | } | |
378 | ||
379 | RecordHandle record = ClientSession::toIPCHandle(findDbUniqueRecord(inUniqueRecord)); | |
380 | KeyHandle keyId = noKey; | |
381 | mClientSession.findRecordHandle(record, pAttributes, inoutData, keyId); | |
382 | postGetRecord(record, CSSM_INVALID_HANDLE, inDbHandle, pAttributes, | |
383 | inoutAttributes, inoutData, keyId); | |
384 | } | |
385 | ||
386 | void | |
387 | SDDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle, | |
388 | CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) | |
389 | { | |
390 | RecordHandle record = ClientSession::toIPCHandle(findDbUniqueRecord(inUniqueRecordIdentifier)); | |
391 | freeDbUniqueRecord(inUniqueRecordIdentifier); | |
392 | mClientSession.releaseRecord(record); | |
393 | } | |
394 | ||
395 | void | |
396 | SDDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle, | |
397 | uint32 inPassThroughId, | |
398 | const void *inInputParams, | |
399 | void **outOutputParams) | |
400 | { | |
401 | switch (inPassThroughId) | |
402 | { | |
403 | case CSSM_APPLECSPDL_DB_LOCK: | |
404 | mClientSession.lock(ClientSession::toIPCHandle(inDbHandle)); | |
405 | break; | |
406 | case CSSM_APPLECSPDL_DB_UNLOCK: | |
407 | { | |
408 | TrackingAllocator track(Allocator::standard()); | |
409 | AutoCredentials creds(track); | |
410 | creds.tag("PIN1"); | |
411 | if (inInputParams) | |
412 | creds += TypedList(track, CSSM_SAMPLE_TYPE_PASSWORD, | |
413 | new (track) ListElement(track, | |
414 | *reinterpret_cast<const CssmData *>(inInputParams))); | |
415 | else | |
416 | creds += TypedList(track, CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD, | |
417 | new (track) ListElement(track, CssmData())); | |
418 | ||
419 | Authenticate(inDbHandle, CSSM_DB_ACCESS_READ, creds); | |
420 | break; | |
421 | } | |
422 | case CSSM_APPLECSPDL_DB_IS_LOCKED: | |
423 | { | |
424 | if (!outOutputParams) | |
425 | CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER); | |
426 | ||
427 | bool isLocked = mClientSession.isLocked(ClientSession::toIPCHandle(inDbHandle)); | |
428 | CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params = | |
429 | DatabaseSession::alloc<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS>(); | |
430 | params->isLocked = isLocked; | |
431 | *reinterpret_cast<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR *> | |
432 | (outOutputParams) = params; | |
433 | break; | |
434 | } | |
435 | case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD: | |
436 | { | |
437 | if (!inInputParams) | |
438 | CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); | |
439 | ||
440 | const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *params = | |
441 | reinterpret_cast | |
442 | <const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *> | |
443 | (inInputParams); | |
444 | ||
445 | AutoAclEntryInfoList acls /* (mClientSession.allocator()) */; | |
446 | CSSM_STRING tag = { 'P', 'I', 'N', '1' }; | |
447 | GetDbAcl(inDbHandle, &tag, | |
448 | *static_cast<uint32 *>(acls), | |
449 | *static_cast<CSSM_ACL_ENTRY_INFO **>(acls)); | |
450 | if (acls.size() == 0) | |
451 | CssmError::throwMe(CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND); | |
452 | ||
453 | const AclEntryInfo &slot = acls.at(0); | |
454 | if (acls.size() > 1) | |
455 | secdebug("acl", | |
456 | "Using entry handle %ld from %d total candidates", | |
457 | slot.handle(), acls.size()); | |
458 | AclEdit edit(slot.handle(), slot.proto()); | |
459 | ChangeDbAcl(inDbHandle, | |
460 | AccessCredentials::required(params->accessCredentials), edit); | |
461 | break; | |
462 | } | |
463 | case CSSM_APPLECSPDL_DB_RELATION_EXISTS: | |
464 | { | |
465 | // We always return true so that the individual tokend can decide | |
466 | if (!outOutputParams) | |
467 | CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER); | |
468 | *reinterpret_cast<CSSM_BOOL *>(outOutputParams) = true; | |
469 | break; | |
470 | } | |
471 | default: | |
472 | CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID); | |
473 | } | |
474 | } | |
475 | ||
476 | CSSM_DB_UNIQUE_RECORD_PTR | |
477 | SDDLSession::makeDbUniqueRecord(RecordHandle uniqueId) | |
478 | { | |
479 | CSSM_DB_UNIQUE_RECORD *aUniqueRecord = DatabaseSession::alloc<CSSM_DB_UNIQUE_RECORD>(); | |
480 | memset(aUniqueRecord, 0, sizeof(CSSM_DB_UNIQUE_RECORD)); | |
481 | aUniqueRecord->RecordIdentifier.Length = sizeof(CSSM_HANDLE); | |
482 | try | |
483 | { | |
484 | aUniqueRecord->RecordIdentifier.Data = DatabaseSession::alloc<uint8>(sizeof(CSSM_HANDLE)); | |
485 | *reinterpret_cast<CSSM_HANDLE *>(aUniqueRecord->RecordIdentifier.Data) = uniqueId; | |
486 | } | |
487 | catch(...) | |
488 | { | |
489 | allocator().free(aUniqueRecord); | |
490 | throw; | |
491 | } | |
492 | ||
493 | return aUniqueRecord; | |
494 | } | |
495 | ||
496 | // formerly returned a RecordHandle, but redefining them to be 32-bit made | |
497 | // that untenable | |
498 | CSSM_HANDLE | |
499 | SDDLSession::findDbUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord) | |
500 | { | |
501 | if (inUniqueRecord.RecordIdentifier.Length != sizeof(CSSM_HANDLE)) | |
502 | CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID); | |
503 | ||
504 | return *reinterpret_cast<CSSM_HANDLE *>(inUniqueRecord.RecordIdentifier.Data); | |
505 | } | |
506 | ||
507 | void | |
508 | SDDLSession::freeDbUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord) | |
509 | { | |
510 | if (inUniqueRecord.RecordIdentifier.Length != 0 | |
511 | && inUniqueRecord.RecordIdentifier.Data != NULL) | |
512 | { | |
513 | inUniqueRecord.RecordIdentifier.Length = 0; | |
514 | allocator().free(inUniqueRecord.RecordIdentifier.Data); | |
515 | } | |
516 | allocator().free(&inUniqueRecord); | |
517 | } |