1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/softoken/legacydb/lginit.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,664 @@ 1.4 +/* 1.5 + * NSS utility functions 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "lowkeyi.h" 1.12 +#include "pcert.h" 1.13 +#include "keydbi.h" 1.14 +#include "lgdb.h" 1.15 +#include "secoid.h" 1.16 +#include "prenv.h" 1.17 +#include "softkver.h" 1.18 + 1.19 +/* Library identity and versioning */ 1.20 + 1.21 +#if defined(DEBUG) 1.22 +#define _DEBUG_STRING " (debug)" 1.23 +#else 1.24 +#define _DEBUG_STRING "" 1.25 +#endif 1.26 + 1.27 +/* 1.28 + * Version information for the 'ident' and 'what commands 1.29 + * 1.30 + * NOTE: the first component of the concatenated rcsid string 1.31 + * must not end in a '$' to prevent rcs keyword substitution. 1.32 + */ 1.33 +const char __nss_dbm_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING 1.34 + " " __DATE__ " " __TIME__ " $"; 1.35 +const char __nss_dbm_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING 1.36 + " " __DATE__ " " __TIME__; 1.37 + 1.38 +typedef struct LGPrivateStr { 1.39 + NSSLOWCERTCertDBHandle *certDB; 1.40 + NSSLOWKEYDBHandle *keyDB; 1.41 + PRLock *dbLock; 1.42 + PLHashTable *hashTable; 1.43 +} LGPrivate; 1.44 + 1.45 +static char * 1.46 +lg_certdb_name_cb(void *arg, int dbVersion) 1.47 +{ 1.48 + const char *configdir = (const char *)arg; 1.49 + const char *dbver; 1.50 + char *smpname = NULL; 1.51 + char *dbname = NULL; 1.52 + 1.53 + switch (dbVersion) { 1.54 + case 8: 1.55 + dbver = "8"; 1.56 + break; 1.57 + case 7: 1.58 + dbver = "7"; 1.59 + break; 1.60 + case 6: 1.61 + dbver = "6"; 1.62 + break; 1.63 + case 5: 1.64 + dbver = "5"; 1.65 + break; 1.66 + case 4: 1.67 + default: 1.68 + dbver = ""; 1.69 + break; 1.70 + } 1.71 + 1.72 + /* make sure we return something allocated with PORT_ so we have properly 1.73 + * matched frees at the end */ 1.74 + smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver); 1.75 + if (smpname) { 1.76 + dbname = PORT_Strdup(smpname); 1.77 + PR_smprintf_free(smpname); 1.78 + } 1.79 + return dbname; 1.80 +} 1.81 + 1.82 +static char * 1.83 +lg_keydb_name_cb(void *arg, int dbVersion) 1.84 +{ 1.85 + const char *configdir = (const char *)arg; 1.86 + const char *dbver; 1.87 + char *smpname = NULL; 1.88 + char *dbname = NULL; 1.89 + 1.90 + switch (dbVersion) { 1.91 + case 4: 1.92 + dbver = "4"; 1.93 + break; 1.94 + case 3: 1.95 + dbver = "3"; 1.96 + break; 1.97 + case 1: 1.98 + dbver = "1"; 1.99 + break; 1.100 + case 2: 1.101 + default: 1.102 + dbver = ""; 1.103 + break; 1.104 + } 1.105 + 1.106 + smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver); 1.107 + if (smpname) { 1.108 + dbname = PORT_Strdup(smpname); 1.109 + PR_smprintf_free(smpname); 1.110 + } 1.111 + return dbname; 1.112 +} 1.113 + 1.114 +const char * 1.115 +lg_EvaluateConfigDir(const char *configdir,char **appName) 1.116 +{ 1.117 + if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) { 1.118 + char *cdir; 1.119 + 1.120 + *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1); 1.121 + if (*appName == NULL) { 1.122 + return configdir; 1.123 + } 1.124 + cdir = *appName; 1.125 + while (*cdir && *cdir != ':') { 1.126 + cdir++; 1.127 + } 1.128 + if (*cdir == ':') { 1.129 + *cdir = 0; 1.130 + cdir++; 1.131 + } 1.132 + configdir = cdir; 1.133 + } 1.134 + return configdir; 1.135 +} 1.136 + 1.137 +static int rdbmapflags(int flags); 1.138 +static rdbfunc lg_rdbfunc = NULL; 1.139 +static rdbstatusfunc lg_rdbstatusfunc = NULL; 1.140 + 1.141 +/* NOTE: SHLIB_SUFFIX is defined on the command line */ 1.142 +#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX 1.143 + 1.144 +DB * rdbopen(const char *appName, const char *prefix, 1.145 + const char *type, int flags, int *status) 1.146 +{ 1.147 + PRLibrary *lib; 1.148 + DB *db; 1.149 + char *disableUnload = NULL; 1.150 + 1.151 + if (lg_rdbfunc) { 1.152 + db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags)); 1.153 + if (!db && status && lg_rdbstatusfunc) { 1.154 + *status = (*lg_rdbstatusfunc)(); 1.155 + } 1.156 + return db; 1.157 + } 1.158 + 1.159 + /* 1.160 + * try to open the library. 1.161 + */ 1.162 + lib = PR_LoadLibrary(RDBLIB); 1.163 + 1.164 + if (!lib) { 1.165 + return NULL; 1.166 + } 1.167 + 1.168 + /* get the entry points */ 1.169 + lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus"); 1.170 + lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen"); 1.171 + if (lg_rdbfunc) { 1.172 + db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags)); 1.173 + if (!db && status && lg_rdbstatusfunc) { 1.174 + *status = (*lg_rdbstatusfunc)(); 1.175 + } 1.176 + return db; 1.177 + } 1.178 + 1.179 + /* couldn't find the entry point, unload the library and fail */ 1.180 + disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); 1.181 + if (!disableUnload) { 1.182 + PR_UnloadLibrary(lib); 1.183 + } 1.184 + return NULL; 1.185 +} 1.186 + 1.187 +/* 1.188 + * the following data structures are from rdb.h. 1.189 + */ 1.190 +struct RDBStr { 1.191 + DB db; 1.192 + int (*xactstart)(DB *db); 1.193 + int (*xactdone)(DB *db, PRBool abort); 1.194 + int version; 1.195 + int (*dbinitcomplete)(DB *db); 1.196 +}; 1.197 + 1.198 +#define DB_RDB ((DBTYPE) 0xff) 1.199 +#define RDB_RDONLY 1 1.200 +#define RDB_RDWR 2 1.201 +#define RDB_CREATE 4 1.202 + 1.203 +static int 1.204 +rdbmapflags(int flags) { 1.205 + switch (flags) { 1.206 + case NO_RDONLY: 1.207 + return RDB_RDONLY; 1.208 + case NO_RDWR: 1.209 + return RDB_RDWR; 1.210 + case NO_CREATE: 1.211 + return RDB_CREATE; 1.212 + default: 1.213 + break; 1.214 + } 1.215 + return 0; 1.216 +} 1.217 + 1.218 +PRBool 1.219 +db_IsRDB(DB *db) 1.220 +{ 1.221 + return (PRBool) db->type == DB_RDB; 1.222 +} 1.223 + 1.224 +int 1.225 +db_BeginTransaction(DB *db) 1.226 +{ 1.227 + struct RDBStr *rdb = (struct RDBStr *)db; 1.228 + if (db->type != DB_RDB) { 1.229 + return 0; 1.230 + } 1.231 + 1.232 + return rdb->xactstart(db); 1.233 +} 1.234 + 1.235 +int 1.236 +db_FinishTransaction(DB *db, PRBool abort) 1.237 +{ 1.238 + struct RDBStr *rdb = (struct RDBStr *)db; 1.239 + if (db->type != DB_RDB) { 1.240 + return 0; 1.241 + } 1.242 + 1.243 + return rdb->xactdone(db, abort); 1.244 +} 1.245 + 1.246 +static DB * 1.247 +lg_getRawDB(SDB *sdb) 1.248 +{ 1.249 + NSSLOWCERTCertDBHandle *certDB; 1.250 + NSSLOWKEYDBHandle *keyDB; 1.251 + 1.252 + certDB = lg_getCertDB(sdb); 1.253 + if (certDB) { 1.254 + return certDB->permCertDB; 1.255 + } 1.256 + keyDB = lg_getKeyDB(sdb); 1.257 + if (keyDB) { 1.258 + return keyDB->db; 1.259 + } 1.260 + return NULL; 1.261 +} 1.262 + 1.263 +CK_RV 1.264 +lg_Begin(SDB *sdb) 1.265 +{ 1.266 + DB *db = lg_getRawDB(sdb); 1.267 + int ret; 1.268 + 1.269 + if (db == NULL) { 1.270 + return CKR_GENERAL_ERROR; /* shouldn't happen */ 1.271 + } 1.272 + ret = db_BeginTransaction(db); 1.273 + if (ret != 0) { 1.274 + return CKR_GENERAL_ERROR; /* could happen */ 1.275 + } 1.276 + return CKR_OK; 1.277 +} 1.278 + 1.279 +CK_RV 1.280 +lg_Commit(SDB *sdb) 1.281 +{ 1.282 + DB *db = lg_getRawDB(sdb); 1.283 + int ret; 1.284 + 1.285 + if (db == NULL) { 1.286 + return CKR_GENERAL_ERROR; /* shouldn't happen */ 1.287 + } 1.288 + ret = db_FinishTransaction(db, PR_FALSE); 1.289 + if (ret != 0) { 1.290 + return CKR_GENERAL_ERROR; /* could happen */ 1.291 + } 1.292 + return CKR_OK; 1.293 +} 1.294 + 1.295 +CK_RV 1.296 +lg_Abort(SDB *sdb) 1.297 +{ 1.298 + DB *db = lg_getRawDB(sdb); 1.299 + int ret; 1.300 + 1.301 + if (db == NULL) { 1.302 + return CKR_GENERAL_ERROR; /* shouldn't happen */ 1.303 + } 1.304 + ret = db_FinishTransaction(db, PR_TRUE); 1.305 + if (ret != 0) { 1.306 + return CKR_GENERAL_ERROR; /* could happen */ 1.307 + } 1.308 + return CKR_OK; 1.309 +} 1.310 + 1.311 +int 1.312 +db_InitComplete(DB *db) 1.313 +{ 1.314 + struct RDBStr *rdb = (struct RDBStr *)db; 1.315 + if (db->type != DB_RDB) { 1.316 + return 0; 1.317 + } 1.318 + /* we should have added a version number to the RDBS structure. Since we 1.319 + * didn't, we detect that we have and 'extended' structure if the rdbstatus 1.320 + * func exists */ 1.321 + if (!lg_rdbstatusfunc) { 1.322 + return 0; 1.323 + } 1.324 + 1.325 + return rdb->dbinitcomplete(db); 1.326 +} 1.327 + 1.328 + 1.329 + 1.330 +SECStatus 1.331 +db_Copy(DB *dest,DB *src) 1.332 +{ 1.333 + int ret; 1.334 + DBT key,data; 1.335 + ret = (*src->seq)(src, &key, &data, R_FIRST); 1.336 + if (ret) { 1.337 + return SECSuccess; 1.338 + } 1.339 + 1.340 + do { 1.341 + (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE); 1.342 + } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0); 1.343 + (void)(*dest->sync)(dest,0); 1.344 + 1.345 + return SECSuccess; 1.346 +} 1.347 + 1.348 + 1.349 +static CK_RV 1.350 +lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly, 1.351 + NSSLOWCERTCertDBHandle **certdbPtr) 1.352 +{ 1.353 + NSSLOWCERTCertDBHandle *certdb = NULL; 1.354 + CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED; 1.355 + SECStatus rv; 1.356 + char * name = NULL; 1.357 + char * appName = NULL; 1.358 + 1.359 + if (prefix == NULL) { 1.360 + prefix = ""; 1.361 + } 1.362 + 1.363 + configdir = lg_EvaluateConfigDir(configdir, &appName); 1.364 + 1.365 + name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix); 1.366 + if (name == NULL) goto loser; 1.367 + 1.368 + certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle)); 1.369 + if (certdb == NULL) 1.370 + goto loser; 1.371 + 1.372 + certdb->ref = 1; 1.373 +/* fix when we get the DB in */ 1.374 + rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix, 1.375 + lg_certdb_name_cb, (void *)name, PR_FALSE); 1.376 + if (rv == SECSuccess) { 1.377 + crv = CKR_OK; 1.378 + *certdbPtr = certdb; 1.379 + certdb = NULL; 1.380 + } 1.381 +loser: 1.382 + if (certdb) PR_Free(certdb); 1.383 + if (name) PR_smprintf_free(name); 1.384 + if (appName) PORT_Free(appName); 1.385 + return crv; 1.386 +} 1.387 + 1.388 +static CK_RV 1.389 +lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly, 1.390 + NSSLOWKEYDBHandle **keydbPtr) 1.391 +{ 1.392 + NSSLOWKEYDBHandle *keydb; 1.393 + char * name = NULL; 1.394 + char * appName = NULL; 1.395 + 1.396 + if (prefix == NULL) { 1.397 + prefix = ""; 1.398 + } 1.399 + configdir = lg_EvaluateConfigDir(configdir, &appName); 1.400 + 1.401 + name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix); 1.402 + if (name == NULL) 1.403 + return CKR_HOST_MEMORY; 1.404 + keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix, 1.405 + lg_keydb_name_cb, (void *)name); 1.406 + PR_smprintf_free(name); 1.407 + if (appName) PORT_Free(appName); 1.408 + if (keydb == NULL) 1.409 + return CKR_NETSCAPE_KEYDB_FAILED; 1.410 + *keydbPtr = keydb; 1.411 + 1.412 + return CKR_OK; 1.413 +} 1.414 + 1.415 +/* 1.416 + * Accessors for the private parts of the sdb structure. 1.417 + */ 1.418 +void 1.419 +lg_DBLock(SDB *sdb) 1.420 +{ 1.421 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.422 + SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock)); 1.423 +} 1.424 + 1.425 +void 1.426 +lg_DBUnlock(SDB *sdb) 1.427 +{ 1.428 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.429 + SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock)); 1.430 +} 1.431 + 1.432 +PLHashTable * 1.433 +lg_GetHashTable(SDB *sdb) 1.434 +{ 1.435 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.436 + return lgdb_p->hashTable; 1.437 +} 1.438 + 1.439 +NSSLOWCERTCertDBHandle * 1.440 +lg_getCertDB(SDB *sdb) 1.441 +{ 1.442 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.443 + 1.444 + return lgdb_p->certDB; 1.445 +} 1.446 + 1.447 +NSSLOWKEYDBHandle * 1.448 +lg_getKeyDB(SDB *sdb) 1.449 +{ 1.450 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.451 + 1.452 + return lgdb_p->keyDB; 1.453 +} 1.454 + 1.455 +PRBool lg_parentForkedAfterC_Initialize; 1.456 + 1.457 +void lg_SetForkState(PRBool forked) 1.458 +{ 1.459 + lg_parentForkedAfterC_Initialize = forked; 1.460 +} 1.461 + 1.462 +CK_RV 1.463 +lg_Close(SDB *sdb) 1.464 +{ 1.465 + LGPrivate *lgdb_p = (LGPrivate *)sdb->private; 1.466 + lg_ClearTokenKeyHashTable(sdb); 1.467 + if (lgdb_p) { 1.468 + if (lgdb_p->certDB) { 1.469 + nsslowcert_ClosePermCertDB(lgdb_p->certDB); 1.470 + } else if (lgdb_p->keyDB) { 1.471 + nsslowkey_CloseKeyDB(lgdb_p->keyDB); 1.472 + } 1.473 + if (lgdb_p->dbLock) { 1.474 + SKIP_AFTER_FORK(PR_DestroyLock(lgdb_p->dbLock)); 1.475 + } 1.476 + if (lgdb_p->hashTable) { 1.477 + PL_HashTableDestroy(lgdb_p->hashTable); 1.478 + } 1.479 + PORT_Free(lgdb_p); 1.480 + } 1.481 + PORT_Free(sdb); 1.482 + return CKR_OK; 1.483 +} 1.484 + 1.485 +static PLHashNumber 1.486 +lg_HashNumber(const void *key) 1.487 +{ 1.488 + return (PLHashNumber) key; 1.489 +} 1.490 + 1.491 +PRIntn 1.492 +lg_CompareValues(const void *v1, const void *v2) 1.493 +{ 1.494 + PLHashNumber value1 = (PLHashNumber) v1; 1.495 + PLHashNumber value2 = (PLHashNumber) v2; 1.496 + return (value1 == value2); 1.497 +} 1.498 + 1.499 +/* 1.500 + * helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle 1.501 + * with and sdb structure. 1.502 + */ 1.503 +CK_RV 1.504 +lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr, 1.505 + NSSLOWKEYDBHandle *keydbPtr) 1.506 +{ 1.507 + SDB *sdb = NULL; 1.508 + LGPrivate *lgdb_p = NULL; 1.509 + CK_RV error = CKR_HOST_MEMORY; 1.510 + 1.511 + *pSdb = NULL; 1.512 + sdb = (SDB *) PORT_Alloc(sizeof(SDB)); 1.513 + if (sdb == NULL) { 1.514 + goto loser; 1.515 + } 1.516 + lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate)); 1.517 + if (lgdb_p == NULL) { 1.518 + goto loser; 1.519 + } 1.520 + /* invariant fields */ 1.521 + lgdb_p->certDB = certdbPtr; 1.522 + lgdb_p->keyDB = keydbPtr; 1.523 + lgdb_p->dbLock = PR_NewLock(); 1.524 + if (lgdb_p->dbLock == NULL) { 1.525 + goto loser; 1.526 + } 1.527 + lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, lg_CompareValues, 1.528 + SECITEM_HashCompare, NULL, 0); 1.529 + if (lgdb_p->hashTable == NULL) { 1.530 + goto loser; 1.531 + } 1.532 + 1.533 + sdb->private = lgdb_p; 1.534 + sdb->version = 0; 1.535 + /*sdb->sdb_type = SDB_LEGACY; */ 1.536 + sdb->sdb_flags = flags; 1.537 + sdb->app_private = NULL; 1.538 + sdb->sdb_FindObjectsInit = lg_FindObjectsInit; 1.539 + sdb->sdb_FindObjects = lg_FindObjects; 1.540 + sdb->sdb_FindObjectsFinal = lg_FindObjectsFinal; 1.541 + sdb->sdb_GetAttributeValue = lg_GetAttributeValue; 1.542 + sdb->sdb_SetAttributeValue = lg_SetAttributeValue; 1.543 + sdb->sdb_CreateObject = lg_CreateObject; 1.544 + sdb->sdb_DestroyObject = lg_DestroyObject; 1.545 + sdb->sdb_GetMetaData = lg_GetMetaData; 1.546 + sdb->sdb_PutMetaData = lg_PutMetaData; 1.547 + sdb->sdb_Begin = lg_Begin; 1.548 + sdb->sdb_Commit = lg_Commit; 1.549 + sdb->sdb_Abort = lg_Abort; 1.550 + sdb->sdb_Reset = lg_Reset; 1.551 + sdb->sdb_Close = lg_Close; 1.552 + sdb->sdb_SetForkState = lg_SetForkState; 1.553 + 1.554 + *pSdb = sdb; 1.555 + return CKR_OK; 1.556 + 1.557 +loser: 1.558 + if (sdb) { 1.559 + PORT_Free(sdb); 1.560 + } 1.561 + if (lgdb_p) { 1.562 + if (lgdb_p->dbLock) { 1.563 + PR_DestroyLock(lgdb_p->dbLock); 1.564 + } 1.565 + if (lgdb_p->hashTable) { 1.566 + PL_HashTableDestroy(lgdb_p->hashTable); 1.567 + } 1.568 + PORT_Free(lgdb_p); 1.569 + } 1.570 + return error; 1.571 + 1.572 +} 1.573 + 1.574 +/* 1.575 + * OK there are now lots of options here, lets go through them all: 1.576 + * 1.577 + * configdir - base directory where all the cert, key, and module datbases live. 1.578 + * certPrefix - prefix added to the beginning of the cert database example: " 1.579 + * "https-server1-" 1.580 + * keyPrefix - prefix added to the beginning of the key database example: " 1.581 + * "https-server1-" 1.582 + * secmodName - name of the security module database (usually "secmod.db"). 1.583 + * readOnly - Boolean: true if the databases are to be openned read only. 1.584 + * nocertdb - Don't open the cert DB and key DB's, just initialize the 1.585 + * Volatile certdb. 1.586 + * nomoddb - Don't open the security module DB, just initialize the 1.587 + * PKCS #11 module. 1.588 + * forceOpen - Continue to force initializations even if the databases cannot 1.589 + * be opened. 1.590 + */ 1.591 +CK_RV 1.592 +legacy_Open(const char *configdir, const char *certPrefix, 1.593 + const char *keyPrefix, int certVersion, int keyVersion, 1.594 + int flags, SDB **certDB, SDB **keyDB) 1.595 +{ 1.596 + CK_RV crv = CKR_OK; 1.597 + SECStatus rv; 1.598 + PRBool readOnly = (flags == SDB_RDONLY)? PR_TRUE: PR_FALSE; 1.599 + volatile char c; /* force a reference that won't get optimized away */ 1.600 + 1.601 + c = __nss_dbm_rcsid[0] + __nss_dbm_sccsid[0]; 1.602 + 1.603 + rv = SECOID_Init(); 1.604 + if (SECSuccess != rv) { 1.605 + return CKR_DEVICE_ERROR; 1.606 + } 1.607 + nsslowcert_InitLocks(); 1.608 + 1.609 + if (keyDB) *keyDB = NULL; 1.610 + if (certDB) *certDB = NULL; 1.611 + 1.612 + if (certDB) { 1.613 + NSSLOWCERTCertDBHandle *certdbPtr; 1.614 + 1.615 + crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr); 1.616 + if (crv != CKR_OK) { 1.617 + goto loser; 1.618 + } 1.619 + crv = lg_init(certDB, flags, certdbPtr, NULL); 1.620 + if (crv != CKR_OK) { 1.621 + nsslowcert_ClosePermCertDB(certdbPtr); 1.622 + goto loser; 1.623 + } 1.624 + } 1.625 + if (keyDB) { 1.626 + NSSLOWKEYDBHandle *keydbPtr; 1.627 + 1.628 + crv = lg_OpenKeyDB(configdir, keyPrefix, readOnly, &keydbPtr); 1.629 + if (crv != CKR_OK) { 1.630 + goto loser; 1.631 + } 1.632 + crv = lg_init(keyDB, flags, NULL, keydbPtr); 1.633 + if (crv != CKR_OK) { 1.634 + nsslowkey_CloseKeyDB(keydbPtr); 1.635 + goto loser; 1.636 + } 1.637 + if (certDB && *certDB) { 1.638 + LGPrivate *lgdb_p = (LGPrivate *)(*certDB)->private; 1.639 + lgdb_p->keyDB = keydbPtr; 1.640 + } 1.641 + } 1.642 + 1.643 +loser: 1.644 + if (crv != CKR_OK) { 1.645 + if (keyDB && *keyDB) { 1.646 + lg_Close(*keyDB); 1.647 + *keyDB = NULL; 1.648 + } 1.649 + if (certDB && *certDB) { 1.650 + lg_Close(*certDB); 1.651 + *certDB = NULL; 1.652 + } 1.653 + } 1.654 + return crv; 1.655 +} 1.656 + 1.657 +CK_RV 1.658 +legacy_Shutdown(PRBool forked) 1.659 +{ 1.660 + lg_SetForkState(forked); 1.661 + nsslowcert_DestroyFreeLists(); 1.662 + nsslowcert_DestroyGlobalLocks(); 1.663 + SECOID_Shutdown(); 1.664 + lg_SetForkState(PR_FALSE); 1.665 + return CKR_OK; 1.666 +} 1.667 +