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

Packit 40b132
/*
Packit 40b132
 * NSS utility functions
Packit 40b132
 *
Packit 40b132
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
Packit 40b132
#include "lowkeyi.h"
Packit 40b132
#include "pcert.h"
Packit 40b132
#include "keydbi.h"
Packit 40b132
#include "lgdb.h"
Packit 40b132
#include "secoid.h"
Packit 40b132
#include "prenv.h"
Packit 40b132
#include "softkver.h"
Packit 40b132
Packit 40b132
/* Library identity and versioning */
Packit 40b132
Packit 40b132
#if defined(DEBUG)
Packit 40b132
#define _DEBUG_STRING " (debug)"
Packit 40b132
#else
Packit 40b132
#define _DEBUG_STRING ""
Packit 40b132
#endif
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * Version information
Packit 40b132
 */
Packit 40b132
const char __nss_dbm_version[] = "Version: NSS " SOFTOKEN_VERSION _DEBUG_STRING;
Packit 40b132
Packit 40b132
typedef struct LGPrivateStr {
Packit 40b132
    NSSLOWCERTCertDBHandle *certDB;
Packit 40b132
    NSSLOWKEYDBHandle *keyDB;
Packit 40b132
    PRLock *dbLock;
Packit 40b132
    PLHashTable *hashTable;
Packit 40b132
} LGPrivate;
Packit 40b132
Packit 40b132
static char *
Packit 40b132
lg_certdb_name_cb(void *arg, int dbVersion)
Packit 40b132
{
Packit 40b132
    const char *configdir = (const char *)arg;
Packit 40b132
    const char *dbver;
Packit 40b132
    char *smpname = NULL;
Packit 40b132
    char *dbname = NULL;
Packit 40b132
Packit 40b132
    switch (dbVersion) {
Packit 40b132
      case 8:
Packit 40b132
	dbver = "8";
Packit 40b132
	break;
Packit 40b132
      case 7:
Packit 40b132
	dbver = "7";
Packit 40b132
	break;
Packit 40b132
      case 6:
Packit 40b132
	dbver = "6";
Packit 40b132
	break;
Packit 40b132
      case 5:
Packit 40b132
	dbver = "5";
Packit 40b132
	break;
Packit 40b132
      case 4:
Packit 40b132
      default:
Packit 40b132
	dbver = "";
Packit 40b132
	break;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* make sure we return something allocated with PORT_ so we have properly
Packit 40b132
     * matched frees at the end */
Packit 40b132
    smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
Packit 40b132
    if (smpname) {
Packit 40b132
	dbname = PORT_Strdup(smpname);
Packit 40b132
	PR_smprintf_free(smpname);
Packit 40b132
    }
Packit 40b132
    return dbname;
Packit 40b132
}
Packit 40b132
    
Packit 40b132
static char *
Packit 40b132
lg_keydb_name_cb(void *arg, int dbVersion)
Packit 40b132
{
Packit 40b132
    const char *configdir = (const char *)arg;
Packit 40b132
    const char *dbver;
Packit 40b132
    char *smpname = NULL;
Packit 40b132
    char *dbname = NULL;
Packit 40b132
    
Packit 40b132
    switch (dbVersion) {
Packit 40b132
      case 4:
Packit 40b132
	dbver = "4";
Packit 40b132
	break;
Packit 40b132
      case 3:
Packit 40b132
	dbver = "3";
Packit 40b132
	break;
Packit 40b132
      case 1:
Packit 40b132
	dbver = "1";
Packit 40b132
	break;
Packit 40b132
      case 2:
Packit 40b132
      default:
Packit 40b132
	dbver = "";
Packit 40b132
	break;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver);
Packit 40b132
    if (smpname) {
Packit 40b132
	dbname = PORT_Strdup(smpname);
Packit 40b132
	PR_smprintf_free(smpname);
Packit 40b132
    }
Packit 40b132
    return dbname;
Packit 40b132
}
Packit 40b132
Packit 40b132
const char *
Packit 40b132
lg_EvaluateConfigDir(const char *configdir,char **appName)
Packit 40b132
{
Packit 40b132
    if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
Packit 40b132
	char *cdir;
Packit 40b132
Packit 40b132
	*appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
Packit 40b132
	if (*appName == NULL) {
Packit 40b132
	    return configdir;
Packit 40b132
	}
Packit 40b132
	cdir = *appName;
Packit 40b132
	while (*cdir && *cdir != ':') {
Packit 40b132
	    cdir++;
Packit 40b132
	}
Packit 40b132
	if (*cdir == ':') {
Packit 40b132
	   *cdir = 0;
Packit 40b132
	   cdir++;
Packit 40b132
	}
Packit 40b132
	configdir = cdir;
Packit 40b132
    }
Packit 40b132
    return configdir;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int rdbmapflags(int flags);
Packit 40b132
static rdbfunc lg_rdbfunc = NULL;
Packit 40b132
static rdbstatusfunc lg_rdbstatusfunc = NULL;
Packit 40b132
Packit 40b132
/* NOTE: SHLIB_SUFFIX is defined on the command line */
Packit 40b132
#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX
Packit 40b132
Packit 40b132
DB * rdbopen(const char *appName, const char *prefix, 
Packit 40b132
			const char *type, int flags, int *status)
Packit 40b132
{
Packit 40b132
    PRLibrary *lib;
Packit 40b132
    DB *db;
Packit 40b132
    char *disableUnload = NULL;
Packit 40b132
Packit 40b132
    if (lg_rdbfunc) {
Packit 40b132
	db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
Packit 40b132
	if (!db && status && lg_rdbstatusfunc) {
Packit 40b132
	    *status = (*lg_rdbstatusfunc)();
Packit 40b132
	}
Packit 40b132
	return db;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*
Packit 40b132
     * try to open the library.
Packit 40b132
     */
Packit 40b132
    lib = PR_LoadLibrary(RDBLIB);
Packit 40b132
Packit 40b132
    if (!lib) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* get the entry points */
Packit 40b132
    lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
Packit 40b132
    lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
Packit 40b132
    if (lg_rdbfunc) {
Packit 40b132
	db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
Packit 40b132
	if (!db && status && lg_rdbstatusfunc) {
Packit 40b132
	    *status = (*lg_rdbstatusfunc)();
Packit 40b132
	}
Packit 40b132
	return db;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* couldn't find the entry point, unload the library and fail */
Packit 40b132
    disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
Packit 40b132
    if (!disableUnload) {
Packit 40b132
        PR_UnloadLibrary(lib);
Packit 40b132
    }
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * the following data structures are from rdb.h.
Packit 40b132
 */
Packit 40b132
struct RDBStr {
Packit 40b132
    DB	db;
Packit 40b132
    int (*xactstart)(DB *db);
Packit 40b132
    int (*xactdone)(DB *db, PRBool abort);
Packit 40b132
    int version;
Packit 40b132
    int (*dbinitcomplete)(DB *db);
Packit 40b132
};
Packit 40b132
Packit 40b132
#define DB_RDB ((DBTYPE) 0xff)
Packit 40b132
#define RDB_RDONLY	1
Packit 40b132
#define RDB_RDWR 	2
Packit 40b132
#define RDB_CREATE      4
Packit 40b132
Packit 40b132
static int
Packit 40b132
rdbmapflags(int flags) {
Packit 40b132
   switch (flags) {
Packit 40b132
   case NO_RDONLY:
Packit 40b132
	return RDB_RDONLY;
Packit 40b132
   case NO_RDWR:
Packit 40b132
	return RDB_RDWR;
Packit 40b132
   case NO_CREATE:
Packit 40b132
	return RDB_CREATE;
Packit 40b132
   default:
Packit 40b132
	break;
Packit 40b132
   }
Packit 40b132
   return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
PRBool
Packit 40b132
db_IsRDB(DB *db)
Packit 40b132
{
Packit 40b132
    return (PRBool) db->type == DB_RDB;
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
db_BeginTransaction(DB *db)
Packit 40b132
{
Packit 40b132
    struct RDBStr *rdb = (struct RDBStr *)db;
Packit 40b132
    if (db->type != DB_RDB) {
Packit 40b132
	return 0;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return rdb->xactstart(db);
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
db_FinishTransaction(DB *db, PRBool abort)
Packit 40b132
{
Packit 40b132
    struct RDBStr *rdb = (struct RDBStr *)db;
Packit 40b132
    if (db->type != DB_RDB) {
Packit 40b132
	return 0;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return rdb->xactdone(db, abort);
Packit 40b132
}
Packit 40b132
Packit 40b132
static DB *
Packit 40b132
lg_getRawDB(SDB *sdb)
Packit 40b132
{
Packit 40b132
    NSSLOWCERTCertDBHandle *certDB;
Packit 40b132
    NSSLOWKEYDBHandle *keyDB;
Packit 40b132
Packit 40b132
    certDB = lg_getCertDB(sdb);
Packit 40b132
    if (certDB) {
Packit 40b132
	return certDB->permCertDB;
Packit 40b132
    }
Packit 40b132
    keyDB = lg_getKeyDB(sdb);
Packit 40b132
    if (keyDB) {
Packit 40b132
	return keyDB->db;
Packit 40b132
    }
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_RV
Packit 40b132
lg_Begin(SDB *sdb)
Packit 40b132
{
Packit 40b132
    DB *db = lg_getRawDB(sdb);
Packit 40b132
    int ret;
Packit 40b132
Packit 40b132
    if (db == NULL) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* shouldn't happen */
Packit 40b132
    }
Packit 40b132
    ret = db_BeginTransaction(db);
Packit 40b132
    if (ret != 0) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* could happen */
Packit 40b132
    }
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_RV
Packit 40b132
lg_Commit(SDB *sdb)
Packit 40b132
{
Packit 40b132
    DB *db = lg_getRawDB(sdb);
Packit 40b132
    int ret;
Packit 40b132
Packit 40b132
    if (db == NULL) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* shouldn't happen */
Packit 40b132
    }
Packit 40b132
    ret = db_FinishTransaction(db, PR_FALSE);
Packit 40b132
    if (ret != 0) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* could happen */
Packit 40b132
    }
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_RV
Packit 40b132
lg_Abort(SDB *sdb)
Packit 40b132
{
Packit 40b132
    DB *db = lg_getRawDB(sdb);
Packit 40b132
    int ret;
Packit 40b132
Packit 40b132
    if (db == NULL) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* shouldn't happen */
Packit 40b132
    }
Packit 40b132
    ret = db_FinishTransaction(db, PR_TRUE);
Packit 40b132
    if (ret != 0) {
Packit 40b132
	return CKR_GENERAL_ERROR; /* could happen */
Packit 40b132
    }
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
db_InitComplete(DB *db)
Packit 40b132
{
Packit 40b132
    struct RDBStr *rdb = (struct RDBStr *)db;
Packit 40b132
    if (db->type != DB_RDB) {
Packit 40b132
	return 0;
Packit 40b132
    }
Packit 40b132
    /* we should have added a version number to the RDBS structure. Since we
Packit 40b132
     * didn't, we detect that we have and 'extended' structure if the rdbstatus
Packit 40b132
     * func exists */
Packit 40b132
    if (!lg_rdbstatusfunc) {
Packit 40b132
	return 0;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return rdb->dbinitcomplete(db);
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
Packit 40b132
SECStatus
Packit 40b132
db_Copy(DB *dest,DB *src)
Packit 40b132
{
Packit 40b132
    int ret;
Packit 40b132
    DBT key,data;
Packit 40b132
    ret = (*src->seq)(src, &key, &data, R_FIRST);
Packit 40b132
    if (ret)  {
Packit 40b132
	return SECSuccess;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    do {
Packit 40b132
	(void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
Packit 40b132
    } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
Packit 40b132
    (void)(*dest->sync)(dest,0);
Packit 40b132
Packit 40b132
    return SECSuccess;
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
static CK_RV
Packit 40b132
lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
Packit 40b132
    					    NSSLOWCERTCertDBHandle **certdbPtr)
Packit 40b132
{
Packit 40b132
    NSSLOWCERTCertDBHandle *certdb = NULL;
Packit 40b132
    CK_RV        crv = CKR_NETSCAPE_CERTDB_FAILED;
Packit 40b132
    SECStatus    rv;
Packit 40b132
    char * name = NULL;
Packit 40b132
    char * appName = NULL;
Packit 40b132
Packit 40b132
    if (prefix == NULL) {
Packit 40b132
	prefix = "";
Packit 40b132
    }
Packit 40b132
Packit 40b132
    configdir = lg_EvaluateConfigDir(configdir, &appName);
Packit 40b132
Packit 40b132
    name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
Packit 40b132
    if (name == NULL) goto loser;
Packit 40b132
Packit 40b132
    certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
Packit 40b132
    if (certdb == NULL) 
Packit 40b132
    	goto loser;
Packit 40b132
Packit 40b132
    certdb->ref = 1;
Packit 40b132
/* fix when we get the DB in */
Packit 40b132
    rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
Packit 40b132
				lg_certdb_name_cb, (void *)name, PR_FALSE);
Packit 40b132
    if (rv == SECSuccess) {
Packit 40b132
	crv = CKR_OK;
Packit 40b132
	*certdbPtr = certdb;
Packit 40b132
	certdb = NULL;
Packit 40b132
    }
Packit 40b132
loser: 
Packit 40b132
    if (certdb) PR_Free(certdb);
Packit 40b132
    if (name) PR_smprintf_free(name);
Packit 40b132
    if (appName) PORT_Free(appName);
Packit 40b132
    return crv;
Packit 40b132
}
Packit 40b132
Packit 40b132
static CK_RV
Packit 40b132
lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
Packit 40b132
    						NSSLOWKEYDBHandle **keydbPtr)
Packit 40b132
{
Packit 40b132
    NSSLOWKEYDBHandle *keydb;
Packit 40b132
    char * name = NULL;
Packit 40b132
    char * appName = NULL;
Packit 40b132
Packit 40b132
    if (prefix == NULL) {
Packit 40b132
	prefix = "";
Packit 40b132
    }
Packit 40b132
    configdir = lg_EvaluateConfigDir(configdir, &appName);
Packit 40b132
Packit 40b132
    name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);	
Packit 40b132
    if (name == NULL) 
Packit 40b132
	return CKR_HOST_MEMORY;
Packit 40b132
    keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix, 
Packit 40b132
					lg_keydb_name_cb, (void *)name);
Packit 40b132
    PR_smprintf_free(name);
Packit 40b132
    if (appName) PORT_Free(appName);
Packit 40b132
    if (keydb == NULL)
Packit 40b132
	return CKR_NETSCAPE_KEYDB_FAILED;
Packit 40b132
    *keydbPtr = keydb;
Packit 40b132
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * Accessors for the private parts of the sdb structure.
Packit 40b132
 */
Packit 40b132
void
Packit 40b132
lg_DBLock(SDB *sdb) 
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
    SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock));
Packit 40b132
}
Packit 40b132
Packit 40b132
void
Packit 40b132
lg_DBUnlock(SDB *sdb) 
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
    SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock));
Packit 40b132
}
Packit 40b132
Packit 40b132
PLHashTable *
Packit 40b132
lg_GetHashTable(SDB *sdb) 
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
    return lgdb_p->hashTable;
Packit 40b132
}
Packit 40b132
Packit 40b132
NSSLOWCERTCertDBHandle *
Packit 40b132
lg_getCertDB(SDB *sdb)
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
Packit 40b132
    return lgdb_p->certDB;
Packit 40b132
}
Packit 40b132
Packit 40b132
NSSLOWKEYDBHandle *
Packit 40b132
lg_getKeyDB(SDB *sdb)
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
Packit 40b132
    return lgdb_p->keyDB;
Packit 40b132
}
Packit 40b132
Packit 40b132
PRBool lg_parentForkedAfterC_Initialize;
Packit 40b132
Packit 40b132
void lg_SetForkState(PRBool forked)
Packit 40b132
{
Packit 40b132
    lg_parentForkedAfterC_Initialize = forked;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_RV
Packit 40b132
lg_Close(SDB *sdb)
Packit 40b132
{
Packit 40b132
    LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
Packit 40b132
    lg_ClearTokenKeyHashTable(sdb);
Packit 40b132
    if (lgdb_p) {
Packit 40b132
    	if (lgdb_p->certDB) {
Packit 40b132
	    nsslowcert_ClosePermCertDB(lgdb_p->certDB);
Packit 40b132
	} else if (lgdb_p->keyDB) {
Packit 40b132
	    nsslowkey_CloseKeyDB(lgdb_p->keyDB);
Packit 40b132
	}
Packit 40b132
	if (lgdb_p->dbLock) {
Packit 40b132
	    SKIP_AFTER_FORK(PR_DestroyLock(lgdb_p->dbLock));
Packit 40b132
	}
Packit 40b132
	if (lgdb_p->hashTable) {
Packit 40b132
	    PL_HashTableDestroy(lgdb_p->hashTable);
Packit 40b132
	}
Packit 40b132
	PORT_Free(lgdb_p);
Packit 40b132
    }
Packit 40b132
    PORT_Free(sdb);
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132
Packit 40b132
static PLHashNumber
Packit 40b132
lg_HashNumber(const void *key)
Packit 40b132
{
Packit 40b132
    return (PLHashNumber) key;
Packit 40b132
}
Packit 40b132
Packit 40b132
PRIntn
Packit 40b132
lg_CompareValues(const void *v1, const void *v2)
Packit 40b132
{
Packit 40b132
    PLHashNumber value1 = (PLHashNumber) v1;
Packit 40b132
    PLHashNumber value2 = (PLHashNumber) v2;
Packit 40b132
    return (value1 == value2);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle
Packit 40b132
 * with and sdb structure.
Packit 40b132
 */
Packit 40b132
CK_RV 
Packit 40b132
lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr,
Packit 40b132
	 NSSLOWKEYDBHandle *keydbPtr)
Packit 40b132
{
Packit 40b132
    SDB *sdb = NULL;
Packit 40b132
    LGPrivate *lgdb_p = NULL;
Packit 40b132
    CK_RV error = CKR_HOST_MEMORY;
Packit 40b132
Packit 40b132
    *pSdb = NULL;
Packit 40b132
    sdb = (SDB *) PORT_Alloc(sizeof(SDB));
Packit 40b132
    if (sdb == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
    lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate));
Packit 40b132
    if (lgdb_p == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
    /* invariant fields */
Packit 40b132
    lgdb_p->certDB = certdbPtr;
Packit 40b132
    lgdb_p->keyDB = keydbPtr;
Packit 40b132
    lgdb_p->dbLock = PR_NewLock();
Packit 40b132
    if (lgdb_p->dbLock == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
    lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, lg_CompareValues,
Packit 40b132
			SECITEM_HashCompare, NULL, 0);
Packit 40b132
    if (lgdb_p->hashTable == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    sdb->private = lgdb_p;
Packit 40b132
    sdb->version = 0;
Packit 40b132
    /*sdb->sdb_type = SDB_LEGACY; */
Packit 40b132
    sdb->sdb_flags = flags;
Packit 40b132
    sdb->app_private = NULL;
Packit 40b132
    sdb->sdb_FindObjectsInit = lg_FindObjectsInit;
Packit 40b132
    sdb->sdb_FindObjects = lg_FindObjects;
Packit 40b132
    sdb->sdb_FindObjectsFinal = lg_FindObjectsFinal;
Packit 40b132
    sdb->sdb_GetAttributeValue = lg_GetAttributeValue;
Packit 40b132
    sdb->sdb_SetAttributeValue = lg_SetAttributeValue;
Packit 40b132
    sdb->sdb_CreateObject = lg_CreateObject;
Packit 40b132
    sdb->sdb_DestroyObject = lg_DestroyObject;
Packit 40b132
    sdb->sdb_GetMetaData = lg_GetMetaData;
Packit 40b132
    sdb->sdb_PutMetaData = lg_PutMetaData;
Packit 40b132
    sdb->sdb_Begin = lg_Begin;
Packit 40b132
    sdb->sdb_Commit = lg_Commit;
Packit 40b132
    sdb->sdb_Abort = lg_Abort;
Packit 40b132
    sdb->sdb_Reset = lg_Reset;
Packit 40b132
    sdb->sdb_Close = lg_Close;
Packit 40b132
    sdb->sdb_SetForkState = lg_SetForkState;
Packit 40b132
Packit 40b132
    *pSdb = sdb;
Packit 40b132
    return CKR_OK;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    if (sdb) {
Packit 40b132
	PORT_Free(sdb);
Packit 40b132
    }
Packit 40b132
    if (lgdb_p) {
Packit 40b132
	if (lgdb_p->dbLock) {
Packit 40b132
	    PR_DestroyLock(lgdb_p->dbLock);
Packit 40b132
	}
Packit 40b132
	if (lgdb_p->hashTable) {
Packit 40b132
	    PL_HashTableDestroy(lgdb_p->hashTable);
Packit 40b132
	}
Packit 40b132
	PORT_Free(lgdb_p);
Packit 40b132
    }
Packit 40b132
    return error;
Packit 40b132
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * OK there are now lots of options here, lets go through them all:
Packit 40b132
 *
Packit 40b132
 * configdir - base directory where all the cert, key, and module datbases live.
Packit 40b132
 * certPrefix - prefix added to the beginning of the cert database example: "
Packit 40b132
 * 			"https-server1-"
Packit 40b132
 * keyPrefix - prefix added to the beginning of the key database example: "
Packit 40b132
 * 			"https-server1-"
Packit 40b132
 * secmodName - name of the security module database (usually "secmod.db").
Packit 40b132
 * readOnly - Boolean: true if the databases are to be openned read only.
Packit 40b132
 * nocertdb - Don't open the cert DB and key DB's, just initialize the 
Packit 40b132
 *			Volatile certdb.
Packit 40b132
 * nomoddb - Don't open the security module DB, just initialize the 
Packit 40b132
 *			PKCS #11 module.
Packit 40b132
 * forceOpen - Continue to force initializations even if the databases cannot
Packit 40b132
 * 			be opened.
Packit 40b132
 */
Packit 40b132
CK_RV
Packit 40b132
legacy_Open(const char *configdir, const char *certPrefix, 
Packit 40b132
	    const char *keyPrefix, int certVersion, int keyVersion,
Packit 40b132
	    int flags, SDB **certDB, SDB **keyDB)
Packit 40b132
{
Packit 40b132
    CK_RV crv = CKR_OK;
Packit 40b132
    SECStatus rv;
Packit 40b132
    PRBool readOnly = (flags == SDB_RDONLY)? PR_TRUE: PR_FALSE;
Packit 40b132
    volatile char c; /* force a reference that won't get optimized away */
Packit 40b132
Packit 40b132
    c = __nss_dbm_version[0];
Packit 40b132
Packit 40b132
    rv = SECOID_Init();
Packit 40b132
    if (SECSuccess != rv) {
Packit 40b132
        return CKR_DEVICE_ERROR;
Packit 40b132
    }
Packit 40b132
    nsslowcert_InitLocks();
Packit 40b132
Packit 40b132
    if (keyDB) *keyDB = NULL;
Packit 40b132
    if (certDB) *certDB = NULL;
Packit 40b132
Packit 40b132
    if (certDB) {
Packit 40b132
	NSSLOWCERTCertDBHandle *certdbPtr;
Packit 40b132
Packit 40b132
	crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr);
Packit 40b132
	if (crv != CKR_OK) {
Packit 40b132
	    goto loser;
Packit 40b132
	}
Packit 40b132
	crv = lg_init(certDB, flags, certdbPtr, NULL);
Packit 40b132
	if (crv != CKR_OK) {
Packit 40b132
	    nsslowcert_ClosePermCertDB(certdbPtr);
Packit 40b132
	    goto loser;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    if (keyDB) {
Packit 40b132
	NSSLOWKEYDBHandle *keydbPtr;
Packit 40b132
Packit 40b132
	crv = lg_OpenKeyDB(configdir, keyPrefix, readOnly, &keydbPtr);
Packit 40b132
	if (crv != CKR_OK) {
Packit 40b132
	    goto loser;
Packit 40b132
	}
Packit 40b132
	crv = lg_init(keyDB, flags, NULL, keydbPtr);
Packit 40b132
	if (crv != CKR_OK) {
Packit 40b132
	    nsslowkey_CloseKeyDB(keydbPtr);
Packit 40b132
	    goto loser;
Packit 40b132
	}
Packit 40b132
	if (certDB && *certDB) {
Packit 40b132
	    LGPrivate *lgdb_p = (LGPrivate *)(*certDB)->private;
Packit 40b132
	    lgdb_p->keyDB = keydbPtr;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    if (crv != CKR_OK) {
Packit 40b132
	if (keyDB && *keyDB) {
Packit 40b132
	    lg_Close(*keyDB);
Packit 40b132
	    *keyDB = NULL;
Packit 40b132
	}
Packit 40b132
	if (certDB && *certDB) {
Packit 40b132
	    lg_Close(*certDB);
Packit 40b132
	    *certDB = NULL;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return crv;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_RV
Packit 40b132
legacy_Shutdown(PRBool forked)
Packit 40b132
{
Packit 40b132
    lg_SetForkState(forked);
Packit 40b132
    nsslowcert_DestroyFreeLists();
Packit 40b132
    nsslowcert_DestroyGlobalLocks();
Packit 40b132
    SECOID_Shutdown();
Packit 40b132
    lg_SetForkState(PR_FALSE);
Packit 40b132
    return CKR_OK;
Packit 40b132
}
Packit 40b132