1/* 2 * Copyright (c) 2005-2006,2010 Apple 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 * 01DL_CreateReleation.c 24 */ 25 26#include <stdlib.h> 27#include <unistd.h> 28#include <Security/cssmapi.h> 29#include <Security/cssmapple.h> 30 31#include "testmore.h" 32#include "testenv.h" 33#include "testcssm.h" 34#include "testleaks.h" 35 36#define DBNAME "testdl" 37 38CSSM_APPLEDL_OPEN_PARAMETERS openParameters = 39{ 40 sizeof(CSSM_APPLEDL_OPEN_PARAMETERS), 41 CSSM_APPLEDL_OPEN_PARAMETERS_VERSION, 42 CSSM_FALSE, 43 kCSSM_APPLEDL_MASK_MODE, 44 0600 45}; 46CSSM_DBINFO dbInfo = 47{ 48 0 /* NumberOfRecordTypes */, 49 NULL, 50 NULL, 51 NULL, 52 CSSM_TRUE /* IsLocal */, 53 NULL, /* AccessPath - URL, dir path, etc. */ 54 NULL /* reserved */ 55}; 56CSSM_DB_SCHEMA_ATTRIBUTE_INFO attributeInfo[] = 57{ 58 { 59 1, 60 "string-1", 61 {}, 62 CSSM_DB_ATTRIBUTE_FORMAT_STRING 63 }, 64 { 65 2, 66 "sint32-2", 67 {}, 68 CSSM_DB_ATTRIBUTE_FORMAT_SINT32 69 }, 70 { 71 3, 72 "uint32-3", 73 {}, 74 CSSM_DB_ATTRIBUTE_FORMAT_UINT32 75 }, 76 { 77 4, 78 "big_num-4", 79 {}, 80 CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM 81 }, 82 { 83 5, 84 "real-5", 85 {}, 86 CSSM_DB_ATTRIBUTE_FORMAT_REAL 87 }, 88 { 89 6, 90 "time-date-6", 91 {}, 92 CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE 93 }, 94 { 95 7, 96 "blob-7", 97 {}, 98 CSSM_DB_ATTRIBUTE_FORMAT_BLOB 99 }, 100 { 101 8, 102 "multi-uint32-8", 103 {}, 104 CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32 105 }, 106#if 0 107 /* @@@ DL bug if you create a relation with a 108 CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX type attribute it succeeds but 109 subsequent inserts in that table fail. */ 110 { 111 9, 112 "complex-9", 113 {}, 114 CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX 115 } 116#endif 117}; 118CSSM_DB_SCHEMA_INDEX_INFO indexInfo[] = 119{ 120 { 121 1, 122 0, 123 CSSM_DB_INDEX_UNIQUE, 124 CSSM_DB_INDEX_ON_ATTRIBUTE 125 }, 126 { 127 1, 128 1, 129 CSSM_DB_INDEX_NONUNIQUE, 130 CSSM_DB_INDEX_ON_ATTRIBUTE 131 }, 132 { 133 2, 134 2, 135 CSSM_DB_INDEX_NONUNIQUE, 136 CSSM_DB_INDEX_ON_ATTRIBUTE 137 } 138}; 139CSSM_DATA values_str_1[] = 140{ 141 { 7, (uint8 *)"value-1" } 142}; 143CSSM_DATA values_str_2[] = 144{ 145 { 7, (uint8 *)"value-2" } 146}; 147CSSM_DATA values_sint32_1[] = 148{ 149 { sizeof(sint32), (uint8 *)"1111" } 150}; 151CSSM_DATA values_sint32_2[] = 152{ 153 { sizeof(sint32), (uint8 *)"2222" } 154}; 155 156CSSM_DB_ATTRIBUTE_DATA attributeData[] = 157{ 158 { 159 { 160 CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, 161 { (char *)((uint64_t)1<<32|1) }, 162 CSSM_DB_ATTRIBUTE_FORMAT_STRING 163 }, 164 sizeof(values_str_1) / sizeof(CSSM_DATA), 165 values_str_1 166 }, 167 { 168 { 169 CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, 170 { (char *)((uint64_t)2<<32|2) }, 171 CSSM_DB_ATTRIBUTE_FORMAT_SINT32 172 }, 173 sizeof(values_sint32_1) / sizeof(CSSM_DATA), 174 values_sint32_1 175 } 176}; 177CSSM_DB_RECORD_ATTRIBUTE_DATA attributes = 178{ 179 42, 180 0x00008000, 181 sizeof(attributeData) / sizeof(CSSM_DB_ATTRIBUTE_DATA), 182 attributeData 183}; 184 185CSSM_DB_ATTRIBUTE_DATA newAttributeData[] = 186{ 187 { 188 { 189 CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, 190 { (char *)((uint64_t)1<<32|1) }, 191 CSSM_DB_ATTRIBUTE_FORMAT_STRING 192 }, 193 sizeof(values_str_2) / sizeof(CSSM_DATA), 194 values_str_2 195 }, 196 { 197 { 198 CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, 199 { (char *)((uint64_t)2<<32|2) }, 200 CSSM_DB_ATTRIBUTE_FORMAT_SINT32 201 }, 202 sizeof(values_sint32_2) / sizeof(CSSM_DATA), 203 values_sint32_2 204 } 205}; 206CSSM_DB_RECORD_ATTRIBUTE_DATA newAttributes = 207{ 208 42, 209 0x80000001, /* Semantic Information. */ 210 sizeof(newAttributeData) / sizeof(CSSM_DB_ATTRIBUTE_DATA), 211 newAttributeData 212}; 213 214static void free_attributes_data(const CSSM_API_MEMORY_FUNCS *memfuncs, 215 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR attributes, CSSM_DATA_PTR data) 216{ 217 if (data && data->Data) 218 { 219 memfuncs->free_func(data->Data, memfuncs->AllocRef); 220 data->Data = NULL; 221 } 222 223 if (attributes && attributes->AttributeData) 224 { 225 uint32 aix; 226 for (aix = 0; aix < attributes->NumberOfAttributes; ++aix) 227 { 228 if (attributes->AttributeData[aix].Value) 229 { 230 uint32 vix; 231 for (vix = 0; 232 vix < attributes->AttributeData[aix].NumberOfValues; ++vix) 233 { 234 if (attributes->AttributeData[aix].Value[vix].Data) 235 { 236 memfuncs->free_func( 237 attributes->AttributeData[aix].Value[vix].Data, 238 memfuncs->AllocRef); 239 } 240 } 241 242 memfuncs->free_func(attributes->AttributeData[aix].Value, 243 memfuncs->AllocRef); 244 attributes->AttributeData[aix].NumberOfValues = 0; 245 attributes->AttributeData[aix].Value = NULL; 246 } 247 } 248 } 249} 250 251static int test_is_attributes_data( 252 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes1, const CSSM_DATA *data1, 253 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes2, const CSSM_DATA *data2, 254 const char *description, const char *directive, 255 const char *reason, const char *file, unsigned line) 256{ 257 if (attributes1 || attributes2) 258 { 259 if (!attributes1 || !attributes2) 260 return test_ok(0, description, directive, reason, file, line, 261 "# got CSSM_DB_RECORD_ATTRIBUTE_DATA %p\n" 262 "# expected CSSM_DB_RECORD_ATTRIBUTE_DATA %p\n", 263 attributes1, attributes2); 264 265 if (attributes1->DataRecordType != attributes2->DataRecordType || 266 attributes1->SemanticInformation != 267 attributes2->SemanticInformation || 268 attributes1->NumberOfAttributes != attributes2->NumberOfAttributes) 269 return test_ok(0, description, directive, reason, file, line, 270 "# got CSSM_DB_RECORD_ATTRIBUTE_DATA:\n" 271 "# DataRecordType: %08x\n" 272 "# SemanticInformation: %08x\n" 273 "# NumberOfAttributes: %lu\n" 274 "# expected CSSM_DB_RECORD_ATTRIBUTE_DATA:\n" 275 "# DataRecordType: %08x\n" 276 "# SemanticInformation: %08x\n" 277 "# NumberOfAttributes: %lu\n", 278 attributes1->DataRecordType, 279 attributes1->SemanticInformation, 280 attributes1->NumberOfAttributes, 281 attributes2->DataRecordType, 282 attributes2->SemanticInformation, 283 attributes2->NumberOfAttributes); 284 uint32 ai; 285 for (ai = 0; ai < attributes1->NumberOfAttributes; ++ai) 286 { 287 const CSSM_DB_ATTRIBUTE_DATA *a1 = &attributes1->AttributeData[ai]; 288 const CSSM_DB_ATTRIBUTE_DATA *a2 = &attributes2->AttributeData[ai]; 289 if (a1->Info.AttributeFormat != a2->Info.AttributeFormat || 290 a1->NumberOfValues != a2->NumberOfValues) 291 return test_ok(0, description, directive, reason, file, line, 292 "# got AttributeData[%lu]:\n" 293 "# AttributeFormat: %08x\n" 294 "# NumberOfValues: %lu\n" 295 "# expected AttributeData[%lu]:\n" 296 "# AttributeFormat: %08x\n" 297 "# NumberOfValues: %lu\n", 298 ai, a1->Info.AttributeFormat, a1->NumberOfValues, 299 ai, a2->Info.AttributeFormat, a2->NumberOfValues); 300 uint32 vi; 301 for (vi = 0; vi < a1->NumberOfValues; ++vi) 302 { 303 const CSSM_DATA *d1 = &a1->Value[vi]; 304 const CSSM_DATA *d2 = &a2->Value[vi]; 305 if (d1->Length != d2->Length || !d1->Data || !d2->Data || 306 memcmp(d1->Data, d2->Data, d1->Length)) 307 return test_ok(d1->Data == d2->Data, description, 308 directive, reason, file, line, 309 "# got AttributeData[%lu].Value[%lu]:\n" 310 "# length: %lu\n" 311 "# data: '%.*s'\n" 312 "# expected AttributeData[%lu].Value[%lu]:\n" 313 "# length: %lu\n" 314 "# data: '%.*s'\n", 315 ai, vi, d1->Length, (int)d1->Length, d1->Data, 316 ai, vi, d2->Length, (int)d2->Length, d2->Data); 317 } 318 } 319 } 320 if (data1 || data2) 321 { 322 if (!data1 || !data2) 323 return test_ok(0, description, directive, reason, file, line, 324 "# got CSSM_DATA %p\n" 325 "# expected CSSM_DATA %p\n", data1, data2); 326 if (data1->Length != data2->Length || !data1->Data || !data2->Data || 327 memcmp(data1->Data, data2->Data, data1->Length)) 328 return test_ok(data1->Data == data2->Data, description, directive, 329 reason, file, line, 330 "# got CSSM_DATA:\n" 331 "# length: %lu\n" 332 "# data: '%.*s'\n" 333 "# expected CSSM_DATA:\n" 334 "# length: %lu\n" 335 "# data: '%.*s'\n", 336 data1->Length, (int)data1->Length, data1->Data, 337 data2->Length, (int)data2->Length, data2->Data); 338 } 339 340 return test_ok(1, description, directive, reason, file, line, NULL); 341} 342 343#define is_attributes_data(A1, D1, A2, D2, TESTNAME) \ 344( \ 345 test_is_attributes_data((A1), (D1), (A2), (D2), \ 346 TESTNAME, test_directive, test_reason, __FILE__, __LINE__) \ 347) 348 349static void test1(CSSM_DL_HANDLE dl) 350{ 351 CSSM_DL_DB_HANDLE dldb = { dl }; 352 CSSM_DB_UNIQUE_RECORD_PTR uniqueId; 353 354 CSSM_DATA data = { 4, (uint8 *)"test" }; 355 ok_status(CSSM_DL_DbCreate(dl, DBNAME, NULL /* DbLocation */, 356 &dbInfo, 357 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE, 358 NULL /* CredAndAclEntry */, 359 NULL /* &openParameters */, 360 &dldb.DBHandle), 361 "CSSM_DL_DbCreate"); 362 363 is_status(CSSM_DL_DataInsert(dldb, 364 attributes.DataRecordType, 365 &attributes, 366 &data, 367 &uniqueId), 368 CSSMERR_DL_INVALID_RECORDTYPE, "CSSM_DL_DataInsert no table"); 369 370 ok_status(CSSM_DL_CreateRelation(dldb, 371 42, 372 "Fourty Two", 373 sizeof(attributeInfo) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO), 374 attributeInfo, 375 sizeof(indexInfo) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO), 376 indexInfo), "CSSM_DL_CreateRelation"); 377 378 ok_status(CSSM_DL_DataInsert(dldb, 379 attributes.DataRecordType, 380 &attributes, 381 &data, 382 &uniqueId), "CSSM_DL_DataInsert"); 383 384 is_status(CSSM_DL_DataInsert(dldb, 385 attributes.DataRecordType, 386 &attributes, 387 &data, 388 &uniqueId), 389 CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA, "CSSM_DL_DataInsert dupe"); 390 391 ok_status(CSSM_DL_DataModify(dldb, 392 attributes.DataRecordType, 393 uniqueId, 394 &newAttributes, 395 &data, 396 CSSM_DB_MODIFY_ATTRIBUTE_REPLACE), "CSSM_DL_DataModify"); 397 398 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 399 "CSSM_DL_FreeUniqueRecord"); 400 401 ok_status(CSSM_DL_DataInsert(dldb, 402 attributes.DataRecordType, 403 &attributes, 404 &data, 405 &uniqueId), "CSSM_DL_DataInsert old one again"); 406 407 CSSM_API_MEMORY_FUNCS memfuncs = {}; 408 ok_status(CSSM_GetAPIMemoryFunctions(dldb.DLHandle, &memfuncs), 409 "CSSM_GetAPIMemoryFunctions"); 410 411 ok_status(CSSM_DL_DataGetFromUniqueRecordId(dldb, uniqueId, NULL, NULL), 412 "CSSM_DL_DataGetFromUniqueRecordId get nothing"); 413 414 CSSM_DATA resultData = {}; 415 ok_status(CSSM_DL_DataGetFromUniqueRecordId(dldb, uniqueId, 416 NULL, &resultData), 417 "CSSM_DL_DataGetFromUniqueRecordId get data"); 418 is_attributes_data(NULL, &resultData, NULL, &data, "Does data match?"); 419 free_attributes_data(&memfuncs, NULL, &resultData); 420 421 CSSM_DB_RECORD_ATTRIBUTE_DATA baseNoAttrs = attributes; 422 baseNoAttrs.NumberOfAttributes = 0; 423 baseNoAttrs.AttributeData = NULL; 424 CSSM_DB_RECORD_ATTRIBUTE_DATA resultNoAttrs = {}; 425 ok_status(CSSM_DL_DataGetFromUniqueRecordId(dldb, uniqueId, 426 &resultNoAttrs, NULL), 427 "CSSM_DL_DataGetFromUniqueRecordId get 0 attributes"); 428 is_attributes_data(&resultNoAttrs, NULL, &baseNoAttrs, NULL, 429 "Do attrs match?"); 430 free_attributes_data(&memfuncs, &resultNoAttrs, NULL); 431 432 ok_status(CSSM_DL_DataGetFromUniqueRecordId(dldb, uniqueId, 433 &resultNoAttrs, &resultData), 434 "CSSM_DL_DataGetFromUniqueRecordId get data and 0 attributes"); 435 is_attributes_data(&resultNoAttrs, &resultData, &baseNoAttrs, &data, 436 "Do attrs and data match?"); 437 free_attributes_data(&memfuncs, &resultNoAttrs, &resultData); 438 439 CSSM_DB_ATTRIBUTE_DATA resultAttributeData[] = 440 { 441 {{ CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, { (char *)((uint64_t)1<<32|1) } }}, 442 {{ CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, { (char *)((uint64_t)2<<32|2) } }} 443 }; 444 CSSM_DB_RECORD_ATTRIBUTE_DATA resultAttrs = 445 { 446 0, 0, 447 sizeof(resultAttributeData) / sizeof(*resultAttributeData), 448 resultAttributeData 449 }; 450 ok_status(CSSM_DL_DataGetFromUniqueRecordId(dldb, uniqueId, 451 &resultAttrs, &resultData), 452 "CSSM_DL_DataGetFromUniqueRecordId get data and 2 attributes"); 453 is_attributes_data(&resultAttrs, &resultData, &attributes, &data, 454 "Do attrs and data match?"); 455 free_attributes_data(&memfuncs, &resultAttrs, &resultData); 456 457 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 458 "CSSM_DL_FreeUniqueRecord"); 459 460 CSSM_SELECTION_PREDICATE predicates[] = 461 { 462 { 463 CSSM_DB_EQUAL, 464 { 465 { CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, { (char *)((uint64_t)1<<32|1) } }, 466 1, values_str_1 467 } 468 } 469 }; 470 CSSM_QUERY query = 471 { 472 attributes.DataRecordType, 473 CSSM_DB_AND, 474 sizeof(predicates) / sizeof(*predicates), 475 predicates, 476 { CSSM_QUERY_TIMELIMIT_NONE, CSSM_QUERY_SIZELIMIT_NONE }, 477 0 /* CSSM_QUERY_RETURN_DATA -- for keys only to return raw key bits */ 478 }; 479 CSSM_HANDLE search = CSSM_INVALID_HANDLE; 480 is_status(CSSM_DL_DataGetFirst(dldb, &query, NULL, 481 NULL, NULL, NULL), CSSM_ERRCODE_INVALID_POINTER, 482 "CSSM_DL_DataGetFirst no search handle, no unique_record"); 483 is_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 484 NULL, NULL, NULL), CSSM_ERRCODE_INVALID_POINTER, 485 "CSSM_DL_DataGetFirst no unique_record"); 486 is_status(CSSM_DL_DataGetFirst(dldb, &query, NULL, 487 NULL, NULL, &uniqueId), CSSM_ERRCODE_INVALID_POINTER, 488 "CSSM_DL_DataGetFirst no search handle"); 489 490 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 491 NULL, NULL, &uniqueId), 492 "CSSM_DL_DataGetFirst no data no attrs"); 493 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 494 "CSSM_DL_FreeUniqueRecord"); 495 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 496 "CSSM_DL_DataAbortQuery"); 497 498 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 499 &resultNoAttrs, NULL, &uniqueId), 500 "CSSM_DL_DataGetFirst 0 attrs"); 501 is_attributes_data(&resultNoAttrs, NULL, &baseNoAttrs, NULL, 502 "Do attrs match?"); 503 free_attributes_data(&memfuncs, &resultNoAttrs, NULL); 504 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 505 "CSSM_DL_FreeUniqueRecord"); 506 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 507 "CSSM_DL_DataAbortQuery"); 508 509 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 510 NULL, &resultData, &uniqueId), 511 "CSSM_DL_DataGetFirst data"); 512 is_attributes_data(NULL, &resultData, NULL, &data, "Does data match?"); 513 free_attributes_data(&memfuncs, NULL, &resultData); 514 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 515 "CSSM_DL_FreeUniqueRecord"); 516 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 517 "CSSM_DL_DataAbortQuery"); 518 519 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 520 &resultNoAttrs, &resultData, &uniqueId), 521 "CSSM_DL_DataGetFirst 0 attrs and data"); 522 is_attributes_data(&resultNoAttrs, &resultData, &baseNoAttrs, &data, 523 "Do attrs and data match?"); 524 free_attributes_data(&memfuncs, &resultNoAttrs, &resultData); 525 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 526 "CSSM_DL_FreeUniqueRecord"); 527 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 528 "CSSM_DL_DataAbortQuery"); 529 530 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 531 &resultAttrs, &resultData, &uniqueId), 532 "CSSM_DL_DataGetFirst 2 attrs and data"); 533 is_attributes_data(&resultAttrs, &resultData, &attributes, &data, 534 "Do attrs and data match?"); 535 free_attributes_data(&memfuncs, &resultAttrs, &resultData); 536 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 537 "CSSM_DL_FreeUniqueRecord"); 538 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 539 "CSSM_DL_DataAbortQuery"); 540 541 SKIP: { 542 skip("nothing to free", 2, 543 ok_status(CSSM_DL_DataGetFirst(dldb, &query, &search, 544 &resultAttrs, &resultData, &uniqueId), 545 "CSSM_DL_DataGetFirst 2 attrs and data")); 546 is_attributes_data(&resultAttrs, &resultData, &attributes, &data, 547 "Do attrs and data match?"); 548 free_attributes_data(&memfuncs, &resultAttrs, &resultData); 549 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 550 "CSSM_DL_FreeUniqueRecord"); 551 } 552 553 is_status(CSSM_DL_DataGetNext(dldb, search, 554 &resultAttrs, &resultData, &uniqueId), 555 CSSMERR_DL_ENDOFDATA, "CSSM_DL_DataGetNext returns eod"); 556 557 CSSM_QUERY query2 = 558 { 559 attributes.DataRecordType, 560 CSSM_DB_NONE, 561 0, 562 NULL, 563 { CSSM_QUERY_TIMELIMIT_NONE, CSSM_QUERY_SIZELIMIT_NONE }, 564 0 /* CSSM_QUERY_RETURN_DATA -- for keys only to return raw key bits */ 565 }; 566 ok_status(CSSM_DL_DataGetFirst(dldb, &query2, &search, 567 &resultAttrs, &resultData, &uniqueId), 568 "CSSM_DL_DataGetFirst 2 attrs and data"); 569 free_attributes_data(&memfuncs, &resultAttrs, &resultData); 570 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 571 "CSSM_DL_FreeUniqueRecord"); 572 ok_status(CSSM_DL_DataGetNext(dldb, search, 573 &resultAttrs, &resultData, &uniqueId), 574 "CSSM_DL_DataGetNext 2 attrs and data"); 575 free_attributes_data(&memfuncs, &resultAttrs, &resultData); 576 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 577 "CSSM_DL_FreeUniqueRecord"); 578 ok_status(CSSM_DL_DataAbortQuery(dldb, search), 579 "CSSM_DL_DataAbortQuery"); 580 581 ok_status(CSSM_DL_DbClose(dldb), 582 "CSSM_DL_DbClose"); 583} 584 585static void test2(CSSM_DL_HANDLE dl) 586{ 587 CSSM_DL_DB_HANDLE dldb = { dl }; 588 CSSM_DB_UNIQUE_RECORD_PTR uniqueId; 589 590 ok_status(CSSM_DL_DbCreate(dl, DBNAME, NULL /* DbLocation */, 591 &dbInfo, 592 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE, 593 NULL /* CredAndAclEntry */, 594 NULL, 595 &dldb.DBHandle), 596 "CSSM_DL_DbCreate"); 597 598 ok_status(CSSM_DL_DbClose(dldb), 599 "CSSM_DL_DbClose"); 600 601 ok_status(CSSM_DL_DbOpen(dl, DBNAME, NULL /* DbLocation */, 602 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE, 603 NULL /* CredAndAclEntry */, 604 &openParameters, 605 &dldb.DBHandle), 606 "CSSM_DL_DbOpen"); 607 608 is_status(CSSM_DL_DataInsert(dldb, 609 attributes.DataRecordType, 610 &attributes, 611 NULL, 612 &uniqueId), 613 CSSMERR_DL_INVALID_RECORDTYPE, "CSSM_DL_DataInsert no table"); 614 615 ok_status(CSSM_DL_CreateRelation(dldb, 616 42, 617 "Fourty Two", 618 sizeof(attributeInfo) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO), 619 attributeInfo, 620 sizeof(indexInfo) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO), 621 indexInfo), "CSSM_DL_CreateRelation"); 622 623 ok_status(CSSM_DL_DataInsert(dldb, 624 attributes.DataRecordType, 625 &attributes, 626 NULL, 627 &uniqueId), "CSSM_DL_DataInsert fails unless 4039735 is fixed"); 628 629 is_status(CSSM_DL_DataInsert(dldb, 630 attributes.DataRecordType, 631 &attributes, 632 NULL, 633 &uniqueId), 634 CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA, 635 "CSSM_DL_DataInsert dupe"); 636 637 ok_status(CSSM_DL_DataDelete(dldb, uniqueId), 638 "CSSM_DL_Delete"); 639 640 is_status(CSSM_DL_DataDelete(dldb, uniqueId), 641 CSSMERR_DL_RECORD_NOT_FOUND, "delete again should fail"); 642 643 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 644 "CSSM_DL_FreeUniqueRecord"); 645 646 ok_status(CSSM_DL_DataInsert(dldb, 647 attributes.DataRecordType, 648 &attributes, 649 NULL, 650 &uniqueId), "Insert again after delete"); 651 652 ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId), 653 "CSSM_DL_FreeUniqueRecord"); 654 655 ok_status(CSSM_DL_DbClose(dldb), 656 "CSSM_DL_DbDelete"); 657} 658 659int 660main(int argc, char * const *argv) 661{ 662 int guid_alt = argc > 1 && !strcmp(argv[1], "-g"); 663 /* {2cb56191-ee6f-432d-a377-853d3c6b949e} */ 664 CSSM_GUID s3dl_guid = 665 { 666 0x2cb56191, 0xee6f, 0x432d, 667 { 0xa3, 0x77, 0x85, 0x3d, 0x3c, 0x6b, 0x94, 0x9e } 668 }; 669 const CSSM_GUID *guid = guid_alt ? & s3dl_guid : &gGuidAppleFileDL; 670 671 plan_tests(70); 672 673 CSSM_DL_HANDLE dl; 674 ok(cssm_attach(guid, &dl), "cssm_attach"); 675 ok(tests_begin(argc, argv), "tests_begin"); 676 677 test1(dl); 678 ok_status(CSSM_DL_DbDelete(dl, DBNAME, NULL /* DbLocation */, 679 NULL /* AccessCred */), "CSSM_DL_DbDelete"); 680 test2(dl); 681 ok_status(CSSM_DL_DbDelete(dl, DBNAME, NULL /* DbLocation */, 682 NULL /* AccessCred */), "CSSM_DL_DbDelete"); 683 ok(cssm_detach(guid, dl), "cssm_detach"); 684 ok_leaks("no leaks"); 685 686 return !tests_end(1); 687} 688