3 #include "attributes.h"
4 #include <security_cdsa_client/multidldb.h>
6 #include <security_cdsa_client/securestorage.h> // For CSPDL.
7 #include <security_cdsa_client/genkey.h>
8 #include <security_utilities/trackingallocator.h>
10 using namespace CssmClient
;
13 #define HEX_DIGITS_PER_LINE 20
17 const CSSM_GUID
* gSelectedFileGuid
= &gGuidAppleFileDL
;
21 static void testDLCreate(const Guid
&dlGuid
);
22 static void testDLDelete(const Guid
&dlGuid
, bool throwOnError
);
23 static void testGen(const Guid
&cspDlGuid
);
24 static void testDLCrypt(const Guid
&cspDlGuid
);
25 static void testMultiDLDb(const Guid
&dlGuid
);
26 static void dumpRelation(uint32 indent
, Db
&db
, uint32 relationID
, const char *relationName
, bool printSchema
);
27 static void dumpRecord(uint32 indent
, const DbAttributes
&record
, const CssmData
&data
, const DbUniqueRecord
&uniqueId
);
29 #define CSSM_DB_RELATION(RELATIONID) RecordAttrInfo ## RELATIONID
31 #define CSSM_DB_DEFINE_RELATION_BEGIN(RELATIONID) \
32 static const CSSM_DB_ATTRIBUTE_INFO AttrInfo ## RELATIONID[] =
34 #define CSSM_DB_DEFINE_RELATION_END(RELATIONID) \
36 static const CSSM_DB_RECORD_ATTRIBUTE_INFO CSSM_DB_RELATION(RELATIONID) = \
39 sizeof(AttrInfo ## RELATIONID) / sizeof(CSSM_DB_ATTRIBUTE_INFO), \
40 const_cast<CSSM_DB_ATTRIBUTE_INFO_PTR>(AttrInfo ## RELATIONID) \
44 CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
)
46 CSSM_DB_ATTR(Attributes::Class
),
47 CSSM_DB_ATTR(Attributes::CreationDate
),
48 CSSM_DB_ATTR(Attributes::ModDate
),
49 CSSM_DB_ATTR(Attributes::Description
),
50 CSSM_DB_ATTR(Attributes::Comment
),
51 CSSM_DB_ATTR(Attributes::Creator
),
52 CSSM_DB_ATTR(Attributes::Type
),
53 CSSM_DB_ATTR(Attributes::ScrCode
),
54 CSSM_DB_ATTR(Attributes::Label
),
55 CSSM_DB_ATTR(Attributes::Invisible
),
56 CSSM_DB_ATTR(Attributes::Negative
),
57 CSSM_DB_ATTR(Attributes::Custom
),
58 //CSSM_DB_ATTR(Attributes::Protected),
59 CSSM_DB_ATTR(Attributes::Account
),
60 CSSM_DB_ATTR(Attributes::Service
),
61 CSSM_DB_ATTR(Attributes::Generic
)
63 CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
);
66 // APPLESHARE PASSWORDS
67 CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
)
69 CSSM_DB_ATTR(Attributes::Class
),
70 CSSM_DB_ATTR(Attributes::CreationDate
),
71 CSSM_DB_ATTR(Attributes::ModDate
),
72 CSSM_DB_ATTR(Attributes::Description
),
73 CSSM_DB_ATTR(Attributes::Comment
),
74 CSSM_DB_ATTR(Attributes::Creator
),
75 CSSM_DB_ATTR(Attributes::Type
),
76 CSSM_DB_ATTR(Attributes::ScrCode
),
77 CSSM_DB_ATTR(Attributes::Label
),
78 CSSM_DB_ATTR(Attributes::Invisible
),
79 CSSM_DB_ATTR(Attributes::Negative
),
80 CSSM_DB_ATTR(Attributes::Custom
),
81 //CSSM_DB_ATTR(Attributes::Protected),
82 CSSM_DB_ATTR(Attributes::Volume
),
83 CSSM_DB_ATTR(Attributes::Addr
),
84 CSSM_DB_ATTR(Attributes::Signature
),
85 CSSM_DB_ATTR(Attributes::ProtocolType
)
87 CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
);
90 CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_INTERNET_PASSWORD
)
92 CSSM_DB_ATTR(Attributes::Class
),
93 CSSM_DB_ATTR(Attributes::CreationDate
),
94 CSSM_DB_ATTR(Attributes::ModDate
),
95 CSSM_DB_ATTR(Attributes::Description
),
96 CSSM_DB_ATTR(Attributes::Comment
),
97 CSSM_DB_ATTR(Attributes::Creator
),
98 CSSM_DB_ATTR(Attributes::Type
),
99 CSSM_DB_ATTR(Attributes::ScrCode
),
100 CSSM_DB_ATTR(Attributes::Label
),
101 CSSM_DB_ATTR(Attributes::Invisible
),
102 CSSM_DB_ATTR(Attributes::Negative
),
103 CSSM_DB_ATTR(Attributes::Custom
),
104 //CSSM_DB_ATTR(Attributes::Protected),
105 CSSM_DB_ATTR(Attributes::Account
),
106 CSSM_DB_ATTR(Attributes::SecDomain
),
107 CSSM_DB_ATTR(Attributes::Server
),
108 CSSM_DB_ATTR(Attributes::AuthType
),
109 CSSM_DB_ATTR(Attributes::Port
),
110 CSSM_DB_ATTR(Attributes::Path
),
111 CSSM_DB_ATTR(Attributes::ProtocolType
)
113 CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_INTERNET_PASSWORD
);
115 // INTERNET PASSWORDS
116 CSSM_DB_DEFINE_RELATION_BEGIN(CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
118 CSSM_DB_ATTR(Attributes::KeyClass
),
119 CSSM_DB_ATTR(Attributes::PrintName
),
120 CSSM_DB_ATTR(Attributes::Alias
),
121 CSSM_DB_ATTR(Attributes::Permanent
),
122 CSSM_DB_ATTR(Attributes::Private
),
123 CSSM_DB_ATTR(Attributes::Modifiable
),
124 CSSM_DB_ATTR(Attributes::Label
),
125 CSSM_DB_ATTR(Attributes::ApplicationTag
),
126 CSSM_DB_ATTR(Attributes::KeyCreator
),
127 CSSM_DB_ATTR(Attributes::KeyType
),
128 CSSM_DB_ATTR(Attributes::KeySizeInBits
),
129 CSSM_DB_ATTR(Attributes::EffectiveKeySize
),
130 CSSM_DB_ATTR(Attributes::StartDate
),
131 CSSM_DB_ATTR(Attributes::EndDate
),
132 CSSM_DB_ATTR(Attributes::Sensitive
),
133 CSSM_DB_ATTR(Attributes::AlwaysSensitive
),
134 CSSM_DB_ATTR(Attributes::Extractable
),
135 CSSM_DB_ATTR(Attributes::NeverExtractable
),
136 CSSM_DB_ATTR(Attributes::Encrypt
),
137 CSSM_DB_ATTR(Attributes::Decrypt
),
138 CSSM_DB_ATTR(Attributes::Derive
),
139 CSSM_DB_ATTR(Attributes::Sign
),
140 CSSM_DB_ATTR(Attributes::Verify
),
141 CSSM_DB_ATTR(Attributes::SignRecover
),
142 CSSM_DB_ATTR(Attributes::VerifyRecover
),
143 CSSM_DB_ATTR(Attributes::Wrap
),
144 CSSM_DB_ATTR(Attributes::UnWrap
)
146 CSSM_DB_DEFINE_RELATION_END(CSSM_DL_DB_RECORD_SYMMETRIC_KEY
);
149 static const CSSM_DB_RECORD_ATTRIBUTE_INFO KCAttrs
[] =
151 CSSM_DB_RELATION(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
),
152 CSSM_DB_RELATION(CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
),
153 CSSM_DB_RELATION(CSSM_DL_DB_RECORD_INTERNET_PASSWORD
)
154 //CSSM_DB_RELATION(CSSM_DL_DB_RECORD_SYMMETRIC_KEY)
157 static const CSSM_DB_RECORD_INDEX_INFO recordIndex
=
159 CSSM_DB_RECORDTYPE_APP_DEFINED_START
, // CSSM_DB_RECORDTYPE
163 static const CSSM_DB_RECORD_INDEX_INFO recordIndexes
[] = {recordIndex
, recordIndex
, recordIndex
};
165 // parse info (to improve later)
166 static const CSSM_DB_PARSING_MODULE_INFO parseInfo
=
168 CSSM_DB_RECORDTYPE_APP_DEFINED_START
,
176 static const CSSM_DB_PARSING_MODULE_INFO parseInfos
[] = {parseInfo
, parseInfo
, parseInfo
};
178 static const CSSM_DBINFO KCDBInfo
=
180 sizeof(KCAttrs
) / sizeof(CSSM_DB_RECORD_ATTRIBUTE_INFO
),
181 const_cast<CSSM_DB_PARSING_MODULE_INFO_PTR
>(parseInfos
),
182 const_cast<CSSM_DB_RECORD_ATTRIBUTE_INFO_PTR
>(KCAttrs
),
183 const_cast<CSSM_DB_RECORD_INDEX_INFO_PTR
>(recordIndexes
),
191 void dltests(bool autoCommit
)
193 testDLDelete(gGuidAppleFileDL
, false);
194 testDLCreate(gGuidAppleFileDL
);
195 testMultiDLDb(gGuidAppleFileDL
);
197 testDLDelete(gGuidAppleCSPDL
, false);
198 testDLCreate(gGuidAppleCSPDL
);
199 testGen(gGuidAppleCSPDL
);
200 testDLCrypt(gGuidAppleCSPDL
);
201 testMultiDLDb(gGuidAppleCSPDL
);
202 //testDLDelete(gGuidAppleCSPDL, true);
205 static void testDLCreate(const Guid
&dlGuid
)
208 Db
testDb(appledl
, DBNAME1
);
209 testDb
->dbInfo(&KCDBInfo
);
213 static void testDLDelete(const Guid
&dlGuid
, bool throwOnError
)
216 Db
testDb(appledl
, DBNAME1
);
223 if (throwOnError
|| e
.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST
)
228 static void testGen(const Guid
&cspDlGuid
)
230 printf("\n* performing CSP/DL keygen test...\n");
231 CSPDL
cspdl(cspDlGuid
);
232 Db
db(cspdl
, DBNAME1
);
234 printf("Generating permanent key\n");
235 GenerateKey
genKey(cspdl
, CSSM_ALGID_DES
, 64);
237 CssmPolyData
label("First Key!");
238 Key key
= genKey(KeySpec(CSSM_KEYUSE_ANY
,
239 CSSM_KEYATTR_PERMANENT
| CSSM_KEYATTR_SENSITIVE
,
244 static void testDLCrypt(const Guid
&cspDlGuid
)
246 printf("\n* performing encrypt/decrypt test...\n");
247 CSPDL
cspdl(cspDlGuid
);
248 Db
db(cspdl
, DBNAME1
);
250 printf("Finding key\n");
252 cursor
->recordType(CSSM_DL_DB_RECORD_SYMMETRIC_KEY
);
253 DbUniqueRecord keyId
;
254 CssmDataContainer keyData
;
255 if (!cursor
->next(NULL
, &keyData
, keyId
))
256 CssmError::throwMe(CSSMERR_DL_ENDOFDATA
);
258 Key
key(cspdl
, *reinterpret_cast<CSSM_KEY
*>(keyData
.Data
));
263 printf("Generating iv\n");
264 //CssmData iv = Random(csp, CSSM_ALGID_SHARandom)(8);
265 CssmPolyData
iv("12345678");
267 CssmPolyData
in("Om mani padme hum");
272 printf("Encrypting\n");
274 Encrypt
encrypt(cspdl
, CSSM_ALGID_DES
);
275 encrypt
.mode(CSSM_ALGMODE_CBCPadIV8
);
276 encrypt
.padding(CSSM_PADDING_PKCS1
);
277 encrypt
.initVector(iv
);
281 encrypt
.encrypt(&in
, 1, &cipher
, 1);
282 encrypt
.final(remcipher
);
283 printf("ciphertext=");
285 printf("remainder=");
289 printf("Decrypting\n");
291 Decrypt
decrypt(cspdl
, CSSM_ALGID_DES
);
293 decrypt
.mode(CSSM_ALGMODE_CBCPadIV8
);
294 decrypt
.padding(CSSM_PADDING_PKCS1
);
295 decrypt
.initVector(iv
);
298 CssmData inp
[] = { cipher
, remcipher
};
299 decrypt
.decrypt(inp
, 2, &plain
, 1);
300 decrypt
.final(remplain
);
301 printf("plaintext=");
303 printf("remainder=");
306 printf("end encrypt/decrypt test\n");
309 static void print(sint32 value
)
311 printf("%ld", value
);
314 static void print(double value
)
319 static void print(uint32 value
)
321 uint8
*bytes
= reinterpret_cast<uint8
*>(&value
);
323 for (uint32 ix
= 0; ix
< sizeof(uint32
); ++ix
)
324 if (bytes
[ix
] < 0x20 || bytes
[ix
] > 0x7f)
333 for (uint32 ix
= 0; ix
< sizeof(uint32
); ++ix
)
336 printf("' (0x%08lx)", value
);
339 printf("0x%08lx", value
);
342 static void printAsString(uint32 indent
, const CSSM_DATA
&value
)
344 printf("%.*s", static_cast<int>(value
.Length
), value
.Data
);
347 static void print(uint32 indent
, const char *value
)
352 static void printIndent(uint32 indent
)
358 for (uint32 ix
= 0; ix
< indent
; ++ix
)
362 static void printRange(uint32 length
, const uint8
*data
)
364 for (uint32 ix
= 0; ix
< HEX_DIGITS_PER_LINE
; ++ix
)
366 if (ix
&& ix
% 4 == 0)
370 printf("%02x", static_cast<unsigned int>(data
[ix
]));
376 for (uint32 ix
= 0; ix
< length
; ++ix
)
378 if (data
[ix
] < 0x20 || data
[ix
] > 0x7f)
385 static void print(uint32 indent
, const CSSM_DATA
&value
)
387 if (value
.Length
== 0)
390 if (value
.Length
> HEX_DIGITS_PER_LINE
)
393 for (ix
= 0; ix
< value
.Length
- HEX_DIGITS_PER_LINE
; ix
+= HEX_DIGITS_PER_LINE
)
396 printRange(HEX_DIGITS_PER_LINE
, &value
.Data
[ix
]);
399 printRange(value
.Length
- ix
, &value
.Data
[ix
]);
400 printIndent(indent
- INDENT_SIZE
);
403 printRange(value
.Length
, value
.Data
);
406 static void printOID(uint32 indent
, const CSSM_OID
&value
)
408 print(indent
, value
);
411 static const char *format(CSSM_DB_ATTRIBUTE_FORMAT format
)
415 case CSSM_DB_ATTRIBUTE_FORMAT_STRING
: return "string";
416 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
: return "sint32";
417 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
: return "uint32";
418 case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM
: return "big_num";
419 case CSSM_DB_ATTRIBUTE_FORMAT_REAL
: return "real";
420 case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
: return "time_date";
421 case CSSM_DB_ATTRIBUTE_FORMAT_BLOB
: return "blob";
422 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
: return "multi_uint32";
423 case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
: return "complex";
428 static void print(uint32 indent
, const CssmDbAttributeData
&attr
)
430 bool multiValues
= false;
431 if (attr
.size() == 0)
437 if (attr
.size() != 1)
441 indent
+= INDENT_SIZE
;
445 for (uint32 ix
= 0; ix
< attr
.size(); ++ix
)
450 printf("<%s>", format(attr
.format()));
451 switch (attr
.format())
453 case CSSM_DB_ATTRIBUTE_FORMAT_STRING
:
454 printAsString(indent
+ INDENT_SIZE
, attr
.at(ix
));
456 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
:
457 print(attr
.at
<uint32
>(ix
));
459 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
:
460 print(attr
.at
<sint32
>(ix
));
462 case CSSM_DB_ATTRIBUTE_FORMAT_REAL
:
463 print(attr
.at
<double>(ix
));
465 case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
:
466 printf("%*s", 15, attr
.at
<const char *>(ix
));
468 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
:
469 case CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM
:
470 case CSSM_DB_ATTRIBUTE_FORMAT_BLOB
:
471 case CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
:
473 print(indent
+ INDENT_SIZE
, attr
.at
<const CssmData
&>(ix
));
476 printf("</%s>", format(attr
.format()));
481 indent
-= INDENT_SIZE
;
487 static void print(uint32 indent
, const CssmDbAttributeInfo
&info
)
489 switch (info
.nameFormat())
491 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
494 print(indent
+ INDENT_SIZE
, info
.Label
.AttributeName
);
498 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
501 print(info
.Label
.AttributeID
);
502 printf("</integer>");
505 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
508 printOID(indent
+ INDENT_SIZE
, info
.Label
.AttributeOID
);
513 throw Error(CSSMERR_DL_DATABASE_CORRUPT
);
517 void dumpDb(char *dbName
, bool printSchema
)
519 DL
appledl(*gSelectedFileGuid
);
520 Db
db(appledl
, dbName
);
521 DbCursor
relations(db
);
522 relations
->recordType(CSSM_DL_DB_SCHEMA_INFO
);
523 DbAttributes
schemaRecord(db
, 2);
524 schemaRecord
.add(Attributes::RelationID
);
525 schemaRecord
.add(Attributes::RelationName
);
526 CssmDataContainer data
;
527 DbUniqueRecord
uniqueId(db
);
530 printf("<database>");
531 indent
+= INDENT_SIZE
;
533 printf("<name>%s</name>", dbName
);
534 while (relations
->next(&schemaRecord
, &data
, uniqueId
))
536 uint32 relationID
= schemaRecord
.at(0);
537 if (!printSchema
&& CSSM_DB_RECORDTYPE_SCHEMA_START
<= relationID
538 && relationID
< CSSM_DB_RECORDTYPE_SCHEMA_END
)
542 printf("<relation>");
543 string relationName
= schemaRecord
.at(1);
544 dumpRelation(indent
+ INDENT_SIZE
, db
, relationID
, relationName
.c_str(), printSchema
);
546 printf("</relation>");
549 indent
-= INDENT_SIZE
;
551 printf("</database>\n");
554 static void dumpRelation(uint32 indent
, Db
&db
, uint32 relationID
, const char *relationName
, bool printSchema
)
556 TrackingAllocator
anAllocator(Allocator::standard());
560 print(indent
+ INDENT_SIZE
, relationName
);
567 // Create a cursor on the SCHEMA_ATTRIBUTES table for records with RelationID == relationID
568 DbCursor
attributes(db
);
569 attributes
->recordType(CSSM_DL_DB_SCHEMA_ATTRIBUTES
);
570 attributes
->add(CSSM_DB_EQUAL
, Attributes::RelationID
, relationID
);
572 // Set up a record for retriving the SCHEMA_ATTRIBUTES
573 DbAttributes
schemaRecord(db
, 5);
574 schemaRecord
.add(Attributes::AttributeNameFormat
);
575 schemaRecord
.add(Attributes::AttributeFormat
);
576 schemaRecord
.add(Attributes::AttributeName
);
577 schemaRecord
.add(Attributes::AttributeID
);
578 schemaRecord
.add(Attributes::AttributeNameID
);
580 DbAttributes
record(db
);
581 CssmDataContainer data
;
582 DbUniqueRecord
uniqueId(db
);
588 indent
+= INDENT_SIZE
;
591 while (attributes
->next(&schemaRecord
, &data
, uniqueId
))
593 CssmDbAttributeInfo
&anInfo
= record
.add().info();
594 anInfo
.AttributeNameFormat
= schemaRecord
.at(0);
595 anInfo
.AttributeFormat
= schemaRecord
.at(1);
596 switch (anInfo
.AttributeNameFormat
)
598 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
600 CssmDbAttributeData
&anAttributeName
= schemaRecord
.at(2);
602 string name
= static_cast<string
>(anAttributeName
);
603 anInfo
.Label
.AttributeName
= reinterpret_cast<char *>(anAllocator
.malloc(name
.size() + 1));
604 strcpy(anInfo
.Label
.AttributeName
, name
.c_str());
606 // XXX Need to copy the memory. For now avoid it being freed.
607 anAttributeName
.Value
[0].Data
= NULL
;
608 anAttributeName
.Value
[0].Length
= 0;
611 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
613 CssmDbAttributeData
&anAttributeID
= schemaRecord
.at(3);
614 anInfo
.Label
.AttributeID
= anAttributeID
;
617 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
619 CssmDbAttributeData
&anAttributeOID
= schemaRecord
.at(4);
620 anInfo
.Label
.AttributeOID
= anAttributeOID
;
622 // XXX Need to copy the memory. For now avoid it being freed.
623 anAttributeOID
.Value
[0].Data
= NULL
;
624 anAttributeOID
.Value
[0].Length
= 0;
628 throw Error(CSSMERR_DL_DATABASE_CORRUPT
);
634 print(indent
, anInfo
);
635 printf("<format>%s</format>", format(anInfo
.format()));
641 indent
-= INDENT_SIZE
;
646 DbCursor
records(db
);
647 records
->recordType(relationID
);
650 indent
+= INDENT_SIZE
;
651 while (records
->next(&record
, &data
, uniqueId
))
652 dumpRecord(indent
, record
, data
, uniqueId
);
654 indent
-= INDENT_SIZE
;
656 printf("</records>");
660 dumpRecord(uint32 indent
, const DbAttributes
&record
, const CssmData
&data
, const DbUniqueRecord
&uniqueId
)
662 const CSSM_DB_UNIQUE_RECORD
*recId
= static_cast<const DbUniqueRecord
&>(uniqueId
);
663 uint32 recCount
= recId
->RecordIdentifier
.Length
;
664 const uint32
*recArray
= reinterpret_cast<const uint32
*>(recId
->RecordIdentifier
.Data
);
667 for (uint32 ix
= 0; ix
< recCount
/ 4; ++ix
)
671 printf("0x%08lx", recArray
[ix
]);
675 // Print the attributes
677 if (record
.size() == 0)
679 printf("<attributes/>");
683 printf("<attributes>");
684 indent
+= INDENT_SIZE
;
685 for (uint32 ix
= 0; ix
< record
.size(); ix
++)
687 const CssmDbAttributeData
&anAttr
= record
.at(ix
);
688 if (anAttr
.size()) // Skip zero valued attributes.
691 print(indent
+ INDENT_SIZE
, anAttr
.info());
692 print(indent
+ INDENT_SIZE
, anAttr
);
696 indent
-= INDENT_SIZE
;
698 printf("</attributes>");
706 print(indent
+ INDENT_SIZE
, data
);
713 static void testMultiDLDb(const Guid
&dlGuid
)
715 // Setup a list of DLDbIdentifier object to hand off the MultiDLDb.
716 vector
<DLDbIdentifier
> list
;
717 list
.push_back(DLDbIdentifier(CssmSubserviceUid(dlGuid
), "multidb1.db", NULL
));
718 list
.push_back(DLDbIdentifier(CssmSubserviceUid(dlGuid
), "multidb2.db", NULL
));
720 // Create MultiDLDb instance.
721 MultiDLDb
multiDLDb(list
, false);
723 // Get a handle for the first and second Db.
724 Db
db1(multiDLDb
->database(list
[0]));
725 Db
db2(multiDLDb
->database(list
[1]));
727 // Until this point no CSSM API's have been called!
729 // Delete both databases if they exist.
733 { if (e
.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST
) throw; }
738 { if (e
.osStatus() != CSSMERR_DL_DATASTORE_DOESNOT_EXIST
) throw; }
740 // XXX Note to self if you set the schema but do not call create()
741 // explicitly maybe the db should only be created if it did not yet exist...
743 // Set the schema of both databases so they get created on activate.
744 db1
->dbInfo(&KCDBInfo
);
745 db2
->dbInfo(&KCDBInfo
);
747 // Insert a record into each database.
748 DbAttributes
attrs(db1
);
749 attrs
.add(Attributes::Comment
, "This is the first comment").add("This is the second comment", attrs
);
750 attrs
.add(Attributes::Label
, "Item1");
751 CssmPolyData
testdata1("testdata1");
752 db1
->insert(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
, &attrs
, &testdata1
);
755 attrs
.add(Attributes::Comment
, "This is the second comment");
756 attrs
.add(Attributes::Label
, "Item (in database2).");
757 CssmPolyData
testdata2("testdata2");
758 db2
->insert(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
, &attrs
, &testdata2
);
760 // Create a cursor on the multiDLDb.
761 DbCursor
cursor(multiDLDb
);
762 // Set the type of records we wish to query.
763 cursor
->recordType(CSSM_DL_DB_RECORD_GENERIC_PASSWORD
);
764 cursor
->add(CSSM_DB_EQUAL
, Attributes::Comment
, "This is the second comment");
766 DbUniqueRecord uniqueId
; // Empty uniqueId calling cursor.next will initialize.
767 CssmDataContainer data
; // XXX Think about data's allocator.
769 // Iterate over the records in all the db's in the multiDLDb.
770 while (cursor
->next(&attrs
, &data
, uniqueId
))
772 // Print the record data.
773 dumpRecord(0, attrs
, data
, uniqueId
);
778 CssmDb::Impl
*CssmDL::Impl::newDb(args
) { new CssmDbImpl(args
); }
780 SecureStorage
ss(Guid
);
781 CssmDb
db(ss
, DBNAME
);
783 db
.insert(attr
, data
, unique
);
794 SecureStorage
ss(Guid
);
795 CssmDb db
= ss
->db(DBNAME
);
797 db
->insert(attr
, data
, unique
);