mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 18:55:30 +00:00
Add transactions to the database update portion of the code.
This commit is contained in:
parent
9e6b49ed4f
commit
d31340924d
@ -32,7 +32,7 @@
|
||||
*
|
||||
* Private Key Database code
|
||||
*
|
||||
* $Id: keydb.c,v 1.20 2002/06/01 00:37:00 rangansen%netscape.com Exp $
|
||||
* $Id: keydb.c,v 1.21 2002/06/13 23:25:37 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include "lowkeyi.h"
|
||||
@ -831,16 +831,116 @@ done:
|
||||
return(SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
openNewDB(const char *appName, const char *prefix, const char *dbname,
|
||||
NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
char *updname = NULL;
|
||||
DB *updatedb = NULL;
|
||||
PRBool updated = PR_FALSE;
|
||||
int ret;
|
||||
|
||||
if (appName) {
|
||||
handle->db = rdbopen( appName, prefix, "key", NO_CREATE);
|
||||
} else {
|
||||
handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 );
|
||||
}
|
||||
/* if create fails then we lose */
|
||||
if ( handle->db == NULL ) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = db_BeginTransaction(handle->db);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* force a transactional read, which will verify that one and only one
|
||||
* process attempts the update. */
|
||||
if (nsslowkey_version(updatedb) == NSSLOWKEY_DB_FILE_VERSION) {
|
||||
/* someone else has already updated the database for us */
|
||||
db_FinishTransaction(handle->db, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we are creating a multiaccess database, see if there is a
|
||||
* local database we can update from.
|
||||
*/
|
||||
if (appName) {
|
||||
updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
if (updatedb) {
|
||||
handle->version = nsslowkey_version(updatedb);
|
||||
if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
|
||||
(updatedb->close)(updatedb);
|
||||
} else {
|
||||
db_Copy(handle->db, updatedb);
|
||||
(updatedb->close)(updatedb);
|
||||
db_FinishTransaction(updatedb,PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update the version number */
|
||||
rv = makeGlobalVersion(handle);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* try to update from v2 db
|
||||
*/
|
||||
updname = (*namecb)(cbarg, 2);
|
||||
if ( updname != NULL ) {
|
||||
handle->updatedb = dbopen( updname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free( updname );
|
||||
|
||||
if ( handle->updatedb ) {
|
||||
/*
|
||||
* Try to update the db using a null password. If the db
|
||||
* doesn't have a password, then this will work. If it does
|
||||
* have a password, then this will fail and we will do the
|
||||
* update later
|
||||
*/
|
||||
rv = nsslowkey_UpdateKeyDBPass1(handle);
|
||||
if ( rv == SECSuccess ) {
|
||||
updated = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we are using the old salt if we updated from an old db */
|
||||
if ( ! updated ) {
|
||||
rv = makeGlobalSalt(handle);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
/* sync the database */
|
||||
ret = (* handle->db->sync)(handle->db, 0);
|
||||
if ( ret ) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
db_FinishTransaction(handle->db, rv != SECSuccess);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NSSLOWKEYDBHandle *
|
||||
nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
|
||||
NSSLOWKEYDBNameFunc namecb, void *cbarg)
|
||||
{
|
||||
NSSLOWKEYDBHandle *handle;
|
||||
int ret;
|
||||
SECStatus rv;
|
||||
int openflags;
|
||||
char *dbname = NULL;
|
||||
PRBool updated = PR_FALSE;
|
||||
|
||||
handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle));
|
||||
if (handle == NULL) {
|
||||
@ -874,92 +974,22 @@ nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
|
||||
/* bogus version number record, reset the database */
|
||||
(* handle->db->close)( handle->db );
|
||||
handle->db = NULL;
|
||||
|
||||
goto newdb;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newdb:
|
||||
|
||||
/* if first open fails, try to create a new DB */
|
||||
if ( handle->db == NULL ) {
|
||||
if ( readOnly ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (appName) {
|
||||
handle->db = rdbopen( appName, prefix, "key", NO_CREATE);
|
||||
handle->updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
if (handle->updatedb) {
|
||||
handle->version = nsslowkey_version(handle->updatedb);
|
||||
if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
|
||||
(*handle->updatedb->close)(handle->updatedb);
|
||||
handle->updatedb = NULL;
|
||||
} else {
|
||||
db_Copy(handle->db, handle->updatedb);
|
||||
(*handle->updatedb->close)(handle->updatedb);
|
||||
handle->updatedb = NULL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 );
|
||||
}
|
||||
|
||||
PORT_Free( dbname );
|
||||
dbname = NULL;
|
||||
|
||||
/* if create fails then we lose */
|
||||
if ( handle->db == NULL ) {
|
||||
rv = openNewDB(appName, prefix, dbname, handle, namecb, cbarg);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = makeGlobalVersion(handle);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
/*
|
||||
* try to update from v2 db
|
||||
*/
|
||||
dbname = (*namecb)(cbarg, 2);
|
||||
if ( dbname != NULL ) {
|
||||
handle->updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free( dbname );
|
||||
dbname = NULL;
|
||||
|
||||
if ( handle->updatedb ) {
|
||||
/*
|
||||
* Try to update the db using a null password. If the db
|
||||
* doesn't have a password, then this will work. If it does
|
||||
* have a password, then this will fail and we will do the
|
||||
* update later
|
||||
*/
|
||||
rv = nsslowkey_UpdateKeyDBPass1(handle);
|
||||
if ( rv == SECSuccess ) {
|
||||
updated = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* we are using the old salt if we updated from an old db */
|
||||
if ( ! updated ) {
|
||||
rv = makeGlobalSalt(handle);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
/* sync the database */
|
||||
ret = (* handle->db->sync)(handle->db, 0);
|
||||
if ( ret ) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
handle->global_salt = GetKeyDBGlobalSalt(handle);
|
||||
if ( dbname )
|
||||
PORT_Free( dbname );
|
||||
|
@ -34,7 +34,7 @@
|
||||
/*
|
||||
* Permanent Certificate database handling code
|
||||
*
|
||||
* $Id: pcertdb.c,v 1.20 2002/05/21 21:26:14 relyea%netscape.com Exp $
|
||||
* $Id: pcertdb.c,v 1.21 2002/06/13 23:25:37 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "prtime.h"
|
||||
|
||||
@ -3565,6 +3565,100 @@ nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
|
||||
#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
|
||||
#endif
|
||||
|
||||
static SECStatus
|
||||
openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
|
||||
NSSLOWCERTCertDBHandle *handle, NSSLOWCERTDBNameFunc namecb, void *cbarg)
|
||||
{
|
||||
SECStatus rv;
|
||||
certDBEntryVersion *versionEntry = NULL;
|
||||
DB *updatedb = NULL;
|
||||
char *tmpname;
|
||||
PRBool updated = PR_FALSE;
|
||||
PRBool forceUpdate = PR_FALSE;
|
||||
|
||||
if (appName) {
|
||||
handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE);
|
||||
} else {
|
||||
handle->permCertDB=dbopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
|
||||
}
|
||||
|
||||
/* if create fails then we lose */
|
||||
if ( handle->permCertDB == 0 ) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = db_BeginTransaction(handle->permCertDB);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Verify version number; */
|
||||
|
||||
if (appName) {
|
||||
updatedb = dbopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0);
|
||||
if (updatedb) {
|
||||
db_Copy(handle->permCertDB,updatedb);
|
||||
(*updatedb->close)(updatedb);
|
||||
db_FinishTransaction(handle->permCertDB,PR_FALSE);
|
||||
return(SECSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
versionEntry = NewDBVersionEntry(0);
|
||||
if ( versionEntry == NULL ) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = WriteDBVersionEntry(handle, versionEntry);
|
||||
|
||||
DestroyDBEntry((certDBEntry *)versionEntry);
|
||||
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* try to upgrade old db here */
|
||||
tmpname = (* namecb)(cbarg, 6); /* get v6 db name */
|
||||
rv = SECSuccess;
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
rv = UpdateV6DB(handle, updatedb);
|
||||
} else { /* no v6 db, so try v5 db */
|
||||
tmpname = (* namecb)(cbarg, 5); /* get v5 db name */
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
rv = UpdateV5DB(handle, updatedb);
|
||||
} else { /* no v5 db, so try v4 db */
|
||||
/* try to upgrade v4 db */
|
||||
tmpname = (* namecb)(cbarg, 4); /* get v4 db name */
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600,
|
||||
DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
/* NES has v5 db's with v4 db names! */
|
||||
if (isV4DB(updatedb)) {
|
||||
rv = UpdateV4DB(handle, updatedb);
|
||||
} else {
|
||||
rv = UpdateV5DB(handle, updatedb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loser:
|
||||
db_FinishTransaction(handle->permCertDB,rv != SECSuccess);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the certificate database and index databases. Create them if
|
||||
* they are not there or bad.
|
||||
@ -3576,12 +3670,8 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
|
||||
{
|
||||
SECStatus rv;
|
||||
int openflags;
|
||||
certDBEntryVersion *versionEntry = NULL;
|
||||
DB *updatedb = NULL;
|
||||
char *tmpname;
|
||||
char *certdbname;
|
||||
PRBool updated = PR_FALSE;
|
||||
PRBool forceUpdate = PR_FALSE;
|
||||
certDBEntryVersion *versionEntry = NULL;
|
||||
|
||||
certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION);
|
||||
if ( certdbname == NULL ) {
|
||||
@ -3625,90 +3715,12 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
|
||||
if ( readOnly ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (appName) {
|
||||
handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE);
|
||||
|
||||
updatedb = dbopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0);
|
||||
if (updatedb) {
|
||||
db_Copy(handle->permCertDB,updatedb);
|
||||
(*updatedb->close)(updatedb);
|
||||
PORT_Free(certdbname);
|
||||
return(SECSuccess);
|
||||
}
|
||||
} else {
|
||||
handle->permCertDB=dbopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
|
||||
}
|
||||
|
||||
/* if create fails then we lose */
|
||||
if ( handle->permCertDB == 0 ) {
|
||||
rv = openNewCertDB(appName,prefix,certdbname,handle,namecb,cbarg);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
versionEntry = NewDBVersionEntry(0);
|
||||
if ( versionEntry == NULL ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = WriteDBVersionEntry(handle, versionEntry);
|
||||
|
||||
DestroyDBEntry((certDBEntry *)versionEntry);
|
||||
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* try to upgrade old db here */
|
||||
tmpname = (* namecb)(cbarg, 6); /* get v6 db name */
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
rv = UpdateV6DB(handle, updatedb);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
updated = PR_TRUE;
|
||||
} else { /* no v6 db, so try v5 db */
|
||||
tmpname = (* namecb)(cbarg, 5); /* get v5 db name */
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
rv = UpdateV5DB(handle, updatedb);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
updated = PR_TRUE;
|
||||
} else { /* no v5 db, so try v4 db */
|
||||
/* try to upgrade v4 db */
|
||||
tmpname = (* namecb)(cbarg, 4); /* get v4 db name */
|
||||
if ( tmpname ) {
|
||||
updatedb = dbopen( tmpname, NO_RDONLY, 0600,
|
||||
DB_HASH, 0 );
|
||||
PORT_Free(tmpname);
|
||||
if ( updatedb ) {
|
||||
/* NES has v5 db's with v4 db names! */
|
||||
if (isV4DB(updatedb)) {
|
||||
rv = UpdateV4DB(handle, updatedb);
|
||||
} else {
|
||||
rv = UpdateV5DB(handle, updatedb);
|
||||
}
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
forceUpdate = PR_TRUE;
|
||||
updated = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Root certs are no longer automatically added to the DB. They
|
||||
* come from and external PKCS #11 file.
|
||||
*/
|
||||
}
|
||||
|
||||
PORT_Free(certdbname);
|
||||
|
Loading…
Reference in New Issue
Block a user