1/* 2 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. 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#include "Relation.h" 25#include "LDAPDLModule.h" 26#include "CommonCode.h" 27 28TableRelation *LDAPDLModule::mSchemaRelationRelation = NULL, 29 *LDAPDLModule::mSchemaAttributeRelation = NULL, 30 *LDAPDLModule::mSchemaIndexRelation = NULL, 31 *LDAPDLModule::mSchemaParsingModuleRelation = NULL; 32DSX509Relation *LDAPDLModule::mX509Relation = NULL; 33RelationMap *LDAPDLModule::mRelationMap; 34 35 36void LDAPDLModule::SetupSchemaRelationRelation () 37{ 38 // setup the CSSM_DL_DB_SCHEMA_INDEXES 39 40 static columnInfoLoader ciLoader[] = { 41 { 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 42 { 0, "RelationName", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 43 }; 44 45 mSchemaRelationRelation = new TableRelation (CSSM_DL_DB_SCHEMA_INFO, (sizeof(ciLoader) / sizeof(columnInfoLoader)), ciLoader); 46 47 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_SCHEMA_INFO), new StringValue ("CSSM_DL_DB_SCHEMA_INFO")); 48 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_SCHEMA_ATTRIBUTES), new StringValue ("CSSM_DL_DB_SCHEMA_ATTRIBUTES")); 49 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_SCHEMA_INDEXES), new StringValue ("CSSM_DL_DB_SCHEMA_INDEXES")); 50 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_SCHEMA_PARSING_MODULE), new StringValue ("CSSM_DL_DB_SCHEMA_PARSING_MODULE")); 51 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_RECORD_X509_CERTIFICATE), new StringValue ("CSSM_DL_DB_RECORD_X509_CERTIFICATE")); 52 (*mRelationMap)[CSSM_DL_DB_SCHEMA_INFO] = mSchemaRelationRelation; 53 (*mRelationMap)[CSSM_DL_DB_SCHEMA_INDEXES] = mSchemaRelationRelation; 54} 55 56 57struct attributeLoader { 58 UInt32 relationID; 59 UInt32 attrID; 60 const char * attrName; 61 UInt32 attrFormat; 62}; 63 64void LDAPDLModule::SetupSchemaAttributeRelation () 65{ 66 static columnInfoLoader ciLoader[] = { 67 { 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 68 { 1, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 69 { 2, "AttributeNameFormat", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 70 { 3, "AttributeName", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 71 { 4, "AttributeNameID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 72 { 5, "AttributeFormat", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 73 }; 74 mSchemaAttributeRelation = new TableRelation (CSSM_DL_DB_SCHEMA_ATTRIBUTES, (sizeof(ciLoader) / sizeof(columnInfoLoader)), ciLoader); 75 76 static struct attributeLoader loader[] = { 77 // setup the index 78 { CSSM_DL_DB_SCHEMA_INFO, 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 79 { CSSM_DL_DB_SCHEMA_INFO, 1, "RelationName", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 80 81 // setup the attribute table 82 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 83 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 1, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 84 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 2, "AttributeNameFormat", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 85 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 3, "AttributeName", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 86 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 4, "AttributeName", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 87 { CSSM_DL_DB_SCHEMA_ATTRIBUTES, 5, "AttributeNameID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 88 89 // setup the index table 90 { CSSM_DL_DB_SCHEMA_INDEXES, 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 91 { CSSM_DL_DB_SCHEMA_INDEXES, 1, "IndexID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 92 { CSSM_DL_DB_SCHEMA_INDEXES, 2, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 93 { CSSM_DL_DB_SCHEMA_INDEXES, 3, "IndexType", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 94 { CSSM_DL_DB_SCHEMA_INDEXES, 4, "IndexedDataLocation", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 95 96 // setup the schema parsing module 97 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 98 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 1, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 99 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 2, "ModuleID", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 100 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 3, "AddInVersion", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 101 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 4, "SSID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 102 { CSSM_DL_DB_SCHEMA_PARSING_MODULE, 5, "SubserviceType", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 103 104 }; 105 106 int nrows = sizeof(loader) / sizeof(struct attributeLoader); 107 for(int i=0; i < nrows; i++) 108 mSchemaAttributeRelation->AddTuple (new UInt32Value (loader[i].relationID),new UInt32Value (loader[i].attrID),new UInt32Value (CSSM_DB_ATTRIBUTE_NAME_AS_STRING),new StringValue (loader[i].attrName), NULL, new UInt32Value (loader[i].attrFormat)); 109 110 (*mRelationMap)[CSSM_DL_DB_SCHEMA_ATTRIBUTES] = mSchemaAttributeRelation; 111} 112 113 114 115struct indexLoader { 116 UInt32 relationID; 117 UInt32 indexID; 118 UInt32 attributeID; 119 UInt32 indexType; 120 UInt32 indexedDataLocation; 121}; 122 123void LDAPDLModule::SetupSchemaIndexRelation () 124{ 125 static columnInfoLoader ciLoader[] = { 126 { 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 127 { 1, "IndexID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 128 { 2, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 129 { 3, "IndexType", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 130 { 4, "IndexedDataLocation", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 131 }; 132 mSchemaIndexRelation = new TableRelation (CSSM_DL_DB_SCHEMA_INDEXES, (sizeof(ciLoader) / sizeof(columnInfoLoader)), ciLoader); 133 134 static struct indexLoader loader[] = { 135 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 0, 'ctyp', 0, 1 }, 136 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 1, 'issu', 0, 1 }, 137 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 2, 'snbr', 0, 1 }, 138 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 3, 'alis', 1, 1 }, 139 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 4, 'subj', 1, 1 }, 140 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 5, 'issu', 1, 1 }, 141 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 6, 'snbr', 1, 1 }, 142 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 7, 'skid', 1, 1 }, 143 { CSSM_DL_DB_RECORD_X509_CERTIFICATE, 8, 'hpky', 1, 1 }, 144 }; 145 146 int nrows = sizeof(loader) / sizeof(struct indexLoader); 147 for(int i=0; i < nrows; i++) 148 mSchemaIndexRelation->AddTuple (new UInt32Value (loader[i].relationID),new UInt32Value (loader[i].indexID), new UInt32Value (loader[i].attributeID), new UInt32Value (loader[i].indexType), new UInt32Value (loader[i].indexedDataLocation)); 149 150 (*mRelationMap)[CSSM_DL_DB_SCHEMA_INDEXES] = mSchemaIndexRelation; 151} 152 153 154 155void LDAPDLModule::SetupSchemaParsingModuleRelation () 156{ 157 static columnInfoLoader ciLoader[] = { 158 { 0, "RelationID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 159 { 1, "AttributeID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 160 { 2, "ModuleID", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 161 { 3, "AddinVersion", CSSM_DB_ATTRIBUTE_FORMAT_STRING }, 162 { 4, "SSID", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 163 { 5, "SubserviceType", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 164 }; 165 mSchemaParsingModuleRelation = new TableRelation (CSSM_DL_DB_SCHEMA_PARSING_MODULE, (sizeof(ciLoader) / sizeof(columnInfoLoader)), ciLoader); 166 (*mRelationMap)[CSSM_DL_DB_SCHEMA_PARSING_MODULE] = mSchemaParsingModuleRelation; 167} 168 169 170 171void LDAPDLModule::SetupX509Relation () 172{ 173 static columnInfoLoader ciLoader[] = { 174 { 'ctyp', "CertType", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 175 { 'cenc', "CertEncoding", CSSM_DB_ATTRIBUTE_FORMAT_UINT32 }, 176 { 'labl', "PrintName", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 177 { 'alis', "Alias", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 178 { 'subj', "Subject", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 179 { 'issu', "Issuer", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 180 { 'snbr', "SerialNumber", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 181 { 'skid', "SubjectKeyIdentifier", CSSM_DB_ATTRIBUTE_FORMAT_BLOB }, 182 { 'hpky', "PublicKeyHash", CSSM_DB_ATTRIBUTE_FORMAT_BLOB } 183 }; 184 mX509Relation = new DSX509Relation (CSSM_DL_DB_RECORD_X509_CERTIFICATE, (sizeof(ciLoader) / sizeof(columnInfoLoader)), ciLoader); 185 186 // add the relation to the attributes table 187 int max = mX509Relation->GetNumberOfColumns (); 188 189 for (int i = 0; i < max; ++i) 190 mSchemaAttributeRelation->AddTuple (new UInt32Value (CSSM_DL_DB_RECORD_X509_CERTIFICATE), new UInt32Value (mX509Relation->GetColumnIDs (i)), new UInt32Value (CSSM_DB_ATTRIBUTE_NAME_AS_STRING), 191 mX509Relation->GetColumnName (i), NULL, new UInt32Value (mX509Relation->GetColumnFormat (i))); 192 (*mRelationMap)[CSSM_DL_DB_RECORD_X509_CERTIFICATE] = mX509Relation; 193 194 // add to the attribute info database 195 mSchemaRelationRelation->AddTuple (new UInt32Value (CSSM_DL_DB_RECORD_X509_CERTIFICATE), new StringValue ("CSSM_DL_DB_RECORD_X509_CERTIFICATE")); 196 197} 198 199 200 201void LDAPDLModule::InitializeRelations () 202{ 203 mRelationMap = new RelationMap; 204 SetupSchemaRelationRelation (); 205 SetupSchemaAttributeRelation (); 206 SetupSchemaIndexRelation (); 207 SetupSchemaParsingModuleRelation (); 208 SetupX509Relation (); 209} 210 211 212 213LDAPDLModule::LDAPDLModule (pthread_mutex_t *globalLock, CSSM_SPI_ModuleEventHandler CssmNotifyCallback, void* CssmNotifyCallbackCtx) : 214 DataStorageLibrary (globalLock, CssmNotifyCallback, CssmNotifyCallbackCtx) 215{ 216} 217 218 219 220LDAPDLModule::~LDAPDLModule () 221{ 222} 223 224 225 226AttachedInstance* LDAPDLModule::MakeAttachedInstance () 227{ 228 return new LDAPAttachedInstance (); 229} 230 231 232 233Relation* LDAPDLModule::LookupRelation (CSSM_DB_RECORDTYPE recordType) 234{ 235 if (mSchemaRelationRelation == NULL) 236 InitializeRelations (); 237 RelationMap::iterator r = (*mRelationMap).find (recordType); 238 if (r == (*mRelationMap).end ()) 239 CSSMError::ThrowCSSMError (CSSMERR_DL_INVALID_RECORDTYPE); 240 241 return (*r).second; 242} 243 244 245 246Database* LDAPAttachedInstance::MakeDatabaseObject () 247{ 248 return new LDAPDatabase (this); 249} 250 251 252 253LDAPDatabase::LDAPDatabase (AttachedInstance *ai) : Database (ai), mNextHandle (0) 254{ 255} 256 257 258 259LDAPDatabase::~LDAPDatabase () 260{ 261} 262 263 264 265void LDAPDatabase::DbOpen (const char* DbName, const CSSM_NET_ADDRESS *dbLocation, const CSSM_DB_ACCESS_TYPE accessRequest, 266 const CSSM_ACCESS_CREDENTIALS *accessCredentials, const void* openParameters) 267{ 268 if (DbName == NULL) 269 CSSMError::ThrowCSSMError (CSSMERR_CSSM_INVALID_POINTER); 270 271 // this database can only be opened read only. Any attempt to gain write permissions will be dealt with severely 272 if (accessRequest != CSSM_DB_ACCESS_READ) 273 CSSMError::ThrowCSSMError (CSSMERR_DL_INVALID_ACCESS_REQUEST); 274 275 mDatabaseName = DbName; 276} 277 278 279 280void LDAPDatabase::DbClose () 281{ 282 // we're about to disappear... 283} 284 285 286 287void LDAPDatabase::DbGetDbNameFromHandle (char** dbName) 288{ 289 // return the name of our storage library 290 291 *dbName = (char*) mAttachedInstance->malloc (mDatabaseName.length () + 1); 292 strcpy (*dbName, mDatabaseName.c_str ()); 293} 294 295 296 297void LDAPDatabase::CopyAttributes (Relation *r, Tuple *t, CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes) 298{ 299 // fill out each attribute requested 300 if(t == NULL || r == NULL || attributes == NULL) return; 301 302 uint32 i; 303 CSSM_DB_ATTRIBUTE_DATA* d = attributes->AttributeData; 304 attributes->DataRecordType = r->GetRecordType (); 305 Value *v; 306 307 for (i = 0; i < attributes->NumberOfAttributes; ++i, d++) { 308 int columnNumber; 309 switch (d->Info.AttributeNameFormat) { 310 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING: 311 columnNumber = r->GetColumnNumber (d->Info.Label.AttributeName); 312 break; 313 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER: 314 columnNumber = r->GetColumnNumber (d->Info.Label.AttributeID); 315 break; 316 default: 317 columnNumber = r->GetColumnNumber (d->Info.Label.AttributeID); 318 break; 319 } 320 321 if ( columnNumber != -1 && (v = t->GetValue (columnNumber)) != NULL) { 322 d->Value = (CSSM_DATA_PTR) mAttachedInstance->malloc (sizeof (CSSM_DATA)); 323 d->Info.AttributeFormat = v->GetValueType(); 324 uint32 numItems, length; 325 326 d->Value->Data = v->CloneContents (mAttachedInstance, numItems, length); 327 d->Value->Length = length; 328 d->NumberOfValues = numItems; 329 } else { 330 d->Value = NULL; 331 d->NumberOfValues = 0; 332 } 333 } 334} 335 336 337 338const uint32 kMaximumSelectionPredicates = 1000; 339 340 341 342void LDAPDatabase::GetDataFromTuple (Tuple *t, CSSM_DATA &data) 343{ 344 // get the data from the tuple 345 CSSM_DATA tmpData; 346 t->GetData (tmpData); 347 348 // clone it 349 data.Data = (uint8 *)mAttachedInstance->malloc (tmpData.Length); 350 data.Length = tmpData.Length; 351 memmove(data.Data, tmpData.Data, data.Length); 352} 353 354 355void LDAPDatabase::processNext(CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes, CSSM_DATA_PTR data,CSSM_DB_UNIQUE_RECORD_PTR *uniqueID, Query *q, Relation *r) 356{ 357 UniqueIdentifier *id; 358 Tuple* t = q->GetNextTuple (id); 359 360 if (t == NULL) CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 361 if(attributes != NULL) CopyAttributes (r, t, attributes); 362 if (data != NULL) GetDataFromTuple (t, *data); 363 364 // new record unique ID 365 ExportUniqueID (id, uniqueID); 366} 367 368CSSM_HANDLE LDAPDatabase::DbDataGetFirst (const CSSM_QUERY *query, 369 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes, 370 CSSM_DATA_PTR data, 371 CSSM_DB_UNIQUE_RECORD_PTR *uniqueID) 372{ 373 // since we really only track one record type, record type CSSM_DL_DB_RECORD_ANY is the same as 374 // CSSM_DL_DB_RECORD_X509_CERTIFICATE 375 376 *uniqueID = NULL; 377 378 if(!query) CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 379 380 CSSM_DB_RECORDTYPE recordType = query->RecordType; 381 382 switch (recordType) { 383 case CSSM_DL_DB_RECORD_ANY: 384 recordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE; 385 break; 386 case CSSM_DL_DB_SCHEMA_INFO: 387 break; 388 case CSSM_DL_DB_SCHEMA_INDEXES: 389 break; 390 case CSSM_DL_DB_SCHEMA_ATTRIBUTES: 391 break; 392 case CSSM_DL_DB_SCHEMA_PARSING_MODULE: 393 break; 394 case CSSM_DL_DB_RECORD_X509_CERTIFICATE: 395 break; 396 default: 397 CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 398 break; 399 } 400 401 402 // do error checking on the attributes 403 if ((attributes != NULL) && (attributes->SemanticInformation != 0)) CSSMError::ThrowCSSMError (CSSMERR_DL_INVALID_QUERY); 404 405 // set an arbitrary limit on the number of selection predicates -- mostly for range checking 406 if (query->NumSelectionPredicates > kMaximumSelectionPredicates) CSSMError::ThrowCSSMError (CSSMERR_DL_UNSUPPORTED_NUM_SELECTION_PREDS); 407 408 // lookup our relation in the relation map 409 Relation* r = LDAPDLModule::LookupRelation (recordType); 410 411 // make a query for this request 412 Query *q = r->MakeQuery (query); 413 414 if(!q) CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 415 416 processNext(attributes, data, uniqueID, q, r); 417 418 // make a new handle for this query 419 CSSM_HANDLE h = mNextHandle++; 420 mQueryMap[h] = q; 421 return h; 422} 423 424 425bool LDAPDatabase::DbDataGetNext (CSSM_HANDLE resultsHandle, 426 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes, 427 CSSM_DATA_PTR data, 428 CSSM_DB_UNIQUE_RECORD_PTR *uniqueID) 429{ 430 *uniqueID = NULL; 431 432 QueryMap::iterator it = mQueryMap.find (resultsHandle); 433 if (it == mQueryMap.end ()) CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 434 435 Query* q = (*it).second; 436 437 if(!q) CSSMError::ThrowCSSMError (CSSMERR_DL_ENDOFDATA); 438 Relation *r = q->GetRelation (); 439 440 processNext(attributes, data, uniqueID, q, r); 441 442 return true; 443} 444 445 446void LDAPDatabase::ExportUniqueID (UniqueIdentifier *id, CSSM_DB_UNIQUE_RECORD_PTR *uniqueID) 447{ 448 CSSM_DB_UNIQUE_RECORD *ur = new CSSM_DB_UNIQUE_RECORD; 449 // id->Export (*ur); 450 ur->RecordIdentifier.Length = sizeof (id); 451 ur->RecordIdentifier.Data = (uint8*) id; 452 *uniqueID = ur; 453} 454 455 456void LDAPDatabase::DbDataAbortQuery (CSSM_HANDLE resultsHandle) 457{ 458 QueryMap::iterator it = mQueryMap.find (resultsHandle); 459 if (it == mQueryMap.end ()) return; 460 461 Query* q = (*it).second; 462 delete q; 463 mQueryMap.erase (resultsHandle); 464} 465 466 467 468void LDAPDatabase::DbFreeUniqueRecord (CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord) 469{ 470 UniqueIdentifier* id = (UniqueIdentifier*) uniqueRecord->RecordIdentifier.Data; 471 delete id; 472 delete uniqueRecord; 473} 474 475 476 477void LDAPDatabase::DbDataGetFromUniqueRecordID (const CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord, 478 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes, 479 CSSM_DATA_PTR data) 480{ 481 // recover the identifier 482 if(uniqueRecord == NULL) return; 483 484 UniqueIdentifier* id = (UniqueIdentifier*) uniqueRecord->RecordIdentifier.Data; 485 if(id==NULL) return; 486 487 CSSM_DB_RECORDTYPE recordType = id->GetRecordType (); 488 Relation* r = LDAPDLModule::LookupRelation (recordType); 489 if(r == NULL)return; 490 491 Tuple* t = r->GetTupleFromUniqueIdentifier (id); 492 if(t == NULL) return; 493 494 if(attributes != NULL) CopyAttributes (r, t, attributes); 495 if (data != NULL) GetDataFromTuple (t, *data); 496} 497