/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 * This file implements PKCS 11 on top of our existing security modules
 *
 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
 *   This implementation has two slots:
 *      slot 1 is our generic crypto support. It does not require login.
 *   It supports Public Key ops, and all they bulk ciphers and hashes.
 *   It can also support Private Key ops for imported Private keys. It does
 *   not have any token storage.
 *      slot 2 is our private key support. It requires a login before use. It
 *   can store Private Keys and Certs as token objects. Currently only private
 *   keys and their associated Certificates are saved on the token.
 *
 *   In this implementation, session objects are only visible to the session
 *   that created or generated them.
 */

#include "sdb.h"
#include "pkcs11t.h"
#include "seccomon.h"
#include <sqlite3.h>
#include "prthread.h"
#include "prio.h"
#include <stdio.h>
#include "secport.h"
#include "prmon.h"
#include "prenv.h"
#include "prprf.h"
#include "prsystem.h" /* for PR_GetDirectorySeparator() */
#include <sys/stat.h>
#if defined(_WIN32)
#include <io.h>
#include <windows.h>
#elif defined(XP_UNIX)
#include <unistd.h>
#endif
#if defined(LINUX) && !defined(ANDROID)
#include <linux/magic.h>
#include <sys/vfs.h>
#endif
#include "utilpars.h"

#ifdef SQLITE_UNSAFE_THREADS
#include "prlock.h"
/*
 * SQLite can be compiled to be thread safe or not.
 * turn on SQLITE_UNSAFE_THREADS if the OS does not support
 * a thread safe version of sqlite.
 */
static PRLock *sqlite_lock = NULL;

#define LOCK_SQLITE() PR_Lock(sqlite_lock);
#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock);
#else
#define LOCK_SQLITE()
#define UNLOCK_SQLITE()
#endif

typedef enum {
    SDB_CERT = 1,
    SDB_KEY = 2
} sdbDataType;

/*
 * defines controlling how long we wait to acquire locks.
 *
 * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds)
 *  sqlite will wait on lock. If that timeout expires, sqlite will
 *  return SQLITE_BUSY.
 * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits
 *  after receiving a busy before retrying.
 * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on
 *  a busy condition.
 *
 * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual
 *   (prepare/step/reset/finalize) and automatic (sqlite3_exec()).
 * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations
 *
 * total wait time for automatic operations:
 *   1 second (SDB_SQLITE_BUSY_TIMEOUT/1000).
 * total wait time for manual operations:
 *   (1 second + SDB_BUSY_RETRY_TIME) * 30 = 30 seconds.
 * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES
 */
#define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */
#define SDB_BUSY_RETRY_TIME 5        /* 'ticks', varies by platforms */
#define SDB_MAX_BUSY_RETRIES 30

/*
 * known attributes
 */
static const CK_ATTRIBUTE_TYPE known_attributes[] = {
    CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
    CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
    CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
    CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
    CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
    CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
    CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
    CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
    CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
    CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
    CKA_PUBLIC_KEY_INFO, CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS,
    CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
    CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
    CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
    CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
    CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_HW_FEATURE_TYPE,
    CKA_RESET_ON_INIT, CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y,
    CKA_RESOLUTION, CKA_CHAR_ROWS, CKA_CHAR_COLUMNS, CKA_COLOR,
    CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, CKA_ENCODING_METHODS, CKA_MIME_TYPES,
    CKA_MECHANISM_TYPE, CKA_REQUIRED_CMS_ATTRIBUTES,
    CKA_DEFAULT_CMS_ATTRIBUTES, CKA_SUPPORTED_CMS_ATTRIBUTES,
    CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE, CKA_NSS_TRUST, CKA_NSS_URL,
    CKA_NSS_EMAIL, CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP,
    CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES,
    CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED,
    CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC,
    CKA_NSS_OVERRIDE_EXTENSIONS, CKA_NSS_SERVER_DISTRUST_AFTER,
    CKA_NSS_EMAIL_DISTRUST_AFTER, CKA_TRUST_DIGITAL_SIGNATURE,
    CKA_TRUST_NON_REPUDIATION, CKA_TRUST_KEY_ENCIPHERMENT,
    CKA_TRUST_DATA_ENCIPHERMENT, CKA_TRUST_KEY_AGREEMENT,
    CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, CKA_TRUST_SERVER_AUTH,
    CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
    CKA_TRUST_IPSEC_END_SYSTEM, CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
    CKA_TRUST_TIME_STAMPING, CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH,
    CKA_CERT_MD5_HASH, CKA_NSS_DB
};

static const int known_attributes_size = PR_ARRAY_SIZE(known_attributes);

/*
 * Note on use of sqlReadDB: Only one thread at a time may have an actual
 * operation going on given sqlite3 * database. An operation is defined as
 * the time from a sqlite3_prepare() until the sqlite3_finalize().
 * Multiple sqlite3 * databases can be open and have simultaneous operations
 * going. We use the sqlXactDB for all write operations. This database
 * is only opened when we first create a transaction and closed when the
 * transaction is complete. sqlReadDB is open when we first opened the database
 * and is used for all read operation. It's use is protected by a monitor. This
 * is because an operation can span the use of FindObjectsInit() through the
 * call to FindObjectsFinal(). In the intermediate time it is possible to call
 * other operations like NSC_GetAttributeValue */

struct SDBPrivateStr {
    char *sqlDBName;                /* invariant, path to this database */
    sqlite3 *sqlXactDB;             /* access protected by dbMon, use protected
                                    * by the transaction. Current transaction db*/
    PRThread *sqlXactThread;        /* protected by dbMon,
                                    * current transaction thread */
    sqlite3 *sqlReadDB;             /* use protected by dbMon, value invariant */
    PRIntervalTime lastUpdateTime;  /* last time the cache was updated */
    PRIntervalTime updateInterval;  /* how long the cache can go before it
                                    * must be updated again */
    sdbDataType type;               /* invariant, database type */
    char *table;                    /* invariant, SQL table which contains the db */
    char *cacheTable;               /* invariant, SQL table cache of db */
    PRMonitor *dbMon;               /* invariant, monitor to protect
                                    * sqlXact* fields, and use of the sqlReadDB */
    CK_ATTRIBUTE_TYPE *schemaAttrs; /* Attribute columns that exist in the table. */
    unsigned int numSchemaAttrs;
};

typedef struct SDBPrivateStr SDBPrivate;

/* Magic for an explicit NULL. NOTE: ideally this should be
 * out of band data. Since it's not completely out of band, pick
 * a value that has no meaning to any existing PKCS #11 attributes.
 * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG
 * or a normal key (too short). 3) not a bool (too long). 4) not an RSA
 * public exponent (too many bits).
 */
const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a };
#define SQLITE_EXPLICIT_NULL_LEN 3

/*
 * determine when we've completed our tasks
 */
static int
sdb_done(int err, int *count)
{
    /* allow as many rows as the database wants to give */
    if (err == SQLITE_ROW) {
        *count = 0;
        return 0;
    }
    if (err != SQLITE_BUSY) {
        return 1;
    }
    /* err == SQLITE_BUSY, Dont' retry forever in this case */
    if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
        return 1;
    }
    return 0;
}

#if defined(_WIN32)
/*
 * NSPR functions and narrow CRT functions do not handle UTF-8 file paths that
 * sqlite3 expects.
 */

static int
sdb_chmod(const char *filename, int pmode)
{
    int result;

    if (!filename) {
        return -1;
    }

    wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename);
    if (!filenameWide) {
        return -1;
    }
    result = _wchmod(filenameWide, pmode);
    PORT_Free(filenameWide);

    return result;
}
#else
#define sdb_chmod(filename, pmode) chmod((filename), (pmode))
#endif

/*
 * find out where sqlite stores the temp tables. We do this by replicating
 * the logic from sqlite.
 */
#if defined(_WIN32)
static char *
sdb_getFallbackTempDir(void)
{
    /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
     * access to sqlite3_temp_directory because it is not exported from
     * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
     * sqlite3_temp_directory is NULL.
     */
    char path[MAX_PATH];
    DWORD rv;
    size_t len;

    rv = GetTempPathA(MAX_PATH, path);
    if (rv > MAX_PATH || rv == 0)
        return NULL;
    len = strlen(path);
    if (len == 0)
        return NULL;
    /* The returned string ends with a backslash, for example, "C:\TEMP\". */
    if (path[len - 1] == '\\')
        path[len - 1] = '\0';
    return PORT_Strdup(path);
}
#elif defined(XP_UNIX)
static char *
sdb_getFallbackTempDir(void)
{
    const char *azDirs[] = {
        NULL,
        NULL,
        "/var/tmp",
        "/usr/tmp",
        "/tmp",
        NULL /* List terminator */
    };
    unsigned int i;
    struct stat buf;
    const char *zDir = NULL;

    azDirs[0] = sqlite3_temp_directory;
    azDirs[1] = PR_GetEnvSecure("TMPDIR");

    for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
        zDir = azDirs[i];
        if (zDir == NULL)
            continue;
        if (stat(zDir, &buf))
            continue;
        if (!S_ISDIR(buf.st_mode))
            continue;
        if (access(zDir, 07))
            continue;
        break;
    }

    if (zDir == NULL)
        return NULL;
    return PORT_Strdup(zDir);
}
#else
#error "sdb_getFallbackTempDir not implemented"
#endif

#ifndef SQLITE_FCNTL_TEMPFILENAME
/* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
#define SQLITE_FCNTL_TEMPFILENAME 16
#endif

static char *
sdb_getTempDir(sqlite3 *sqlDB)
{
    int sqlrv;
    char *result = NULL;
    char *tempName = NULL;
    char *foundSeparator = NULL;

    /* Obtain temporary filename in sqlite's directory for temporary tables */
    sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
                                 (void *)&tempName);
    if (sqlrv == SQLITE_NOTFOUND) {
        /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
         * an older SQLite. */
        return sdb_getFallbackTempDir();
    }
    if (sqlrv != SQLITE_OK) {
        return NULL;
    }

    /* We'll extract the temporary directory from tempName */
    foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
    if (foundSeparator) {
        /* We shorten the temp filename string to contain only
         * the directory name (including the trailing separator).
         * We know the byte after the foundSeparator position is
         * safe to use, in the shortest scenario it contains the
         * end-of-string byte.
         * By keeping the separator at the found position, it will
         * even work if tempDir consists of the separator, only.
         * (In this case the toplevel directory will be used for
         * access speed testing). */
        ++foundSeparator;
        *foundSeparator = 0;

        /* Now we copy the directory name for our caller */
        result = PORT_Strdup(tempName);
    }

    sqlite3_free(tempName);
    return result;
}

/*
 * Map SQL_LITE errors to PKCS #11 errors as best we can.
 */
static CK_RV
sdb_mapSQLError(sdbDataType type, int sqlerr)
{
    switch (sqlerr) {
        /* good matches */
        case SQLITE_OK:
        case SQLITE_DONE:
            return CKR_OK;
        case SQLITE_NOMEM:
            return CKR_HOST_MEMORY;
        case SQLITE_READONLY:
            return CKR_TOKEN_WRITE_PROTECTED;
        /* close matches */
        case SQLITE_AUTH:
        case SQLITE_PERM:
        /*return CKR_USER_NOT_LOGGED_IN; */
        case SQLITE_CANTOPEN:
        case SQLITE_NOTFOUND:
            /* NSS distiguishes between failure to open the cert and the key db */
            return type == SDB_CERT ? CKR_NSS_CERTDB_FAILED : CKR_NSS_KEYDB_FAILED;
        case SQLITE_IOERR:
            return CKR_DEVICE_ERROR;
        default:
            break;
    }
    return CKR_GENERAL_ERROR;
}

/*
 * build up database name from a directory, prefix, name, version and flags.
 */
static char *
sdb_BuildFileName(const char *directory,
                  const char *prefix, const char *type,
                  int version)
{
    char *dbname = NULL;
    /* build the full dbname */
    dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
                             (int)(unsigned char)PR_GetDirectorySeparator(),
                             prefix, type, version);
    return dbname;
}

/*
 * find out how expensive the access system call is for non-existant files
 * in the given directory.  Return the number of operations done in 33 ms.
 */
static PRUint32
sdb_measureAccess(const char *directory)
{
    PRUint32 i;
    PRIntervalTime time;
    PRIntervalTime delta;
    PRIntervalTime duration = PR_MillisecondsToInterval(33);
    const char *doesntExistName = "_dOeSnotExist_.db";
    char *temp, *tempStartOfFilename;
    size_t maxTempLen, maxFileNameLen, directoryLength, tmpdirLength = 0;
#ifdef SDB_MEASURE_USE_TEMP_DIR
    /*
     * on some OS's and Filesystems, creating a bunch of files and deleting
     * them messes up the systems's caching, but if we create the files in
     * a temp directory which we later delete, then the cache gets cleared
     * up. This code uses several OS dependent calls, and it's not clear
     * that temp directory use won't mess up other filesystems and OS caching,
     * so if you need this for your OS, you can turn on the
     * 'SDB_MEASURE_USE_TEMP_DIR' define in coreconf
     */
    const char template[] = "dbTemp.XXXXXX";
    tmpdirLength = sizeof(template);
#endif
    /* no directory, just return one */
    if (directory == NULL) {
        return 1;
    }

    /* our calculation assumes time is a 4 bytes == 32 bit integer */
    PORT_Assert(sizeof(time) == 4);

    directoryLength = strlen(directory);

    maxTempLen = directoryLength + 1       /* dirname + / */
                 + tmpdirLength            /* tmpdirname includes / */
                 + strlen(doesntExistName) /* filename base */
                 + 11                      /* max chars for 32 bit int plus potential sign */
                 + 1;                      /* zero terminator */

    temp = PORT_ZAlloc(maxTempLen);
    if (!temp) {
        return 1;
    }

    /* We'll copy directory into temp just once, then ensure it ends
     * with the directory separator. */

    strcpy(temp, directory);
    if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
        temp[directoryLength++] = PR_GetDirectorySeparator();
    }

#ifdef SDB_MEASURE_USE_TEMP_DIR
    /* add the template for a temporary subdir, and create it */
    strcat(temp, template);
    if (!mkdtemp(temp)) {
        PORT_Free(temp);
        return 1;
    }
    /* and terminate that tmp subdir with a / */
    strcat(temp, "/");
#endif

    /* Remember the position after the last separator, and calculate the
     * number of remaining bytes. */
    tempStartOfFilename = temp + directoryLength + tmpdirLength;
    maxFileNameLen = maxTempLen - directoryLength;

    /* measure number of Access operations that can be done in 33 milliseconds
     * (1/30'th of a second), or 10000 operations, which ever comes first.
     */
    time = PR_IntervalNow();
    for (i = 0; i < 10000u; i++) {
        PRIntervalTime next;

        /* We'll use the variable part first in the filename string, just in
         * case it's longer than assumed, so if anything gets cut off, it
         * will be cut off from the constant part.
         * This code assumes the directory name at the beginning of
         * temp remains unchanged during our loop. */
        PR_snprintf(tempStartOfFilename, maxFileNameLen,
                    ".%lu%s", (PRUint32)(time + i), doesntExistName);
        PR_Access(temp, PR_ACCESS_EXISTS);
        next = PR_IntervalNow();
        delta = next - time;
        if (delta >= duration)
            break;
    }

#ifdef SDB_MEASURE_USE_TEMP_DIR
    /* turn temp back into our tmpdir path by removing doesntExistName, and
     * remove the tmp dir */
    *tempStartOfFilename = '\0';
    (void)rmdir(temp);
#endif
    PORT_Free(temp);

    /* always return 1 or greater */
    return i ? i : 1u;
}

/*
 * some file sytems are very slow to run sqlite3 on, particularly if the
 * access count is pretty high. On these filesystems is faster to create
 * a temporary database on the local filesystem and access that. This
 * code uses a temporary table to create that cache. Temp tables are
 * automatically cleared when the database handle it was created on
 * Is freed.
 */
static const char DROP_CACHE_CMD[] = "DROP TABLE %s";
static const char CREATE_CACHE_CMD[] =
    "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s";
static const char CREATE_ISSUER_INDEX_CMD[] =
    "CREATE INDEX issuer ON %s (a81)";
static const char CREATE_SUBJECT_INDEX_CMD[] =
    "CREATE INDEX subject ON %s (a101)";
static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)";
static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)";

static CK_RV
sdb_buildCache(sqlite3 *sqlDB, sdbDataType type,
               const char *cacheTable, const char *table)
{
    char *newStr;
    int sqlerr = SQLITE_OK;

    newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table);
    if (newStr == NULL) {
        return CKR_HOST_MEMORY;
    }
    sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    if (sqlerr != SQLITE_OK) {
        return sdb_mapSQLError(type, sqlerr);
    }
    /* failure to create the indexes is not an issue */
    newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable);
    if (newStr == NULL) {
        return CKR_OK;
    }
    sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable);
    if (newStr == NULL) {
        return CKR_OK;
    }
    sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable);
    if (newStr == NULL) {
        return CKR_OK;
    }
    sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable);
    if (newStr == NULL) {
        return CKR_OK;
    }
    sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    return CKR_OK;
}

/*
 * update the cache and the data records describing it.
 *  The cache is updated by dropping the temp database and recreating it.
 */
static CK_RV
sdb_updateCache(SDBPrivate *sdb_p)
{
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    char *newStr;

    /* drop the old table */
    newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable);
    if (newStr == NULL) {
        return CKR_HOST_MEMORY;
    }
    sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL);
    sqlite3_free(newStr);
    if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR)) {
        /* something went wrong with the drop, don't try to refresh...
         * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In
         * that case, we just continue on and try to reload it */
        return sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    /* set up the new table */
    error = sdb_buildCache(sdb_p->sqlReadDB, sdb_p->type,
                           sdb_p->cacheTable, sdb_p->table);
    if (error == CKR_OK) {
        /* we have a new cache! */
        sdb_p->lastUpdateTime = PR_IntervalNow();
    }
    return error;
}

/*
 *  The sharing of sqlite3 handles across threads is tricky. Older versions
 *  couldn't at all, but newer ones can under strict conditions. Basically
 *  no 2 threads can use the same handle while another thread has an open
 *  stmt running. Once the sqlite3_stmt is finalized, another thread can then
 *  use the database handle.
 *
 *  We use monitors to protect against trying to use a database before
 *  it's sqlite3_stmt is finalized. This is preferable to the opening and
 *  closing the database each operation because there is significant overhead
 *  in the open and close. Also continually opening and closing the database
 *  defeats the cache code as the cache table is lost on close (thus
 *  requiring us to have to reinitialize the cache every operation).
 *
 *  An execption to the shared handle is transations. All writes happen
 *  through a transaction. When we are in  a transaction, we must use the
 *  same database pointer for that entire transation. In this case we save
 *  the transaction database and use it for all accesses on the transaction
 *  thread. Other threads use the common database.
 *
 *  There can only be once active transaction on the database at a time.
 *
 *  sdb_openDBLocal() provides us with a valid database handle for whatever
 *  state we are in (reading or in a transaction), and acquires any locks
 *  appropriate to that state. It also decides when it's time to refresh
 *  the cache before we start an operation. Any database handle returned
 *  just eventually be closed with sdb_closeDBLocal().
 *
 *  The table returned either points to the database's physical table, or
 *  to the cached shadow. Tranactions always return the physical table
 *  and read operations return either the physical table or the cache
 *  depending on whether or not the cache exists.
 */
static CK_RV
sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
{
    *sqlDB = NULL;

    PR_EnterMonitor(sdb_p->dbMon);

    if (table) {
        *table = sdb_p->table;
    }

    /* We're in a transaction, use the transaction DB */
    if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) {
        *sqlDB = sdb_p->sqlXactDB;
        /* only one thread can get here, safe to unlock */
        PR_ExitMonitor(sdb_p->dbMon);
        return CKR_OK;
    }

    /*
     * if we are just reading from the table, we may have the table
     * cached in a temporary table (especially if it's on a shared FS).
     * In that case we want to see updates to the table, the the granularity
     * is on order of human scale, not computer scale.
     */
    if (table && sdb_p->cacheTable) {
        PRIntervalTime now = PR_IntervalNow();
        if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) {
            sdb_updateCache(sdb_p);
        }
        *table = sdb_p->cacheTable;
    }

    *sqlDB = sdb_p->sqlReadDB;

    /* leave holding the lock. only one thread can actually use a given
     * database connection at once */

    return CKR_OK;
}

/* closing the local database currenly means unlocking the monitor */
static CK_RV
sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB)
{
    if (sdb_p->sqlXactDB != sqlDB) {
        /* if we weren't in a transaction, we got a lock */
        PR_ExitMonitor(sdb_p->dbMon);
    }
    return CKR_OK;
}

/*
 * wrapper to sqlite3_open which also sets the busy_timeout
 */
static int
sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
{
    int sqlerr;
    int openFlags;

    *sqlDB = NULL;

    if (flags & SDB_RDONLY) {
        openFlags = SQLITE_OPEN_READONLY;
    } else {
        openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
        /* sqlite 3.34 seem to incorrectly open readwrite.
        * when the file is readonly. Explicitly reject that issue here */
        if ((_NSSUTIL_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) && (_NSSUTIL_Access(name, PR_ACCESS_WRITE_OK) != PR_SUCCESS)) {
            return SQLITE_READONLY;
        }
    }

    /* Requires SQLite 3.5.0 or newer. */
    sqlerr = sqlite3_open_v2(name, sqlDB, openFlags, NULL);
    if (sqlerr != SQLITE_OK) {
        return sqlerr;
    }

    sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT);
    if (sqlerr != SQLITE_OK) {
        sqlite3_close(*sqlDB);
        *sqlDB = NULL;
        return sqlerr;
    }
    return SQLITE_OK;
}

/* Sigh, if we created a new table since we opened the database,
 * the database handle will not see the new table, we need to close this
 * database and reopen it. Caller must be in a transaction or holding
 * the dbMon. sqlDB is changed on success. */
static int
sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB)
{
    sqlite3 *newDB;
    int sqlerr;

    /* open a new database */
    sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY);
    if (sqlerr != SQLITE_OK) {
        return sqlerr;
    }

    /* if we are in a transaction, we may not be holding the monitor.
     * grab it before we update the transaction database. This is
     * safe since are using monitors. */
    PR_EnterMonitor(sdb_p->dbMon);
    /* update our view of the database */
    if (sdb_p->sqlReadDB == *sqlDB) {
        sdb_p->sqlReadDB = newDB;
    } else if (sdb_p->sqlXactDB == *sqlDB) {
        sdb_p->sqlXactDB = newDB;
    }
    PR_ExitMonitor(sdb_p->dbMon);

    /* close the old one */
    sqlite3_close(*sqlDB);

    *sqlDB = newDB;
    return SQLITE_OK;
}

struct SDBFindStr {
    sqlite3 *sqlDB;
    sqlite3_stmt *findstmt;
};

static const char FIND_OBJECTS_CMD[] = "SELECT ALL id FROM %s WHERE %s;";
static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL id FROM %s;";
CK_RV
sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count,
                    SDBFind **find)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    const char *table;
    char *newStr, *findStr = NULL;
    sqlite3_stmt *findstmt = NULL;
    char *join = "";
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    unsigned int i;

    LOCK_SQLITE()
    *find = NULL;
    error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
    if (error != CKR_OK) {
        goto loser;
    }

    findStr = sqlite3_mprintf("");
    for (i = 0; findStr && i < count; i++) {
        newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join,
                                 template[i].type, i);
        join = " AND ";
        sqlite3_free(findStr);
        findStr = newStr;
    }

    if (findStr == NULL) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }

    if (count == 0) {
        newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
    } else {
        newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
    }
    sqlite3_free(findStr);
    if (newStr == NULL) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }
    sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL);
    sqlite3_free(newStr);
    for (i = 0; sqlerr == SQLITE_OK && i < count; i++) {
        const void *blobData = template[i].pValue;
        unsigned int blobSize = template[i].ulValueLen;
        if (blobSize == 0) {
            blobSize = SQLITE_EXPLICIT_NULL_LEN;
            blobData = SQLITE_EXPLICIT_NULL;
        }
        sqlerr = sqlite3_bind_blob(findstmt, i + 1, blobData, blobSize,
                                   SQLITE_TRANSIENT);
    }
    if (sqlerr == SQLITE_OK) {
        *find = PORT_New(SDBFind);
        if (*find == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        (*find)->findstmt = findstmt;
        (*find)->sqlDB = sqlDB;
        UNLOCK_SQLITE()
        return CKR_OK;
    }
    error = sdb_mapSQLError(sdb_p->type, sqlerr);

loser:
    if (findstmt) {
        sqlite3_reset(findstmt);
        sqlite3_finalize(findstmt);
    }
    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    UNLOCK_SQLITE()
    return error;
}

CK_RV
sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object,
                CK_ULONG arraySize, CK_ULONG *count)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3_stmt *stmt = sdbFind->findstmt;
    int sqlerr = SQLITE_OK;
    int retry = 0;

    *count = 0;

    if (arraySize == 0) {
        return CKR_OK;
    }
    LOCK_SQLITE()

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
        if (sqlerr == SQLITE_ROW) {
            /* only care about the id */
            *object++ = sqlite3_column_int(stmt, 0);
            arraySize--;
            (*count)++;
        }
    } while (!sdb_done(sqlerr, &retry) && (arraySize > 0));

    /* we only have some of the objects, there is probably more,
     * set the sqlerr to an OK value so we return CKR_OK */
    if (sqlerr == SQLITE_ROW && arraySize == 0) {
        sqlerr = SQLITE_DONE;
    }
    UNLOCK_SQLITE()

    return sdb_mapSQLError(sdb_p->type, sqlerr);
}

CK_RV
sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3_stmt *stmt = sdbFind->findstmt;
    sqlite3 *sqlDB = sdbFind->sqlDB;
    int sqlerr = SQLITE_OK;

    LOCK_SQLITE()
    if (stmt) {
        sqlite3_reset(stmt);
        sqlerr = sqlite3_finalize(stmt);
    }
    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    PORT_Free(sdbFind);

    UNLOCK_SQLITE()
    return sdb_mapSQLError(sdb_p->type, sqlerr);
}

static CK_RV
sdb_GetValidAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
                                 CK_ATTRIBUTE *template, CK_ULONG count)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    const char *table = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int found = 0;
    int retry = 0;
    unsigned int i;

    if (count == 0) {
        error = CKR_OBJECT_HANDLE_INVALID;
        goto loser;
    }

    /* open a new db if necessary */
    error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
    if (error != CKR_OK) {
        goto loser;
    }

    char *columns = NULL;
    for (i = 0; i < count; i++) {
        char *newColumns;
        if (columns) {
            newColumns = sqlite3_mprintf("%s, a%x", columns, template[i].type);
            sqlite3_free(columns);
            columns = NULL;
        } else {
            newColumns = sqlite3_mprintf("a%x", template[i].type);
        }
        if (!newColumns) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        columns = newColumns;
    }

    PORT_Assert(columns);

    char *statement = sqlite3_mprintf("SELECT DISTINCT %s FROM %s where id=$ID LIMIT 1;",
                                      columns, table);
    sqlite3_free(columns);
    columns = NULL;
    if (!statement) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }

    sqlerr = sqlite3_prepare_v2(sqlDB, statement, -1, &stmt, NULL);
    sqlite3_free(statement);
    statement = NULL;
    if (sqlerr != SQLITE_OK) {
        goto loser;
    }

    // NB: indices in sqlite3_bind_int are 1-indexed
    sqlerr = sqlite3_bind_int(stmt, 1, object_id);
    if (sqlerr != SQLITE_OK) {
        goto loser;
    }

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
        if (sqlerr == SQLITE_ROW) {
            PORT_Assert(!found);
            for (i = 0; i < count; i++) {
                unsigned int blobSize;
                const char *blobData;

                // NB: indices in sqlite_column_{bytes,blob} are 0-indexed
                blobSize = sqlite3_column_bytes(stmt, i);
                blobData = sqlite3_column_blob(stmt, i);
                if (blobData == NULL) {
                    /* PKCS 11 requires that get attributes process all the
                     * attributes in the template, marking the attributes with
                     * issues with -1. Mark the error but continue */
                    template[i].ulValueLen = -1;
                    error = CKR_ATTRIBUTE_TYPE_INVALID;
                    continue;
                }
                /* If the blob equals our explicit NULL value, then the
                 * attribute is a NULL. */
                if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) &&
                    (PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL,
                                 SQLITE_EXPLICIT_NULL_LEN) == 0)) {
                    blobSize = 0;
                }
                if (template[i].pValue) {
                    if (template[i].ulValueLen < blobSize) {
                        /* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */
                        template[i].ulValueLen = -1;
                        error = CKR_BUFFER_TOO_SMALL;
                        continue;
                    }
                    PORT_Memcpy(template[i].pValue, blobData, blobSize);
                }
                template[i].ulValueLen = blobSize;
            }
            found = 1;
        }
    } while (!sdb_done(sqlerr, &retry));

    sqlite3_reset(stmt);
    sqlite3_finalize(stmt);
    stmt = NULL;

loser:
    /* fix up the error if necessary */
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
        if (!found && error == CKR_OK) {
            error = CKR_OBJECT_HANDLE_INVALID;
        }
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    /* if we had to open a new database, free it now */
    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    return error;
}

/* NOTE: requires sdb_p->schemaAttrs to be sorted asc. */
inline static PRBool
sdb_attributeExists(SDB *sdb, CK_ATTRIBUTE_TYPE attr)
{
    SDBPrivate *sdb_p = sdb->private;
    int first = 0;
    int last = (int)sdb_p->numSchemaAttrs - 1;
    while (last >= first) {
        int mid = first + (last - first) / 2;
        if (sdb_p->schemaAttrs[mid] == attr) {
            return PR_TRUE;
        }
        if (attr > sdb_p->schemaAttrs[mid]) {
            first = mid + 1;
        } else {
            last = mid - 1;
        }
    }

    return PR_FALSE;
}

CK_RV
sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
                      CK_ATTRIBUTE *template, CK_ULONG count)
{
    CK_RV crv = CKR_OK;
    unsigned int tmplIdx;
    unsigned int resIdx = 0;
    unsigned int validCount = 0;
    unsigned int i;

    if (count == 0) {
        return crv;
    }

    CK_ATTRIBUTE *validTemplate;
    PRBool invalidExists = PR_FALSE;
    for (tmplIdx = 0; tmplIdx < count; tmplIdx++) {
        if (!sdb_attributeExists(sdb, template[tmplIdx].type)) {
            template[tmplIdx].ulValueLen = -1;
            crv = CKR_ATTRIBUTE_TYPE_INVALID;
            invalidExists = PR_TRUE;
            break;
        }
    }

    if (!invalidExists) {
        validTemplate = template;
        validCount = count;
    } else {
        /* Create a new template containing only the valid subset of
         * input |template|, and query with that. */
        validCount = tmplIdx;
        validTemplate = malloc(sizeof(CK_ATTRIBUTE) * count);
        if (!validTemplate) {
            return CKR_HOST_MEMORY;
        }
        /* Copy in what we already know is valid. */
        for (i = 0; i < validCount; i++) {
            validTemplate[i] = template[i];
        }

        /* tmplIdx was left at the index of the first invalid
         * attribute, which has been handled. We only need to
         * deal with the remainder. */
        tmplIdx++;
        for (; tmplIdx < count; tmplIdx++) {
            if (sdb_attributeExists(sdb, template[tmplIdx].type)) {
                validTemplate[validCount++] = template[tmplIdx];
            } else {
                template[tmplIdx].ulValueLen = -1;
            }
        }
    }

    if (validCount) {
        LOCK_SQLITE()
        CK_RV crv2 = sdb_GetValidAttributeValueNoLock(sdb, object_id, validTemplate, validCount);
        UNLOCK_SQLITE()

        /* If an invalid attribute was removed above, let
         * the caller know. Any other error from the actual
         * query should propogate. */
        crv = (crv2 == CKR_OK) ? crv : crv2;
    }

    if (invalidExists) {
        /* Copy out valid lengths. */
        tmplIdx = 0;
        for (resIdx = 0; resIdx < validCount; resIdx++) {
            for (; tmplIdx < count; tmplIdx++) {
                if (template[tmplIdx].type != validTemplate[resIdx].type) {
                    continue;
                }
                template[tmplIdx].ulValueLen = validTemplate[resIdx].ulValueLen;
                tmplIdx++;
                break;
            }
        }
        free(validTemplate);
    }

    return crv;
}

static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;";
CK_RV
sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
                      const CK_ATTRIBUTE *template, CK_ULONG count)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    char *setStr = NULL;
    char *newStr = NULL;
    int sqlerr = SQLITE_OK;
    int retry = 0;
    CK_RV error = CKR_OK;
    unsigned int i;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    if (count == 0) {
        return CKR_OK;
    }

    LOCK_SQLITE()
    setStr = sqlite3_mprintf("");
    for (i = 0; setStr && i < count; i++) {
        if (i == 0) {
            sqlite3_free(setStr);
            setStr = sqlite3_mprintf("a%x=$VALUE%d",
                                     template[i].type, i);
            continue;
        }
        newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr,
                                 template[i].type, i);
        sqlite3_free(setStr);
        setStr = newStr;
    }
    newStr = NULL;

    if (setStr == NULL) {
        return CKR_HOST_MEMORY;
    }
    newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
    sqlite3_free(setStr);
    if (newStr == NULL) {
        UNLOCK_SQLITE()
        return CKR_HOST_MEMORY;
    }
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }
    sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
    if (sqlerr != SQLITE_OK)
        goto loser;
    for (i = 0; i < count; i++) {
        if (template[i].ulValueLen != 0) {
            sqlerr = sqlite3_bind_blob(stmt, i + 1, template[i].pValue,
                                       template[i].ulValueLen, SQLITE_STATIC);
        } else {
            sqlerr = sqlite3_bind_blob(stmt, i + 1, SQLITE_EXPLICIT_NULL,
                                       SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
        }
        if (sqlerr != SQLITE_OK)
            goto loser;
    }
    sqlerr = sqlite3_bind_int(stmt, i + 1, object_id);
    if (sqlerr != SQLITE_OK)
        goto loser;

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
    } while (!sdb_done(sqlerr, &retry));

loser:
    if (newStr) {
        sqlite3_free(newStr);
    }
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }

    UNLOCK_SQLITE()
    return error;
}

/*
 * check to see if a candidate object handle already exists.
 */
static PRBool
sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate)
{
    CK_RV crv;
    CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 };

    crv = sdb_GetValidAttributeValueNoLock(sdb, candidate, &template, 1);
    if (crv == CKR_OBJECT_HANDLE_INVALID) {
        return PR_FALSE;
    }
    return PR_TRUE;
}

/*
 * if we're here, we are in a transaction, so it's safe
 * to examine the current state of the database
 */
static CK_OBJECT_HANDLE
sdb_getObjectId(SDB *sdb)
{
    CK_OBJECT_HANDLE candidate;
    static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE;
    int count;
    /*
     * get an initial object handle to use
     */
    if (next_obj == CK_INVALID_HANDLE) {
        PRTime time;
        time = PR_Now();

        next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
    }
    candidate = next_obj++;
    /* detect that we've looped through all the handles... */
    for (count = 0; count < 0x40000000; count++, candidate = next_obj++) {
        /* mask off excess bits */
        candidate &= 0x3fffffff;
        /* if we hit zero, go to the next entry */
        if (candidate == CK_INVALID_HANDLE) {
            continue;
        }
        /* make sure we aren't already using */
        if (!sdb_objectExists(sdb, candidate)) {
            /* this one is free */
            return candidate;
        }
    }

    /* no handle is free, fail */
    return CK_INVALID_HANDLE;
}

CK_RV
sdb_GetNewObjectID(SDB *sdb, CK_OBJECT_HANDLE *object)
{
    CK_OBJECT_HANDLE id;

    id = sdb_getObjectId(sdb);
    if (id == CK_INVALID_HANDLE) {
        return CKR_DEVICE_MEMORY; /* basically we ran out of resources */
    }
    *object = id;
    return CKR_OK;
}

static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);";
CK_RV
sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id,
                 const CK_ATTRIBUTE *template, CK_ULONG count)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    char *columnStr = NULL;
    char *valueStr = NULL;
    char *newStr = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE;
    int retry = 0;
    unsigned int i;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    LOCK_SQLITE()
    if ((*object_id != CK_INVALID_HANDLE) &&
        !sdb_objectExists(sdb, *object_id)) {
        this_object = *object_id;
    } else {
        this_object = sdb_getObjectId(sdb);
    }
    if (this_object == CK_INVALID_HANDLE) {
        UNLOCK_SQLITE();
        return CKR_HOST_MEMORY;
    }
    columnStr = sqlite3_mprintf("");
    valueStr = sqlite3_mprintf("");
    *object_id = this_object;
    for (i = 0; columnStr && valueStr && i < count; i++) {
        newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type);
        sqlite3_free(columnStr);
        columnStr = newStr;
        newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i);
        sqlite3_free(valueStr);
        valueStr = newStr;
    }
    newStr = NULL;
    if ((columnStr == NULL) || (valueStr == NULL)) {
        if (columnStr) {
            sqlite3_free(columnStr);
        }
        if (valueStr) {
            sqlite3_free(valueStr);
        }
        UNLOCK_SQLITE()
        return CKR_HOST_MEMORY;
    }
    newStr = sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr);
    sqlite3_free(columnStr);
    sqlite3_free(valueStr);
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }
    sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
    if (sqlerr != SQLITE_OK)
        goto loser;
    sqlerr = sqlite3_bind_int(stmt, 1, *object_id);
    if (sqlerr != SQLITE_OK)
        goto loser;
    for (i = 0; i < count; i++) {
        if (template[i].ulValueLen) {
            sqlerr = sqlite3_bind_blob(stmt, i + 2, template[i].pValue,
                                       template[i].ulValueLen, SQLITE_STATIC);
        } else {
            sqlerr = sqlite3_bind_blob(stmt, i + 2, SQLITE_EXPLICIT_NULL,
                                       SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
        }
        if (sqlerr != SQLITE_OK)
            goto loser;
    }

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
    } while (!sdb_done(sqlerr, &retry));

loser:
    if (newStr) {
        sqlite3_free(newStr);
    }
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    UNLOCK_SQLITE()

    return error;
}

/*
 *  Generic destroy that can destroy metadata or objects
 */
static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);";
CK_RV
sdb_destroyAnyObject(SDB *sdb, const char *table,
                     CK_OBJECT_HANDLE object_id, const char *string_id)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    char *newStr = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int retry = 0;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    LOCK_SQLITE()
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }
    newStr = sqlite3_mprintf(DESTROY_CMD, table);
    if (newStr == NULL) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }
    sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
    sqlite3_free(newStr);
    if (sqlerr != SQLITE_OK)
        goto loser;
    if (string_id == NULL) {
        sqlerr = sqlite3_bind_int(stmt, 1, object_id);
    } else {
        sqlerr = sqlite3_bind_text(stmt, 1, string_id,
                                   PORT_Strlen(string_id), SQLITE_STATIC);
    }
    if (sqlerr != SQLITE_OK)
        goto loser;

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
    } while (!sdb_done(sqlerr, &retry));

loser:
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }

    UNLOCK_SQLITE()
    return error;
}

CK_RV
sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
{
    SDBPrivate *sdb_p = sdb->private;
    return sdb_destroyAnyObject(sdb, sdb_p->table, object_id, NULL);
}

CK_RV
sdb_DestroyMetaData(SDB *sdb, const char *id)
{
    return sdb_destroyAnyObject(sdb, "metaData", 0, id);
}

static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";

/*
 * start a transaction.
 *
 * We need to open a new database, then store that new database into
 * the private data structure. We open the database first, then use locks
 * to protect storing the data to prevent deadlocks.
 */
CK_RV
sdb_Begin(SDB *sdb)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int retry = 0;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    LOCK_SQLITE()

    /* get a new version that we will use for the entire transaction */
    sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR);
    if (sqlerr != SQLITE_OK) {
        goto loser;
    }

    sqlerr = sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
        /* don't retry BEGIN transaction*/
        retry = 0;
    } while (!sdb_done(sqlerr, &retry));

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

loser:
    error = sdb_mapSQLError(sdb_p->type, sqlerr);

    /* we are starting a new transaction,
     * and if we succeeded, then save this database for the rest of
     * our transaction */
    if (error == CKR_OK) {
        /* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point
         * sdb_p->sqlXactDB MUST be null */
        PR_EnterMonitor(sdb_p->dbMon);
        PORT_Assert(sdb_p->sqlXactDB == NULL);
        sdb_p->sqlXactDB = sqlDB;
        sdb_p->sqlXactThread = PR_GetCurrentThread();
        PR_ExitMonitor(sdb_p->dbMon);
    } else {
        /* we failed to start our transaction,
         * free any databases we opened. */
        if (sqlDB) {
            sqlite3_close(sqlDB);
        }
    }

    UNLOCK_SQLITE()
    return error;
}

/*
 * Complete a transaction. Basically undo everything we did in begin.
 * There are 2 flavors Abort and Commit. Basically the only differerence between
 * these 2 are what the database will show. (no change in to former, change in
 * the latter).
 */
static CK_RV
sdb_complete(SDB *sdb, const char *cmd)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    sqlite3_stmt *stmt = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int retry = 0;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    /* We must have a transation database, or we shouldn't have arrived here */
    PR_EnterMonitor(sdb_p->dbMon);
    PORT_Assert(sdb_p->sqlXactDB);
    if (sdb_p->sqlXactDB == NULL) {
        PR_ExitMonitor(sdb_p->dbMon);
        return CKR_GENERAL_ERROR; /* shouldn't happen */
    }
    PORT_Assert(sdb_p->sqlXactThread == PR_GetCurrentThread());
    if (sdb_p->sqlXactThread != PR_GetCurrentThread()) {
        PR_ExitMonitor(sdb_p->dbMon);
        return CKR_GENERAL_ERROR; /* shouldn't happen */
    }
    sqlDB = sdb_p->sqlXactDB;
    sdb_p->sqlXactDB = NULL; /* no one else can get to this DB,
                              * safe to unlock */
    sdb_p->sqlXactThread = NULL;
    PR_ExitMonitor(sdb_p->dbMon);

    sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
    } while (!sdb_done(sqlerr, &retry));

    /* Pending BEGIN TRANSACTIONS Can move forward at this point. */

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    /* we we have a cached DB image, update it as well */
    if (sdb_p->cacheTable) {
        PR_EnterMonitor(sdb_p->dbMon);
        sdb_updateCache(sdb_p);
        PR_ExitMonitor(sdb_p->dbMon);
    }

    error = sdb_mapSQLError(sdb_p->type, sqlerr);

    /* We just finished a transaction.
     * Free the database, and remove it from the list */
    sqlite3_close(sqlDB);

    return error;
}

static const char COMMIT_CMD[] = "COMMIT TRANSACTION;";
CK_RV
sdb_Commit(SDB *sdb)
{
    CK_RV crv;
    LOCK_SQLITE()
    crv = sdb_complete(sdb, COMMIT_CMD);
    UNLOCK_SQLITE()
    return crv;
}

static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;";
CK_RV
sdb_Abort(SDB *sdb)
{
    CK_RV crv;
    LOCK_SQLITE()
    crv = sdb_complete(sdb, ROLLBACK_CMD);
    UNLOCK_SQLITE()
    return crv;
}

static int tableExists(sqlite3 *sqlDB, const char *tableName);

static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;";
CK_RV
sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = sdb_p->sqlXactDB;
    sqlite3_stmt *stmt = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int found = 0;
    int retry = 0;

    LOCK_SQLITE()
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }

    /* handle 'test' versions of the sqlite db */
    sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
    /* Sigh, if we created a new table since we opened the database,
     * the database handle will not see the new table, we need to close this
     * database and reopen it. This is safe because we are holding the lock
     * still. */
    if (sqlerr == SQLITE_SCHEMA) {
        sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB);
        if (sqlerr != SQLITE_OK) {
            goto loser;
        }
        sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
    }
    if (sqlerr != SQLITE_OK)
        goto loser;
    sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
        if (sqlerr == SQLITE_ROW) {
            const char *blobData;
            unsigned int len = item1->len;
            item1->len = sqlite3_column_bytes(stmt, 1);
            if (item1->len > len) {
                error = CKR_BUFFER_TOO_SMALL;
                continue;
            }
            blobData = sqlite3_column_blob(stmt, 1);
            PORT_Memcpy(item1->data, blobData, item1->len);
            if (item2) {
                len = item2->len;
                item2->len = sqlite3_column_bytes(stmt, 2);
                if (item2->len > len) {
                    error = CKR_BUFFER_TOO_SMALL;
                    continue;
                }
                blobData = sqlite3_column_blob(stmt, 2);
                PORT_Memcpy(item2->data, blobData, item2->len);
            }
            found = 1;
        }
    } while (!sdb_done(sqlerr, &retry));

loser:
    /* fix up the error if necessary */
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
        if (!found && error == CKR_OK) {
            error = CKR_OBJECT_HANDLE_INVALID;
        }
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    UNLOCK_SQLITE()

    return error;
}

static const char PW_CREATE_TABLE_CMD[] =
    "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);";
static const char PW_CREATE_CMD[] =
    "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);";
static const char MD_CREATE_CMD[] =
    "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);";

CK_RV
sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1,
                const SECItem *item2)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = sdb_p->sqlXactDB;
    sqlite3_stmt *stmt = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    int retry = 0;
    const char *cmd = PW_CREATE_CMD;

    if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    LOCK_SQLITE()
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }

    if (!tableExists(sqlDB, "metaData")) {
        sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
        if (sqlerr != SQLITE_OK)
            goto loser;
    }
    if (item2 == NULL) {
        cmd = MD_CREATE_CMD;
    }
    sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
    if (sqlerr != SQLITE_OK)
        goto loser;
    sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
    if (sqlerr != SQLITE_OK)
        goto loser;
    sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC);
    if (sqlerr != SQLITE_OK)
        goto loser;
    if (item2) {
        sqlerr = sqlite3_bind_blob(stmt, 3, item2->data,
                                   item2->len, SQLITE_STATIC);
        if (sqlerr != SQLITE_OK)
            goto loser;
    }

    do {
        sqlerr = sqlite3_step(stmt);
        if (sqlerr == SQLITE_BUSY) {
            PR_Sleep(SDB_BUSY_RETRY_TIME);
        }
    } while (!sdb_done(sqlerr, &retry));

loser:
    /* fix up the error if necessary */
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    if (stmt) {
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }
    UNLOCK_SQLITE()

    return error;
}

static const char RESET_CMD[] = "DELETE FROM %s;";
CK_RV
sdb_Reset(SDB *sdb)
{
    SDBPrivate *sdb_p = sdb->private;
    sqlite3 *sqlDB = NULL;
    char *newStr;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;

    /* only Key databases can be reset */
    if (sdb_p->type != SDB_KEY) {
        return CKR_OBJECT_HANDLE_INVALID;
    }

    LOCK_SQLITE()
    error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
    if (error != CKR_OK) {
        goto loser;
    }

    if (tableExists(sqlDB, sdb_p->table)) {
        /* delete the contents of the key table */
        newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);

        if (sqlerr != SQLITE_OK)
            goto loser;
    }

    /* delete the password entry table */
    sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;",
                          NULL, 0, NULL);

loser:
    /* fix up the error if necessary */
    if (error == CKR_OK) {
        error = sdb_mapSQLError(sdb_p->type, sqlerr);
    }

    if (sqlDB) {
        sdb_closeDBLocal(sdb_p, sqlDB);
    }

    UNLOCK_SQLITE()
    return error;
}

CK_RV
sdb_Close(SDB *sdb)
{
    SDBPrivate *sdb_p = sdb->private;
    int sqlerr = SQLITE_OK;
    sdbDataType type = sdb_p->type;

    sqlerr = sqlite3_close(sdb_p->sqlReadDB);
    PORT_Free(sdb_p->sqlDBName);
    if (sdb_p->cacheTable) {
        sqlite3_free(sdb_p->cacheTable);
    }
    if (sdb_p->dbMon) {
        PR_DestroyMonitor(sdb_p->dbMon);
    }
    free(sdb_p->schemaAttrs);
    free(sdb_p);
    free(sdb);
    return sdb_mapSQLError(type, sqlerr);
}

/*
 * functions to support open
 */

static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;";

/* return 1 if sqlDB contains table 'tableName */
static int
tableExists(sqlite3 *sqlDB, const char *tableName)
{
    char *cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
    int sqlerr = SQLITE_OK;

    if (cmd == NULL) {
        return 0;
    }

    sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
    sqlite3_free(cmd);

    return (sqlerr == SQLITE_OK) ? 1 : 0;
}

void
sdb_SetForkState(PRBool forked)
{
    /* XXXright now this is a no-op. The global fork state in the softokn3
     * shared library is already taken care of at the PKCS#11 level.
     * If and when we add fork state to the sqlite shared library and extern
     * interface, we will need to set it and reset it from here */
}

static int
sdb_attributeComparator(const void *a, const void *b)
{
    if (*(CK_ATTRIBUTE_TYPE *)a < *(CK_ATTRIBUTE_TYPE *)b) {
        return -1;
    }
    if (*(CK_ATTRIBUTE_TYPE *)a > *(CK_ATTRIBUTE_TYPE *)b) {
        return 1;
    }
    return 0;
}

/*
 * initialize a single database
 */
static const char INIT_CMD[] =
    "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";

CK_RV
sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
         int *newInit, int inFlags, PRUint32 accessOps, SDB **pSdb)
{
    int i;
    char *initStr = NULL;
    char *newStr;
    char *queryStr = NULL;
    int inTransaction = 0;
    SDB *sdb = NULL;
    SDBPrivate *sdb_p = NULL;
    sqlite3 *sqlDB = NULL;
    int sqlerr = SQLITE_OK;
    CK_RV error = CKR_OK;
    char *cacheTable = NULL;
    PRIntervalTime now = 0;
    char *env;
    PRBool enableCache = PR_FALSE;
    PRBool checkFSType = PR_FALSE;
    PRBool measureSpeed = PR_FALSE;
    PRBool create;
    int flags = inFlags & 0x7;

    *pSdb = NULL;
    *inUpdate = 0;

    /* sqlite3 doesn't have a flag to specify that we want to
     * open the database read only. If the db doesn't exist,
     * sqlite3 will always create it.
     */
    LOCK_SQLITE();
    create = (_NSSUTIL_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS);
    if ((flags == SDB_RDONLY) && create) {
        error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
        goto loser;
    }
    sqlerr = sdb_openDB(dbname, &sqlDB, flags);
    if (sqlerr != SQLITE_OK) {
        error = sdb_mapSQLError(type, sqlerr);
        goto loser;
    }

    /*
     * SQL created the file, but it doesn't set appropriate modes for
     * a database.
     *
     * NO NSPR call for chmod? :(
     */
    if (create && sdb_chmod(dbname, 0600) != 0) {
        error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
        goto loser;
    }

    if (flags != SDB_RDONLY) {
        sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }
        inTransaction = 1;
    }
    if (!tableExists(sqlDB, table)) {
        *newInit = 1;
        if (flags != SDB_CREATE) {
            error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
            goto loser;
        }
        initStr = sqlite3_mprintf("");
        for (i = 0; initStr && i < known_attributes_size; i++) {
            newStr = sqlite3_mprintf("%s, a%x", initStr, known_attributes[i]);
            sqlite3_free(initStr);
            initStr = newStr;
        }
        if (initStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }

        newStr = sqlite3_mprintf(INIT_CMD, table, initStr);
        sqlite3_free(initStr);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }

        newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }

        newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }

        newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }

        newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table);
        if (newStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
        sqlite3_free(newStr);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(type, sqlerr);
            goto loser;
        }
    }
    /*
     * detect the case where we have created the database, but have
     * not yet updated it.
     *
     * We only check the Key database because only the key database has
     * a metaData table. The metaData table is created when a password
     * is set, or in the case of update, when a password is supplied.
     * If no key database exists, then the update would have happened immediately
     * on noticing that the cert database didn't exist (see newInit set above).
     */
    if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
        *newInit = 1;
    }

    /* access to network filesystems are significantly slower than local ones
     * for database operations. In those cases we need to create a cached copy
     * of the database in a temporary location on the local disk. SQLITE
     * already provides a way to create a temporary table and initialize it,
     * so we use it for the cache (see sdb_buildCache for how it's done).*/

    /*
     * we decide whether or not to use the cache based on the following input.
     *
     * NSS_SDB_USE_CACHE environment variable is set to anything other than
     *   "yes" or "no" (for instance, "auto"): NSS will measure the performance
     *   of access to the temp database versus the access to the user's
     *   passed-in database location. If the temp database location is
     *   "significantly" faster we will use the cache.
     *
     * NSS_SDB_USE_CACHE environment variable is nonexistent or set to "no":
     *   cache will not be used.
     *
     * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will
     *   always be used.
     *
     * It is expected that most applications will not need this feature, and
     * thus it is disabled by default.
     */

    env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");

    /* Variables enableCache, checkFSType, measureSpeed are PR_FALSE by default,
     * which is the expected behavior for NSS_SDB_USE_CACHE="no".
     * We don't need to check for "no" here. */
    if (!env) {
        /* By default, with no variable set, we avoid expensive measuring for
         * most FS types. We start with inexpensive FS type checking, and
         * might perform measuring for some types. */
        checkFSType = PR_TRUE;
    } else if (PORT_Strcasecmp(env, "yes") == 0) {
        enableCache = PR_TRUE;
    } else if (PORT_Strcasecmp(env, "no") != 0) { /* not "no" => "auto" */
        measureSpeed = PR_TRUE;
    }

    if (checkFSType) {
#if defined(LINUX) && !defined(ANDROID)
        struct statfs statfs_s;
        if (statfs(dbname, &statfs_s) == 0) {
            switch (statfs_s.f_type) {
                case SMB_SUPER_MAGIC:
                case 0xff534d42: /* CIFS_MAGIC_NUMBER */
                case NFS_SUPER_MAGIC:
                    /* We assume these are slow. */
                    enableCache = PR_TRUE;
                    break;
                case CODA_SUPER_MAGIC:
                case 0x65735546: /* FUSE_SUPER_MAGIC */
                case NCP_SUPER_MAGIC:
                    /* It's uncertain if this FS is fast or slow.
                     * It seems reasonable to perform slow measuring for users
                     * with questionable FS speed. */
                    measureSpeed = PR_TRUE;
                    break;
                case AFS_SUPER_MAGIC: /* Already implements caching. */
                default:
                    break;
            }
        }
#endif
    }

    if (measureSpeed) {
        char *tempDir = NULL;
        PRUint32 tempOps = 0;
        /*
         *  Use PR_Access to determine how expensive it
         * is to check for the existance of a local file compared to the same
         * check in the temp directory. If the temp directory is faster, cache
         * the database there. */
        tempDir = sdb_getTempDir(sqlDB);
        if (tempDir) {
            tempOps = sdb_measureAccess(tempDir);
            PORT_Free(tempDir);

            /* There is a cost to continually copying the database.
             * Account for that cost  with the arbitrary factor of 10 */
            enableCache = (PRBool)(tempOps > accessOps * 10);
        }
    }

    if (enableCache) {
        /* try to set the temp store to memory.*/
        sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL);
        /* Failure to set the temp store to memory is not fatal,
         * ignore the error */

        cacheTable = sqlite3_mprintf("%sCache", table);
        if (cacheTable == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        /* build the cache table */
        error = sdb_buildCache(sqlDB, type, cacheTable, table);
        if (error != CKR_OK) {
            goto loser;
        }
        /* initialize the last cache build time */
        now = PR_IntervalNow();
    }

    sdb = (SDB *)malloc(sizeof(SDB));
    if (!sdb) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }
    sdb_p = (SDBPrivate *)malloc(sizeof(SDBPrivate));
    if (!sdb_p) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }

    /* Cache the attributes that are held in the table, so we can later check
     * that queried attributes actually exist. We don't assume the schema
     * to be exactly |known_attributes|, as it may change over time. */
    sdb_p->schemaAttrs = NULL;
    if (!PORT_Strcmp("nssPublic", table) ||
        !PORT_Strcmp("nssPrivate", table)) {
        sqlite3_stmt *stmt = NULL;
        int retry = 0;
        unsigned int backedAttrs = 0;

        /* Can't bind parameters to a PRAGMA. */
        queryStr = sqlite3_mprintf("PRAGMA table_info(%s);", table);
        if (queryStr == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        sqlerr = sqlite3_prepare_v2(sqlDB, queryStr, -1, &stmt, NULL);
        sqlite3_free(queryStr);
        queryStr = NULL;
        if (sqlerr != SQLITE_OK) {
            goto loser;
        }
        unsigned int schemaAttrsCapacity = known_attributes_size;
        sdb_p->schemaAttrs = malloc(schemaAttrsCapacity * sizeof(CK_ATTRIBUTE_TYPE));
        if (!sdb_p->schemaAttrs) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
        do {
            sqlerr = sqlite3_step(stmt);
            if (sqlerr == SQLITE_BUSY) {
                PR_Sleep(SDB_BUSY_RETRY_TIME);
            }
            if (sqlerr == SQLITE_ROW) {
                if (backedAttrs == schemaAttrsCapacity) {
                    schemaAttrsCapacity += known_attributes_size;
                    sdb_p->schemaAttrs = realloc(sdb_p->schemaAttrs,
                                                 schemaAttrsCapacity * sizeof(CK_ATTRIBUTE_TYPE));
                    if (!sdb_p->schemaAttrs) {
                        error = CKR_HOST_MEMORY;
                        goto loser;
                    }
                }
                /* Record the ULONG attribute value. */
                char *val = (char *)sqlite3_column_text(stmt, 1);
                if (val && val[0] == 'a') {
                    CK_ATTRIBUTE_TYPE attr = strtoul(&val[1], NULL, 16);
                    sdb_p->schemaAttrs[backedAttrs++] = attr;
                }
            }
        } while (!sdb_done(sqlerr, &retry));

        if (sqlerr != SQLITE_DONE) {
            goto loser;
        }
        sqlerr = sqlite3_reset(stmt);
        if (sqlerr != SQLITE_OK) {
            goto loser;
        }
        sqlerr = sqlite3_finalize(stmt);
        if (sqlerr != SQLITE_OK) {
            goto loser;
        }

        sdb_p->numSchemaAttrs = backedAttrs;

        /* Sort these once so we can shortcut invalid attribute searches. */
        qsort(sdb_p->schemaAttrs, sdb_p->numSchemaAttrs,
              sizeof(CK_ATTRIBUTE_TYPE), sdb_attributeComparator);
    }

    /* invariant fields */
    sdb_p->sqlDBName = PORT_Strdup(dbname);
    sdb_p->type = type;
    sdb_p->table = table;
    sdb_p->cacheTable = cacheTable;
    sdb_p->lastUpdateTime = now;
    /* set the cache delay time. This is how long we will wait before we
     * decide the existing cache is stale. Currently set to 10 sec */
    sdb_p->updateInterval = PR_SecondsToInterval(10);
    sdb_p->dbMon = PR_NewMonitor();
    /* these fields are protected by the lock */
    sdb_p->sqlXactDB = NULL;
    sdb_p->sqlXactThread = NULL;
    sdb->private = sdb_p;
    sdb->version = 1;
    sdb->sdb_flags = inFlags | SDB_HAS_META;
    sdb->app_private = NULL;
    sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
    sdb->sdb_FindObjects = sdb_FindObjects;
    sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal;
    sdb->sdb_GetAttributeValue = sdb_GetAttributeValue;
    sdb->sdb_SetAttributeValue = sdb_SetAttributeValue;
    sdb->sdb_CreateObject = sdb_CreateObject;
    sdb->sdb_DestroyObject = sdb_DestroyObject;
    sdb->sdb_GetMetaData = sdb_GetMetaData;
    sdb->sdb_PutMetaData = sdb_PutMetaData;
    sdb->sdb_DestroyMetaData = sdb_DestroyMetaData;
    sdb->sdb_Begin = sdb_Begin;
    sdb->sdb_Commit = sdb_Commit;
    sdb->sdb_Abort = sdb_Abort;
    sdb->sdb_Reset = sdb_Reset;
    sdb->sdb_Close = sdb_Close;
    sdb->sdb_SetForkState = sdb_SetForkState;
    sdb->sdb_GetNewObjectID = sdb_GetNewObjectID;

    if (inTransaction) {
        sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL);
        if (sqlerr != SQLITE_OK) {
            error = sdb_mapSQLError(sdb_p->type, sqlerr);
            goto loser;
        }
        inTransaction = 0;
    }

    sdb_p->sqlReadDB = sqlDB;

    *pSdb = sdb;
    UNLOCK_SQLITE();
    return CKR_OK;

loser:
    /* lots of stuff to do */
    if (inTransaction) {
        sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
    }
    if (sdb) {
        free(sdb);
    }
    if (sdb_p) {
        if (sdb_p->schemaAttrs) {
            free(sdb_p->schemaAttrs);
        }
        free(sdb_p);
    }
    if (sqlDB) {
        sqlite3_close(sqlDB);
    }
    UNLOCK_SQLITE();
    return error;
}

/* sdbopen */
CK_RV
s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
       int cert_version, int key_version, int flags,
       SDB **certdb, SDB **keydb, int *newInit)
{
    char *cert = sdb_BuildFileName(directory, certPrefix,
                                   "cert", cert_version);
    char *key = sdb_BuildFileName(directory, keyPrefix,
                                  "key", key_version);
    CK_RV error = CKR_OK;
    int inUpdate;
    PRUint32 accessOps;

    if (certdb)
        *certdb = NULL;
    if (keydb)
        *keydb = NULL;
    *newInit = 0;

#ifdef SQLITE_UNSAFE_THREADS
    if (sqlite_lock == NULL) {
        sqlite_lock = PR_NewLock();
        if (sqlite_lock == NULL) {
            error = CKR_HOST_MEMORY;
            goto loser;
        }
    }
#endif

    /* how long does it take to test for a non-existant file in our working
     * directory? Allows us to test if we may be on a network file system */
    accessOps = 1;
    {
        char *env;
        env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
        /* If the environment variable is undefined or set to yes or no,
         * sdb_init() will ignore the value of accessOps, and we can skip the
         * measuring.*/
        if (env && PORT_Strcasecmp(env, "no") != 0 &&
            PORT_Strcasecmp(env, "yes") != 0) {
            accessOps = sdb_measureAccess(directory);
        }
    }

    /*
     * open the cert data base
     */
    if (certdb) {
        /* initialize Certificate database */
        error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate,
                         newInit, flags, accessOps, certdb);
        if (error != CKR_OK) {
            goto loser;
        }
    }

    /*
     * open the key data base:
     *  NOTE:if we want to implement a single database, we open
     *  the same database file as the certificate here.
     *
     *  cert an key db's have different tables, so they will not
     *  conflict.
     */
    if (keydb) {
        /* initialize the Key database */
        error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate,
                         newInit, flags, accessOps, keydb);
        if (error != CKR_OK) {
            goto loser;
        }
    }

loser:
    if (cert) {
        sqlite3_free(cert);
    }
    if (key) {
        sqlite3_free(key);
    }

    if (error != CKR_OK) {
        /* currently redundant, but could be necessary if more code is added
         * just before loser */
        if (keydb && *keydb) {
            sdb_Close(*keydb);
        }
        if (certdb && *certdb) {
            sdb_Close(*certdb);
        }
    }

    return error;
}

CK_RV
s_shutdown()
{
#ifdef SQLITE_UNSAFE_THREADS
    if (sqlite_lock) {
        PR_DestroyLock(sqlite_lock);
        sqlite_lock = NULL;
    }
#endif
    return CKR_OK;
}
