]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/dbTool/dbTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / dbTool / dbTool.cpp
1 /* Copyright (c) 2002-2006 Apple Computer, Inc.
2 *
3 * dbTool.cpp - DL/DB tool.
4 */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <time.h>
8 #include <strings.h>
9 #include <ctype.h>
10 #include <Security/cssm.h>
11 #include <Security/cssmapple.h>
12 #include <Security/cssmapplePriv.h>
13 #include "cspwrap.h"
14 #include "common.h"
15 #include "dbAttrs.h"
16 #include "dbCert.h"
17 #include "cspdlTesting.h"
18
19
20 static void usage(char **argv)
21 {
22 printf("usage: %s dbFileName command [options]\n", argv[0]);
23 printf("Commands:\n");
24 printf(" r Dump Schema Relations\n");
25 printf(" k Dump all keys\n");
26 printf(" c Dump certs\n");
27 printf(" a Dump all records\n");
28 printf(" d Delete records (interactively)\n");
29 printf(" D Delete records (noninteractively, requires really arg)\n");
30 printf(" i Import bad cert and its (good) private key\n");
31 printf("Options:\n");
32 printf(" v verbose\n");
33 printf(" q quiet\n");
34 printf(" R really! (for D command)\n");
35 printf(" d dump data\n");
36 printf(" c=certFile\n");
37 printf(" k=keyFile\n");
38 exit(1);
39 }
40
41
42 static unsigned indentVal = 0;
43 static void indentIncr()
44 {
45 indentVal += 3;
46 }
47
48 static void indentDecr()
49 {
50 if(indentVal) {
51 indentVal -= 3;
52 }
53 }
54
55 static void doIndent()
56 {
57 unsigned i;
58 for(i=0; i<indentVal; i++) {
59 printf(" ");
60 }
61 }
62
63 #define NORM_KEY_LEN 20
64
65 /* print an attribute name, padding out to NORM_KEY_LEN columns */
66 static void printName(
67 const CSSM_DB_ATTRIBUTE_INFO *attrInfo)
68 {
69 switch(attrInfo->AttributeNameFormat) {
70 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
71 {
72 char *attrName = attrInfo->Label.AttributeName;
73 printf("%s", attrName);
74 int len = strlen(attrName);
75 if(len > NORM_KEY_LEN) {
76 return;
77 }
78 int numSpaces = NORM_KEY_LEN - len;
79 for(int i=0; i<numSpaces; i++) {
80 putchar(' ');
81 }
82 break;
83 }
84 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
85 {
86 /* OSType, endian dependent... */
87 char *cp = (char *)&(attrInfo->Label.AttributeID);
88 for(unsigned i=0; i<4; i++) {
89 putchar(*cp++);
90 }
91 printf(" ");
92 break;
93 }
94 default:
95 printf("Unknown attribute name format (%u)\n",
96 (unsigned)attrInfo->AttributeNameFormat);
97 break;
98 }
99 }
100
101 /*
102 * Attempt to print a numeric value as a string, per a NameValuePair table.
103 * If the value is in fact a collection of legal values (per the nameValues
104 * array), the value will just be printed in hex.
105 */
106 static void printValueAsString(
107 unsigned val,
108 const NameValuePair *nameValues)
109 {
110 if(nameValues != NULL) {
111 while(nameValues->name != NULL) {
112 if(nameValues->value == val) {
113 printf("%s", nameValues->name);
114 return;
115 }
116 nameValues++;
117 }
118 }
119 /* Oh well */
120 printf("0x%x", val);
121 }
122
123 static void safePrint(
124 uint8 *cp,
125 uint32 len)
126 {
127 for(unsigned i=0; i<len; i++) {
128 printf("%c", *cp++);
129 }
130 }
131
132 /* See if a blob is printable. Used for BLOB and UINT32 types, the latter of
133 * which is sometimes used for OSType representation of attr name. */
134 bool isPrintable(
135 const CSSM_DATA *dp)
136 {
137 bool printable = true;
138 uint8 *cp = dp->Data;
139 for(unsigned i=0; i<dp->Length; i++) {
140 if(*cp == 0) {
141 if(i != (dp->Length - 1)) {
142 /* data contains NULL character before end */
143 printable = false;
144 }
145 /* else end of string */
146 break;
147 }
148 if(!isprint(*cp)) {
149 printable = false;
150 break;
151 }
152 cp++;
153 }
154 return printable;
155 }
156
157 #define MAX_BLOB_TO_PRINT 12
158 static void printBlob(
159 const CSSM_DATA *data)
160 {
161 unsigned toPrint = data->Length;
162 if(toPrint > MAX_BLOB_TO_PRINT) {
163 toPrint = MAX_BLOB_TO_PRINT;
164 }
165 for(unsigned i=0; i<toPrint; i++) {
166 unsigned dat = data->Data[i];
167 printf("%02X ", dat);
168 }
169 if(toPrint < data->Length) {
170 printf("...");
171 }
172 }
173
174 static void printAttrData(
175 const CSSM_DB_ATTRIBUTE_INFO *attrInfo,
176 const CSSM_DATA *attrData,
177 const NameValuePair *nameValues) // optional
178 {
179 void *data = attrData->Data;
180
181 switch(attrInfo->AttributeFormat) {
182
183 case CSSM_DB_ATTRIBUTE_FORMAT_STRING:
184 putchar('\'');
185 safePrint(attrData->Data, attrData->Length);
186 putchar('\'');
187 break;
188 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32:
189 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
190 {
191 unsigned val = *(unsigned *)data;
192 printValueAsString(val, nameValues);
193 break;
194 }
195 case CSSM_DB_ATTRIBUTE_FORMAT_BLOB:
196 {
197 printf("BLOB length %u : ", (unsigned)attrData->Length);
198 /* see if it happens to be a printable string */
199 if(isPrintable(attrData)) {
200 putchar('\'');
201 safePrint(attrData->Data, attrData->Length);
202 putchar('\'');
203 }
204 else {
205 printBlob(attrData);
206 }
207 break;
208 }
209 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
210 {
211 printf("multi_int[");
212 uint32 numInts = attrData->Length / sizeof(uint32);
213 uint32 *uip = (uint32 *)data;
214 for(unsigned i=0; i<numInts; i++) {
215 if(i > 0) {
216 printf(", ");
217 }
218 printValueAsString(*uip++, nameValues);
219 }
220 printf("]");
221 break;
222 }
223 case CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE:
224 putchar('\'');
225 safePrint(attrData->Data, attrData->Length);
226 putchar('\'');
227 break;
228
229 default:
230 printf("***UNKNOWN FORMAT (%u), Length %u",
231 (unsigned)attrInfo->AttributeFormat, (unsigned)attrData->Length);
232 break;
233 }
234 }
235
236 /* free attribute(s) allocated by DL */
237 static void freeAttrs(
238 CSSM_DB_RECORD_ATTRIBUTE_DATA *recordAttrs)
239 {
240 unsigned i;
241
242 for(i=0; i<recordAttrs->NumberOfAttributes; i++) {
243 CSSM_DB_ATTRIBUTE_DATA_PTR attrData = &recordAttrs->AttributeData[i];
244 if(attrData == NULL) {
245 /* fault of caller, who allocated the CSSM_DB_ATTRIBUTE_DATA */
246 printf("***freeAttrs screwup: NULL attrData\n");
247 return;
248 }
249 unsigned j;
250 for(j=0; j<attrData->NumberOfValues; j++) {
251 CSSM_DATA_PTR data = &attrData->Value[j];
252 if(data == NULL) {
253 /* fault of MDS, who said there was a value here */
254 printf("***freeAttrs screwup: NULL data\n");
255 return;
256 }
257 CSSM_FREE(data->Data);
258 data->Data = NULL;
259 data->Length = 0;
260 }
261 CSSM_FREE(attrData->Value);
262 attrData->Value = NULL;
263 }
264 }
265
266 static void dumpDataBlob(
267 const CSSM_DATA *datap)
268 {
269 doIndent();
270 printf("Record data length %lu ", datap->Length);
271 if(datap->Length != 0) {
272 printf(" : ");
273 printBlob(datap);
274 }
275 printf("\n");
276 }
277
278 static void dumpRecordAttrs(
279 const CSSM_DB_RECORD_ATTRIBUTE_DATA *recordAttrs,
280 const NameValuePair **nameValues, // parallel to recordAttrs
281 const CSSM_DATA *recordData = NULL) // optional data
282 {
283 unsigned valNum;
284 unsigned dex;
285
286 for(dex=0; dex<recordAttrs->NumberOfAttributes; dex++) {
287 const CSSM_DB_ATTRIBUTE_DATA *attrData = &recordAttrs->AttributeData[dex];
288 doIndent();
289 printName(&attrData->Info);
290 printf(": ");
291 if(attrData->NumberOfValues == 0) {
292 printf("<<not present>>\n");
293 continue;
294 }
295 for(valNum=0; valNum<attrData->NumberOfValues; valNum++) {
296 printAttrData(&attrData->Info, &attrData->Value[valNum], nameValues[dex]);
297 if(valNum < (attrData->NumberOfValues - 1)) {
298 printf(", ");
299 }
300 }
301 printf("\n");
302 }
303 if(recordData) {
304 dumpDataBlob(recordData);
305 }
306 }
307
308 static void dumpRelation(
309 CSSM_DL_DB_HANDLE dlDbHand,
310 const RelationInfo *relInfo,
311 CSSM_BOOL dumpData)
312 {
313 CSSM_QUERY query;
314 CSSM_DB_UNIQUE_RECORD_PTR record = NULL;
315 CSSM_RETURN crtn;
316 CSSM_HANDLE resultHand;
317 CSSM_DB_ATTRIBUTE_DATA *attrs;
318 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
319 unsigned attrDex;
320 unsigned recNum = 0;
321 uint32 numAttrs = relInfo->NumberOfAttributes;
322 CSSM_DATA data = {0, NULL};
323 CSSM_DATA_PTR datap = NULL;
324
325 if(dumpData) {
326 datap = &data;
327 }
328
329 /* build an attr array from known schema */
330 attrs = (CSSM_DB_ATTRIBUTE_DATA *)CSSM_MALLOC(
331 sizeof(CSSM_DB_ATTRIBUTE_DATA) * numAttrs);
332 memset(attrs, 0, sizeof(CSSM_DB_ATTRIBUTE_DATA) * numAttrs);
333 for(attrDex=0; attrDex<numAttrs; attrDex++) {
334 attrs[attrDex].Info = relInfo->AttributeInfo[attrDex];
335 }
336 recordAttrs.DataRecordType = relInfo->DataRecordType;
337 recordAttrs.NumberOfAttributes = numAttrs;
338 recordAttrs.AttributeData = attrs;
339
340 /* just search by recordType, no predicates */
341 query.RecordType = relInfo->DataRecordType;
342 query.Conjunctive = CSSM_DB_NONE;
343 query.NumSelectionPredicates = 0;
344 query.SelectionPredicate = NULL;
345 query.QueryLimits.TimeLimit = 0; // FIXME - meaningful?
346 query.QueryLimits.SizeLimit = 1; // FIXME - meaningful?
347 query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA...FIXME - used?
348
349 crtn = CSSM_DL_DataGetFirst(dlDbHand,
350 &query,
351 &resultHand,
352 &recordAttrs,
353 datap,
354 &record);
355 switch(crtn) {
356 case CSSM_OK:
357 break; // proceed
358 case CSSMERR_DL_ENDOFDATA:
359 printf("%s: no record found\n", relInfo->relationName);
360 CSSM_FREE(attrs);
361 return;
362 default:
363 printError("DataGetFirst", crtn);
364 CSSM_FREE(attrs);
365 return;
366 }
367 printf("%s:\n", relInfo->relationName);
368 printf(" record %d; numAttrs %d:\n",
369 recNum++, (int)recordAttrs.NumberOfAttributes);
370 indentIncr();
371
372 dumpRecordAttrs(&recordAttrs, relInfo->nameValues, datap);
373 CSSM_DL_FreeUniqueRecord(dlDbHand, record);
374 freeAttrs(&recordAttrs);
375 if(datap) {
376 CSSM_FREE(datap->Data);
377 }
378
379 /* now the rest of them */
380 /* hopefully we don't have to re-init the recordAttr array */
381 for(;;) {
382 crtn = CSSM_DL_DataGetNext(dlDbHand,
383 resultHand,
384 &recordAttrs,
385 datap,
386 &record);
387 switch(crtn) {
388 case CSSM_OK:
389 printf(" record %d; numAttrs %d:\n",
390 recNum++, (int)recordAttrs.NumberOfAttributes);
391 dumpRecordAttrs(&recordAttrs, relInfo->nameValues, datap);
392 CSSM_DL_FreeUniqueRecord(dlDbHand, record);
393 freeAttrs(&recordAttrs);
394 if(datap) {
395 CSSM_FREE(datap->Data);
396 }
397 break; // and go again
398 case CSSMERR_DL_ENDOFDATA:
399 /* normal termination */
400 break;
401 default:
402 printError("DataGetNext", crtn);
403 break;
404 }
405 if(crtn != CSSM_OK) {
406 break;
407 }
408 }
409 indentDecr();
410 CSSM_FREE(attrs);
411 }
412
413 /*
414 * Given a record type and a CSSM_DB_UNIQUE_RECORD, fetch and parse all the
415 * attributes we can.
416 */
417 static void fetchParseRecord(
418 CSSM_DL_DB_HANDLE dlDbHand,
419 CSSM_DB_RECORD_ATTRIBUTE_DATA *inRecordAttrs,
420 CSSM_DB_UNIQUE_RECORD_PTR record,
421 const CSSM_DATA_PTR datap,
422 CSSM_BOOL dumpData)
423 {
424 const RelationInfo *relInfo = NULL;
425
426 /* infer RelationInfo from recordType */
427 switch(inRecordAttrs->DataRecordType) {
428 case CSSM_DL_DB_RECORD_PUBLIC_KEY:
429 case CSSM_DL_DB_RECORD_PRIVATE_KEY:
430 case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
431 relInfo = &allKeysRelation;
432 break;
433 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD:
434 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD:
435 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD:
436 relInfo = &genericKcRelation;
437 break;
438 case CSSM_DL_DB_RECORD_CERT:
439 relInfo = &certRecordRelation;
440 break;
441 case CSSM_DL_DB_RECORD_X509_CERTIFICATE:
442 relInfo = &x509CertRecordRelation;
443 break;
444 case CSSM_DL_DB_RECORD_X509_CRL:
445 relInfo = &x509CrlRecordRelation;
446 break;
447 case CSSM_DL_DB_RECORD_USER_TRUST:
448 relInfo = &userTrustRelation;
449 break;
450 case CSSM_DL_DB_RECORD_UNLOCK_REFERRAL:
451 relInfo = &referralRecordRelation;
452 break;
453 case CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE:
454 relInfo = &extendedAttrRelation;
455 break;
456 case DBBlobRelationID:
457 relInfo = NULL;
458 doIndent();
459 printf("--- No attributes ---\n");
460 if(dumpData) {
461 dumpDataBlob(datap);
462 }
463 return;
464 default:
465 doIndent();
466 printf("<<unparsed>>\n");
467 if(dumpData) {
468 doIndent();
469 printf("Record blob (length %ld): ", datap->Length);
470 printBlob(datap);
471 printf("\n");
472 }
473 return;
474 }
475
476 CSSM_DB_ATTRIBUTE_DATA *attrs = NULL;
477 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
478 unsigned attrDex;
479 uint32 numAttrs = relInfo->NumberOfAttributes;
480 CSSM_RETURN crtn;
481 CSSM_DATA recordData = {0, NULL};
482 CSSM_DATA_PTR recordDataP = dumpData ? &recordData : NULL;
483
484 /* build an attr array from known schema */
485 attrs = (CSSM_DB_ATTRIBUTE_DATA *)CSSM_MALLOC(
486 sizeof(CSSM_DB_ATTRIBUTE_DATA) * numAttrs);
487 memset(attrs, 0, sizeof(CSSM_DB_ATTRIBUTE_DATA) * numAttrs);
488 for(attrDex=0; attrDex<numAttrs; attrDex++) {
489 attrs[attrDex].Info = relInfo->AttributeInfo[attrDex];
490 }
491
492 /* from inRecordAttrs, not the relInfo, which could be a typeless template */
493 recordAttrs.DataRecordType = relInfo->DataRecordType;
494 recordAttrs.NumberOfAttributes = numAttrs;
495 recordAttrs.AttributeData = attrs;
496
497 crtn = CSSM_DL_DataGetFromUniqueRecordId(dlDbHand,
498 record,
499 &recordAttrs,
500 recordDataP);
501 if(crtn) {
502 printError("CSSM_DL_DataGetFromUniqueRecordId", crtn);
503 goto abort;
504 }
505 dumpRecordAttrs(&recordAttrs, relInfo->nameValues, recordDataP);
506 freeAttrs(&recordAttrs);
507 if(recordData.Data) {
508 CSSM_FREE(recordData.Data);
509 }
510 abort:
511 if(attrs) {
512 CSSM_FREE(attrs);
513 }
514 return;
515 }
516
517 static void deleteRecord(
518 CSSM_DL_DB_HANDLE dlDbHand,
519 CSSM_DB_UNIQUE_RECORD_PTR record,
520 CSSM_BOOL interact)
521 {
522 if(interact) {
523 fpurge(stdin);
524 printf("\nDelete this record [y/anything] ? ");
525 char resp = getchar();
526 if(resp != 'y') {
527 return;
528 }
529 }
530 CSSM_RETURN crtn;
531 crtn = CSSM_DL_DataDelete(dlDbHand, record);
532 if(crtn) {
533 printError("CSSM_DL_DataDelete", crtn);
534 }
535 else if(interact) {
536 printf("...record deleted\n\n");
537 }
538 }
539
540 /*
541 * In this case we search for CSSM_DL_DB_RECORD_ANY. The current schema results
542 * in no single attribute which all interesting records have in common, so we
543 * can't grab any attributes at GetFirst/GetNext time. Instead we have
544 * to deal with the returned record per its record type.
545 */
546 static void dumpAllRecords(
547 CSSM_DL_DB_HANDLE dlDbHand,
548 CSSM_BOOL deleteAll,
549 CSSM_BOOL interact,
550 CSSM_BOOL dumpData)
551 {
552 CSSM_QUERY query;
553 CSSM_DB_UNIQUE_RECORD_PTR record = NULL;
554 CSSM_RETURN crtn;
555 CSSM_HANDLE resultHand;
556 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
557 CSSM_DATA data = {0, NULL};
558 CSSM_DATA_PTR datap = NULL;
559
560 if(dumpData) {
561 datap = &data;
562 }
563
564 recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_ANY;
565 recordAttrs.NumberOfAttributes = 0;
566 recordAttrs.AttributeData = NULL;
567
568 /* just search by recordType, no predicates */
569 query.RecordType = CSSM_DL_DB_RECORD_ANY;
570 query.Conjunctive = CSSM_DB_NONE;
571 query.NumSelectionPredicates = 0;
572 query.SelectionPredicate = NULL;
573 query.QueryLimits.TimeLimit = 0; // FIXME - meaningful?
574 query.QueryLimits.SizeLimit = 1; // FIXME - meaningful?
575 query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA...FIXME - used?
576
577 crtn = CSSM_DL_DataGetFirst(dlDbHand,
578 &query,
579 &resultHand,
580 &recordAttrs,
581 datap,
582 &record);
583 switch(crtn) {
584 case CSSM_OK:
585 break; // proceed
586 case CSSMERR_DL_ENDOFDATA:
587 printf("CSSM_DL_DB_RECORD_ANY: no record found\n");
588 return;
589 default:
590 printError("DataGetFirst", crtn);
591 return;
592 }
593
594 /* could be anything; check it out */
595 if(interact) {
596 doIndent();
597 printValueAsString(recordAttrs.DataRecordType, recordTypeNames);
598 printf("\n");
599 indentIncr();
600 fetchParseRecord(dlDbHand, &recordAttrs, record, datap, dumpData);
601 indentDecr();
602 }
603 if(deleteAll && (recordAttrs.DataRecordType != DBBlobRelationID)) {
604 /* NEVER delete a DBBlob */
605 deleteRecord(dlDbHand, record, interact);
606 }
607 CSSM_DL_FreeUniqueRecord(dlDbHand, record);
608
609 /* now the rest of them */
610 /* hopefully we don't have to re-init the recordAttr array */
611 for(;;) {
612 crtn = CSSM_DL_DataGetNext(dlDbHand,
613 resultHand,
614 &recordAttrs,
615 datap,
616 &record);
617 switch(crtn) {
618 case CSSM_OK:
619 if(interact) {
620 doIndent();
621 printValueAsString(recordAttrs.DataRecordType, recordTypeNames);
622 printf("\n");
623 indentIncr();
624 fetchParseRecord(dlDbHand, &recordAttrs, record, datap, dumpData);
625 indentDecr();
626 }
627 if(deleteAll && (recordAttrs.DataRecordType != DBBlobRelationID)) {
628 /* NEVER delete a DBBlob */
629 deleteRecord(dlDbHand, record, interact);
630 }
631 CSSM_DL_FreeUniqueRecord(dlDbHand, record);
632 break; // and go again
633 case CSSMERR_DL_ENDOFDATA:
634 /* normal termination */
635 break;
636 default:
637 printError("DataGetNext", crtn);
638 break;
639 }
640 if(crtn != CSSM_OK) {
641 break;
642 }
643 }
644 }
645
646 int main(
647 int argc,
648 char **argv)
649 {
650 int arg;
651 char *argp;
652 char *dbFileName;
653 char cmd;
654 CSSM_DL_DB_HANDLE dlDbHand;
655 CSSM_BOOL verbose = CSSM_FALSE;
656 CSSM_BOOL quiet = CSSM_FALSE;
657 char *certFile = NULL;
658 char *keyFile = NULL;
659 CSSM_BOOL interact = CSSM_TRUE;
660 CSSM_BOOL dumpData = CSSM_FALSE;
661
662 /* should be cmd line opts */
663 CSSM_ALGORITHMS keyAlg = CSSM_ALGID_RSA;
664 CSSM_BOOL pemFormat = CSSM_FALSE;
665 CSSM_KEYBLOB_FORMAT keyFormat = CSSM_KEYBLOB_RAW_FORMAT_NONE;
666 CSSM_RETURN crtn = CSSM_OK;
667
668 if(argc < 3) {
669 usage(argv);
670 }
671 dbFileName = argv[1];
672 cmd = argv[2][0];
673
674 for(arg=3; arg<argc; arg++) {
675 argp = argv[arg];
676 switch(argp[0]) {
677 case 'v':
678 verbose = CSSM_TRUE;
679 break;
680 case 'q':
681 quiet = CSSM_TRUE;
682 break;
683 case 'R':
684 if(cmd == 'D') {
685 interact = CSSM_FALSE;
686 }
687 break;
688 case 'd':
689 dumpData = CSSM_TRUE;
690 break;
691 case 'c':
692 certFile = &argp[2];
693 break;
694 case 'k':
695 keyFile = &argp[2];
696 break;
697 case 'h':
698 default:
699 usage(argv);
700 }
701 }
702
703 dlDbHand.DLHandle = dlStartup();
704 if(dlDbHand.DLHandle == 0) {
705 exit(1);
706 }
707 if(cmd == 'i') {
708 crtn = importBadCert(dlDbHand.DLHandle, dbFileName, certFile,
709 keyFile, keyAlg, pemFormat, keyFormat, verbose);
710 goto done;
711 }
712 crtn = dbCreateOpen(dlDbHand.DLHandle, dbFileName,
713 CSSM_FALSE, CSSM_FALSE, NULL, &dlDbHand.DBHandle);
714 if(crtn) {
715 exit(1);
716 }
717 switch(cmd) {
718 case 'r':
719 dumpRelation(dlDbHand, &schemaInfoRelation, dumpData);
720 break;
721 case 'k':
722 dumpRelation(dlDbHand, &allKeysRelation, dumpData);
723 break;
724 case 'c':
725 dumpRelation(dlDbHand, &x509CertRecordRelation, dumpData);
726 break;
727 case 'a':
728 dumpAllRecords(dlDbHand, CSSM_FALSE, CSSM_TRUE, dumpData);
729 break;
730 case 'd':
731 case 'D':
732 dumpAllRecords(dlDbHand, CSSM_TRUE, interact, dumpData);
733 if(!interact) {
734 /* we ignored errors.... */
735 if(!quiet) {
736 printf("...DB %s wiped clean\n", dbFileName);
737 }
738 }
739 break;
740 default:
741 usage(argv);
742 }
743 CSSM_DL_DbClose(dlDbHand);
744 done:
745 CSSM_ModuleDetach(dlDbHand.DLHandle);
746 return crtn;
747 }