security/nss/lib/softoken/legacydb/lginit.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * NSS utility functions
michael@0 3 *
michael@0 4 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 7
michael@0 8 #include "lowkeyi.h"
michael@0 9 #include "pcert.h"
michael@0 10 #include "keydbi.h"
michael@0 11 #include "lgdb.h"
michael@0 12 #include "secoid.h"
michael@0 13 #include "prenv.h"
michael@0 14 #include "softkver.h"
michael@0 15
michael@0 16 /* Library identity and versioning */
michael@0 17
michael@0 18 #if defined(DEBUG)
michael@0 19 #define _DEBUG_STRING " (debug)"
michael@0 20 #else
michael@0 21 #define _DEBUG_STRING ""
michael@0 22 #endif
michael@0 23
michael@0 24 /*
michael@0 25 * Version information for the 'ident' and 'what commands
michael@0 26 *
michael@0 27 * NOTE: the first component of the concatenated rcsid string
michael@0 28 * must not end in a '$' to prevent rcs keyword substitution.
michael@0 29 */
michael@0 30 const char __nss_dbm_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING
michael@0 31 " " __DATE__ " " __TIME__ " $";
michael@0 32 const char __nss_dbm_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING
michael@0 33 " " __DATE__ " " __TIME__;
michael@0 34
michael@0 35 typedef struct LGPrivateStr {
michael@0 36 NSSLOWCERTCertDBHandle *certDB;
michael@0 37 NSSLOWKEYDBHandle *keyDB;
michael@0 38 PRLock *dbLock;
michael@0 39 PLHashTable *hashTable;
michael@0 40 } LGPrivate;
michael@0 41
michael@0 42 static char *
michael@0 43 lg_certdb_name_cb(void *arg, int dbVersion)
michael@0 44 {
michael@0 45 const char *configdir = (const char *)arg;
michael@0 46 const char *dbver;
michael@0 47 char *smpname = NULL;
michael@0 48 char *dbname = NULL;
michael@0 49
michael@0 50 switch (dbVersion) {
michael@0 51 case 8:
michael@0 52 dbver = "8";
michael@0 53 break;
michael@0 54 case 7:
michael@0 55 dbver = "7";
michael@0 56 break;
michael@0 57 case 6:
michael@0 58 dbver = "6";
michael@0 59 break;
michael@0 60 case 5:
michael@0 61 dbver = "5";
michael@0 62 break;
michael@0 63 case 4:
michael@0 64 default:
michael@0 65 dbver = "";
michael@0 66 break;
michael@0 67 }
michael@0 68
michael@0 69 /* make sure we return something allocated with PORT_ so we have properly
michael@0 70 * matched frees at the end */
michael@0 71 smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
michael@0 72 if (smpname) {
michael@0 73 dbname = PORT_Strdup(smpname);
michael@0 74 PR_smprintf_free(smpname);
michael@0 75 }
michael@0 76 return dbname;
michael@0 77 }
michael@0 78
michael@0 79 static char *
michael@0 80 lg_keydb_name_cb(void *arg, int dbVersion)
michael@0 81 {
michael@0 82 const char *configdir = (const char *)arg;
michael@0 83 const char *dbver;
michael@0 84 char *smpname = NULL;
michael@0 85 char *dbname = NULL;
michael@0 86
michael@0 87 switch (dbVersion) {
michael@0 88 case 4:
michael@0 89 dbver = "4";
michael@0 90 break;
michael@0 91 case 3:
michael@0 92 dbver = "3";
michael@0 93 break;
michael@0 94 case 1:
michael@0 95 dbver = "1";
michael@0 96 break;
michael@0 97 case 2:
michael@0 98 default:
michael@0 99 dbver = "";
michael@0 100 break;
michael@0 101 }
michael@0 102
michael@0 103 smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver);
michael@0 104 if (smpname) {
michael@0 105 dbname = PORT_Strdup(smpname);
michael@0 106 PR_smprintf_free(smpname);
michael@0 107 }
michael@0 108 return dbname;
michael@0 109 }
michael@0 110
michael@0 111 const char *
michael@0 112 lg_EvaluateConfigDir(const char *configdir,char **appName)
michael@0 113 {
michael@0 114 if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
michael@0 115 char *cdir;
michael@0 116
michael@0 117 *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
michael@0 118 if (*appName == NULL) {
michael@0 119 return configdir;
michael@0 120 }
michael@0 121 cdir = *appName;
michael@0 122 while (*cdir && *cdir != ':') {
michael@0 123 cdir++;
michael@0 124 }
michael@0 125 if (*cdir == ':') {
michael@0 126 *cdir = 0;
michael@0 127 cdir++;
michael@0 128 }
michael@0 129 configdir = cdir;
michael@0 130 }
michael@0 131 return configdir;
michael@0 132 }
michael@0 133
michael@0 134 static int rdbmapflags(int flags);
michael@0 135 static rdbfunc lg_rdbfunc = NULL;
michael@0 136 static rdbstatusfunc lg_rdbstatusfunc = NULL;
michael@0 137
michael@0 138 /* NOTE: SHLIB_SUFFIX is defined on the command line */
michael@0 139 #define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX
michael@0 140
michael@0 141 DB * rdbopen(const char *appName, const char *prefix,
michael@0 142 const char *type, int flags, int *status)
michael@0 143 {
michael@0 144 PRLibrary *lib;
michael@0 145 DB *db;
michael@0 146 char *disableUnload = NULL;
michael@0 147
michael@0 148 if (lg_rdbfunc) {
michael@0 149 db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
michael@0 150 if (!db && status && lg_rdbstatusfunc) {
michael@0 151 *status = (*lg_rdbstatusfunc)();
michael@0 152 }
michael@0 153 return db;
michael@0 154 }
michael@0 155
michael@0 156 /*
michael@0 157 * try to open the library.
michael@0 158 */
michael@0 159 lib = PR_LoadLibrary(RDBLIB);
michael@0 160
michael@0 161 if (!lib) {
michael@0 162 return NULL;
michael@0 163 }
michael@0 164
michael@0 165 /* get the entry points */
michael@0 166 lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
michael@0 167 lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
michael@0 168 if (lg_rdbfunc) {
michael@0 169 db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
michael@0 170 if (!db && status && lg_rdbstatusfunc) {
michael@0 171 *status = (*lg_rdbstatusfunc)();
michael@0 172 }
michael@0 173 return db;
michael@0 174 }
michael@0 175
michael@0 176 /* couldn't find the entry point, unload the library and fail */
michael@0 177 disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
michael@0 178 if (!disableUnload) {
michael@0 179 PR_UnloadLibrary(lib);
michael@0 180 }
michael@0 181 return NULL;
michael@0 182 }
michael@0 183
michael@0 184 /*
michael@0 185 * the following data structures are from rdb.h.
michael@0 186 */
michael@0 187 struct RDBStr {
michael@0 188 DB db;
michael@0 189 int (*xactstart)(DB *db);
michael@0 190 int (*xactdone)(DB *db, PRBool abort);
michael@0 191 int version;
michael@0 192 int (*dbinitcomplete)(DB *db);
michael@0 193 };
michael@0 194
michael@0 195 #define DB_RDB ((DBTYPE) 0xff)
michael@0 196 #define RDB_RDONLY 1
michael@0 197 #define RDB_RDWR 2
michael@0 198 #define RDB_CREATE 4
michael@0 199
michael@0 200 static int
michael@0 201 rdbmapflags(int flags) {
michael@0 202 switch (flags) {
michael@0 203 case NO_RDONLY:
michael@0 204 return RDB_RDONLY;
michael@0 205 case NO_RDWR:
michael@0 206 return RDB_RDWR;
michael@0 207 case NO_CREATE:
michael@0 208 return RDB_CREATE;
michael@0 209 default:
michael@0 210 break;
michael@0 211 }
michael@0 212 return 0;
michael@0 213 }
michael@0 214
michael@0 215 PRBool
michael@0 216 db_IsRDB(DB *db)
michael@0 217 {
michael@0 218 return (PRBool) db->type == DB_RDB;
michael@0 219 }
michael@0 220
michael@0 221 int
michael@0 222 db_BeginTransaction(DB *db)
michael@0 223 {
michael@0 224 struct RDBStr *rdb = (struct RDBStr *)db;
michael@0 225 if (db->type != DB_RDB) {
michael@0 226 return 0;
michael@0 227 }
michael@0 228
michael@0 229 return rdb->xactstart(db);
michael@0 230 }
michael@0 231
michael@0 232 int
michael@0 233 db_FinishTransaction(DB *db, PRBool abort)
michael@0 234 {
michael@0 235 struct RDBStr *rdb = (struct RDBStr *)db;
michael@0 236 if (db->type != DB_RDB) {
michael@0 237 return 0;
michael@0 238 }
michael@0 239
michael@0 240 return rdb->xactdone(db, abort);
michael@0 241 }
michael@0 242
michael@0 243 static DB *
michael@0 244 lg_getRawDB(SDB *sdb)
michael@0 245 {
michael@0 246 NSSLOWCERTCertDBHandle *certDB;
michael@0 247 NSSLOWKEYDBHandle *keyDB;
michael@0 248
michael@0 249 certDB = lg_getCertDB(sdb);
michael@0 250 if (certDB) {
michael@0 251 return certDB->permCertDB;
michael@0 252 }
michael@0 253 keyDB = lg_getKeyDB(sdb);
michael@0 254 if (keyDB) {
michael@0 255 return keyDB->db;
michael@0 256 }
michael@0 257 return NULL;
michael@0 258 }
michael@0 259
michael@0 260 CK_RV
michael@0 261 lg_Begin(SDB *sdb)
michael@0 262 {
michael@0 263 DB *db = lg_getRawDB(sdb);
michael@0 264 int ret;
michael@0 265
michael@0 266 if (db == NULL) {
michael@0 267 return CKR_GENERAL_ERROR; /* shouldn't happen */
michael@0 268 }
michael@0 269 ret = db_BeginTransaction(db);
michael@0 270 if (ret != 0) {
michael@0 271 return CKR_GENERAL_ERROR; /* could happen */
michael@0 272 }
michael@0 273 return CKR_OK;
michael@0 274 }
michael@0 275
michael@0 276 CK_RV
michael@0 277 lg_Commit(SDB *sdb)
michael@0 278 {
michael@0 279 DB *db = lg_getRawDB(sdb);
michael@0 280 int ret;
michael@0 281
michael@0 282 if (db == NULL) {
michael@0 283 return CKR_GENERAL_ERROR; /* shouldn't happen */
michael@0 284 }
michael@0 285 ret = db_FinishTransaction(db, PR_FALSE);
michael@0 286 if (ret != 0) {
michael@0 287 return CKR_GENERAL_ERROR; /* could happen */
michael@0 288 }
michael@0 289 return CKR_OK;
michael@0 290 }
michael@0 291
michael@0 292 CK_RV
michael@0 293 lg_Abort(SDB *sdb)
michael@0 294 {
michael@0 295 DB *db = lg_getRawDB(sdb);
michael@0 296 int ret;
michael@0 297
michael@0 298 if (db == NULL) {
michael@0 299 return CKR_GENERAL_ERROR; /* shouldn't happen */
michael@0 300 }
michael@0 301 ret = db_FinishTransaction(db, PR_TRUE);
michael@0 302 if (ret != 0) {
michael@0 303 return CKR_GENERAL_ERROR; /* could happen */
michael@0 304 }
michael@0 305 return CKR_OK;
michael@0 306 }
michael@0 307
michael@0 308 int
michael@0 309 db_InitComplete(DB *db)
michael@0 310 {
michael@0 311 struct RDBStr *rdb = (struct RDBStr *)db;
michael@0 312 if (db->type != DB_RDB) {
michael@0 313 return 0;
michael@0 314 }
michael@0 315 /* we should have added a version number to the RDBS structure. Since we
michael@0 316 * didn't, we detect that we have and 'extended' structure if the rdbstatus
michael@0 317 * func exists */
michael@0 318 if (!lg_rdbstatusfunc) {
michael@0 319 return 0;
michael@0 320 }
michael@0 321
michael@0 322 return rdb->dbinitcomplete(db);
michael@0 323 }
michael@0 324
michael@0 325
michael@0 326
michael@0 327 SECStatus
michael@0 328 db_Copy(DB *dest,DB *src)
michael@0 329 {
michael@0 330 int ret;
michael@0 331 DBT key,data;
michael@0 332 ret = (*src->seq)(src, &key, &data, R_FIRST);
michael@0 333 if (ret) {
michael@0 334 return SECSuccess;
michael@0 335 }
michael@0 336
michael@0 337 do {
michael@0 338 (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
michael@0 339 } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
michael@0 340 (void)(*dest->sync)(dest,0);
michael@0 341
michael@0 342 return SECSuccess;
michael@0 343 }
michael@0 344
michael@0 345
michael@0 346 static CK_RV
michael@0 347 lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
michael@0 348 NSSLOWCERTCertDBHandle **certdbPtr)
michael@0 349 {
michael@0 350 NSSLOWCERTCertDBHandle *certdb = NULL;
michael@0 351 CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED;
michael@0 352 SECStatus rv;
michael@0 353 char * name = NULL;
michael@0 354 char * appName = NULL;
michael@0 355
michael@0 356 if (prefix == NULL) {
michael@0 357 prefix = "";
michael@0 358 }
michael@0 359
michael@0 360 configdir = lg_EvaluateConfigDir(configdir, &appName);
michael@0 361
michael@0 362 name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
michael@0 363 if (name == NULL) goto loser;
michael@0 364
michael@0 365 certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
michael@0 366 if (certdb == NULL)
michael@0 367 goto loser;
michael@0 368
michael@0 369 certdb->ref = 1;
michael@0 370 /* fix when we get the DB in */
michael@0 371 rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
michael@0 372 lg_certdb_name_cb, (void *)name, PR_FALSE);
michael@0 373 if (rv == SECSuccess) {
michael@0 374 crv = CKR_OK;
michael@0 375 *certdbPtr = certdb;
michael@0 376 certdb = NULL;
michael@0 377 }
michael@0 378 loser:
michael@0 379 if (certdb) PR_Free(certdb);
michael@0 380 if (name) PR_smprintf_free(name);
michael@0 381 if (appName) PORT_Free(appName);
michael@0 382 return crv;
michael@0 383 }
michael@0 384
michael@0 385 static CK_RV
michael@0 386 lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
michael@0 387 NSSLOWKEYDBHandle **keydbPtr)
michael@0 388 {
michael@0 389 NSSLOWKEYDBHandle *keydb;
michael@0 390 char * name = NULL;
michael@0 391 char * appName = NULL;
michael@0 392
michael@0 393 if (prefix == NULL) {
michael@0 394 prefix = "";
michael@0 395 }
michael@0 396 configdir = lg_EvaluateConfigDir(configdir, &appName);
michael@0 397
michael@0 398 name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
michael@0 399 if (name == NULL)
michael@0 400 return CKR_HOST_MEMORY;
michael@0 401 keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix,
michael@0 402 lg_keydb_name_cb, (void *)name);
michael@0 403 PR_smprintf_free(name);
michael@0 404 if (appName) PORT_Free(appName);
michael@0 405 if (keydb == NULL)
michael@0 406 return CKR_NETSCAPE_KEYDB_FAILED;
michael@0 407 *keydbPtr = keydb;
michael@0 408
michael@0 409 return CKR_OK;
michael@0 410 }
michael@0 411
michael@0 412 /*
michael@0 413 * Accessors for the private parts of the sdb structure.
michael@0 414 */
michael@0 415 void
michael@0 416 lg_DBLock(SDB *sdb)
michael@0 417 {
michael@0 418 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 419 SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock));
michael@0 420 }
michael@0 421
michael@0 422 void
michael@0 423 lg_DBUnlock(SDB *sdb)
michael@0 424 {
michael@0 425 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 426 SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock));
michael@0 427 }
michael@0 428
michael@0 429 PLHashTable *
michael@0 430 lg_GetHashTable(SDB *sdb)
michael@0 431 {
michael@0 432 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 433 return lgdb_p->hashTable;
michael@0 434 }
michael@0 435
michael@0 436 NSSLOWCERTCertDBHandle *
michael@0 437 lg_getCertDB(SDB *sdb)
michael@0 438 {
michael@0 439 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 440
michael@0 441 return lgdb_p->certDB;
michael@0 442 }
michael@0 443
michael@0 444 NSSLOWKEYDBHandle *
michael@0 445 lg_getKeyDB(SDB *sdb)
michael@0 446 {
michael@0 447 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 448
michael@0 449 return lgdb_p->keyDB;
michael@0 450 }
michael@0 451
michael@0 452 PRBool lg_parentForkedAfterC_Initialize;
michael@0 453
michael@0 454 void lg_SetForkState(PRBool forked)
michael@0 455 {
michael@0 456 lg_parentForkedAfterC_Initialize = forked;
michael@0 457 }
michael@0 458
michael@0 459 CK_RV
michael@0 460 lg_Close(SDB *sdb)
michael@0 461 {
michael@0 462 LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
michael@0 463 lg_ClearTokenKeyHashTable(sdb);
michael@0 464 if (lgdb_p) {
michael@0 465 if (lgdb_p->certDB) {
michael@0 466 nsslowcert_ClosePermCertDB(lgdb_p->certDB);
michael@0 467 } else if (lgdb_p->keyDB) {
michael@0 468 nsslowkey_CloseKeyDB(lgdb_p->keyDB);
michael@0 469 }
michael@0 470 if (lgdb_p->dbLock) {
michael@0 471 SKIP_AFTER_FORK(PR_DestroyLock(lgdb_p->dbLock));
michael@0 472 }
michael@0 473 if (lgdb_p->hashTable) {
michael@0 474 PL_HashTableDestroy(lgdb_p->hashTable);
michael@0 475 }
michael@0 476 PORT_Free(lgdb_p);
michael@0 477 }
michael@0 478 PORT_Free(sdb);
michael@0 479 return CKR_OK;
michael@0 480 }
michael@0 481
michael@0 482 static PLHashNumber
michael@0 483 lg_HashNumber(const void *key)
michael@0 484 {
michael@0 485 return (PLHashNumber) key;
michael@0 486 }
michael@0 487
michael@0 488 PRIntn
michael@0 489 lg_CompareValues(const void *v1, const void *v2)
michael@0 490 {
michael@0 491 PLHashNumber value1 = (PLHashNumber) v1;
michael@0 492 PLHashNumber value2 = (PLHashNumber) v2;
michael@0 493 return (value1 == value2);
michael@0 494 }
michael@0 495
michael@0 496 /*
michael@0 497 * helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle
michael@0 498 * with and sdb structure.
michael@0 499 */
michael@0 500 CK_RV
michael@0 501 lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr,
michael@0 502 NSSLOWKEYDBHandle *keydbPtr)
michael@0 503 {
michael@0 504 SDB *sdb = NULL;
michael@0 505 LGPrivate *lgdb_p = NULL;
michael@0 506 CK_RV error = CKR_HOST_MEMORY;
michael@0 507
michael@0 508 *pSdb = NULL;
michael@0 509 sdb = (SDB *) PORT_Alloc(sizeof(SDB));
michael@0 510 if (sdb == NULL) {
michael@0 511 goto loser;
michael@0 512 }
michael@0 513 lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate));
michael@0 514 if (lgdb_p == NULL) {
michael@0 515 goto loser;
michael@0 516 }
michael@0 517 /* invariant fields */
michael@0 518 lgdb_p->certDB = certdbPtr;
michael@0 519 lgdb_p->keyDB = keydbPtr;
michael@0 520 lgdb_p->dbLock = PR_NewLock();
michael@0 521 if (lgdb_p->dbLock == NULL) {
michael@0 522 goto loser;
michael@0 523 }
michael@0 524 lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, lg_CompareValues,
michael@0 525 SECITEM_HashCompare, NULL, 0);
michael@0 526 if (lgdb_p->hashTable == NULL) {
michael@0 527 goto loser;
michael@0 528 }
michael@0 529
michael@0 530 sdb->private = lgdb_p;
michael@0 531 sdb->version = 0;
michael@0 532 /*sdb->sdb_type = SDB_LEGACY; */
michael@0 533 sdb->sdb_flags = flags;
michael@0 534 sdb->app_private = NULL;
michael@0 535 sdb->sdb_FindObjectsInit = lg_FindObjectsInit;
michael@0 536 sdb->sdb_FindObjects = lg_FindObjects;
michael@0 537 sdb->sdb_FindObjectsFinal = lg_FindObjectsFinal;
michael@0 538 sdb->sdb_GetAttributeValue = lg_GetAttributeValue;
michael@0 539 sdb->sdb_SetAttributeValue = lg_SetAttributeValue;
michael@0 540 sdb->sdb_CreateObject = lg_CreateObject;
michael@0 541 sdb->sdb_DestroyObject = lg_DestroyObject;
michael@0 542 sdb->sdb_GetMetaData = lg_GetMetaData;
michael@0 543 sdb->sdb_PutMetaData = lg_PutMetaData;
michael@0 544 sdb->sdb_Begin = lg_Begin;
michael@0 545 sdb->sdb_Commit = lg_Commit;
michael@0 546 sdb->sdb_Abort = lg_Abort;
michael@0 547 sdb->sdb_Reset = lg_Reset;
michael@0 548 sdb->sdb_Close = lg_Close;
michael@0 549 sdb->sdb_SetForkState = lg_SetForkState;
michael@0 550
michael@0 551 *pSdb = sdb;
michael@0 552 return CKR_OK;
michael@0 553
michael@0 554 loser:
michael@0 555 if (sdb) {
michael@0 556 PORT_Free(sdb);
michael@0 557 }
michael@0 558 if (lgdb_p) {
michael@0 559 if (lgdb_p->dbLock) {
michael@0 560 PR_DestroyLock(lgdb_p->dbLock);
michael@0 561 }
michael@0 562 if (lgdb_p->hashTable) {
michael@0 563 PL_HashTableDestroy(lgdb_p->hashTable);
michael@0 564 }
michael@0 565 PORT_Free(lgdb_p);
michael@0 566 }
michael@0 567 return error;
michael@0 568
michael@0 569 }
michael@0 570
michael@0 571 /*
michael@0 572 * OK there are now lots of options here, lets go through them all:
michael@0 573 *
michael@0 574 * configdir - base directory where all the cert, key, and module datbases live.
michael@0 575 * certPrefix - prefix added to the beginning of the cert database example: "
michael@0 576 * "https-server1-"
michael@0 577 * keyPrefix - prefix added to the beginning of the key database example: "
michael@0 578 * "https-server1-"
michael@0 579 * secmodName - name of the security module database (usually "secmod.db").
michael@0 580 * readOnly - Boolean: true if the databases are to be openned read only.
michael@0 581 * nocertdb - Don't open the cert DB and key DB's, just initialize the
michael@0 582 * Volatile certdb.
michael@0 583 * nomoddb - Don't open the security module DB, just initialize the
michael@0 584 * PKCS #11 module.
michael@0 585 * forceOpen - Continue to force initializations even if the databases cannot
michael@0 586 * be opened.
michael@0 587 */
michael@0 588 CK_RV
michael@0 589 legacy_Open(const char *configdir, const char *certPrefix,
michael@0 590 const char *keyPrefix, int certVersion, int keyVersion,
michael@0 591 int flags, SDB **certDB, SDB **keyDB)
michael@0 592 {
michael@0 593 CK_RV crv = CKR_OK;
michael@0 594 SECStatus rv;
michael@0 595 PRBool readOnly = (flags == SDB_RDONLY)? PR_TRUE: PR_FALSE;
michael@0 596 volatile char c; /* force a reference that won't get optimized away */
michael@0 597
michael@0 598 c = __nss_dbm_rcsid[0] + __nss_dbm_sccsid[0];
michael@0 599
michael@0 600 rv = SECOID_Init();
michael@0 601 if (SECSuccess != rv) {
michael@0 602 return CKR_DEVICE_ERROR;
michael@0 603 }
michael@0 604 nsslowcert_InitLocks();
michael@0 605
michael@0 606 if (keyDB) *keyDB = NULL;
michael@0 607 if (certDB) *certDB = NULL;
michael@0 608
michael@0 609 if (certDB) {
michael@0 610 NSSLOWCERTCertDBHandle *certdbPtr;
michael@0 611
michael@0 612 crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr);
michael@0 613 if (crv != CKR_OK) {
michael@0 614 goto loser;
michael@0 615 }
michael@0 616 crv = lg_init(certDB, flags, certdbPtr, NULL);
michael@0 617 if (crv != CKR_OK) {
michael@0 618 nsslowcert_ClosePermCertDB(certdbPtr);
michael@0 619 goto loser;
michael@0 620 }
michael@0 621 }
michael@0 622 if (keyDB) {
michael@0 623 NSSLOWKEYDBHandle *keydbPtr;
michael@0 624
michael@0 625 crv = lg_OpenKeyDB(configdir, keyPrefix, readOnly, &keydbPtr);
michael@0 626 if (crv != CKR_OK) {
michael@0 627 goto loser;
michael@0 628 }
michael@0 629 crv = lg_init(keyDB, flags, NULL, keydbPtr);
michael@0 630 if (crv != CKR_OK) {
michael@0 631 nsslowkey_CloseKeyDB(keydbPtr);
michael@0 632 goto loser;
michael@0 633 }
michael@0 634 if (certDB && *certDB) {
michael@0 635 LGPrivate *lgdb_p = (LGPrivate *)(*certDB)->private;
michael@0 636 lgdb_p->keyDB = keydbPtr;
michael@0 637 }
michael@0 638 }
michael@0 639
michael@0 640 loser:
michael@0 641 if (crv != CKR_OK) {
michael@0 642 if (keyDB && *keyDB) {
michael@0 643 lg_Close(*keyDB);
michael@0 644 *keyDB = NULL;
michael@0 645 }
michael@0 646 if (certDB && *certDB) {
michael@0 647 lg_Close(*certDB);
michael@0 648 *certDB = NULL;
michael@0 649 }
michael@0 650 }
michael@0 651 return crv;
michael@0 652 }
michael@0 653
michael@0 654 CK_RV
michael@0 655 legacy_Shutdown(PRBool forked)
michael@0 656 {
michael@0 657 lg_SetForkState(forked);
michael@0 658 nsslowcert_DestroyFreeLists();
michael@0 659 nsslowcert_DestroyGlobalLocks();
michael@0 660 SECOID_Shutdown();
michael@0 661 lg_SetForkState(PR_FALSE);
michael@0 662 return CKR_OK;
michael@0 663 }
michael@0 664

mercurial