#ifndef _H_SSDATABASE_
#define _H_SSDATABASE_
#include <security_cdsa_client/dlclient.h>
#include <security_utilities/unix++.h>
#include <securityd_client/ssclient.h>
#include <securityd_client/ssblob.h>
#include <security_utilities/CSPDLTransaction.h>
class SSCSPDLSession;
class SSUniqueRecord;
class SSDatabase;
class SSDatabaseImpl : public CssmClient::DbImpl
{
public:
static const char *const DBBlobRelationName;
static const CSSM_DB_RECORDTYPE DBBlobRelationID =
CSSM_DB_RECORDTYPE_APP_DEFINED_START + 0x8000;
public:
SSDatabaseImpl(SecurityServer::ClientSession &inClientSession,
const CssmClient::DL &dl,
const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
virtual ~SSDatabaseImpl();
void ssCreate(const DLDbIdentifier &dlDbIdentifier);
void ssCreateWithBlob(const DLDbIdentifier &dlDbIdentifier, const CSSM_DATA &blob);
void ssOpen(const DLDbIdentifier &dlDbIdentifier);
SSUniqueRecord ssInsert(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data);
void authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
const CSSM_ACCESS_CREDENTIALS *inAccessCredentials);
void lock();
void unlock();
void unlock(const CSSM_DATA &password);
void stash();
void stashCheck();
void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
bool isLocked();
void changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred);
void ssRecode(const CssmData &data, const CssmData &extraData);
uint32 recodeDbToVersion(uint32 newBlobVersion);
void recodeFinished();
void takeFileLock();
void releaseFileLock(bool success);
CssmClient::DbUniqueRecordImpl *newDbUniqueRecord();
SecurityServer::DbHandle dbHandle();
void getRecordIdentifier(const CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord, CSSM_DATA &data);
void ssCopyBlob(CSSM_DATA& blob);
uint32 dbBlobVersion();
void makeBackup();
void makeCopy(const char* path);
void deleteFile();
SSDatabase ssCloneTo(const DLDbIdentifier& dldbidentifier);
protected:
CssmClient::DbUniqueRecord getDbBlobId(CssmDataContainer *dbb = NULL);
void commonCreate (const DLDbIdentifier &dlDbIdentifier, bool &autocommit);
void load(const DLDbIdentifier &dlDbIdentifier);
static uint32 getDbVersionFromBlob(const CssmData& dbb);
uint32 recodeHelper(SecurityServer::DbHandle clonedDbHandle, CssmClient::DbUniqueRecord& dbBlobId);
private:
static const uint32 kDefaultIdleTimeout = 5 * 60;
static const uint8 kDefaultLockOnSleep = true;
static const unsigned kNumIDWords = 4;
DLDbIdentifier mIdentifier;
UnixPlusPlus::ForkMonitor mForked;
SecurityServer::ClientSession &mClientSession;
SecurityServer::DbHandle mSSDbHandle;
DLTransaction* mTransaction;
};
class SSDatabase : public CssmClient::Db
{
public:
typedef SSDatabaseImpl Impl;
explicit SSDatabase(SSDatabaseImpl *impl) : CssmClient::Db(impl) {}
SSDatabase() : CssmClient::Db(NULL) {}
SSDatabase(SecurityServer::ClientSession &inClientSession,
const CssmClient::DL &dl,
const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
: CssmClient::Db(new SSDatabaseImpl(inClientSession, dl, inDbName, inDbLocation)) {}
SSDatabaseImpl *operator ->() const { return &impl<SSDatabaseImpl>(); }
SSDatabaseImpl &operator *() const { return impl<SSDatabaseImpl>(); }
SecurityServer::DbHandle dbHandle() { return (*this) ? (*this)->dbHandle() : SecurityServer::noDb; }
};
class SSUniqueRecordImpl : public CssmClient::DbUniqueRecordImpl
{
public:
SSUniqueRecordImpl(const SSDatabase &db);
virtual ~SSUniqueRecordImpl();
SSDatabase database() const;
};
class SSUniqueRecord : public CssmClient::DbUniqueRecord
{
public:
typedef SSUniqueRecordImpl Impl;
explicit SSUniqueRecord(SSUniqueRecordImpl *impl) : CssmClient::DbUniqueRecord(impl) {}
SSUniqueRecord() : CssmClient::DbUniqueRecord(NULL) {}
SSUniqueRecord(const SSDatabase &db) : CssmClient::DbUniqueRecord(new SSUniqueRecordImpl(db)) {}
SSUniqueRecordImpl *operator ->() const { return &impl<SSUniqueRecordImpl>(); }
SSUniqueRecordImpl &operator *() const { return impl<SSUniqueRecordImpl>(); }
};
#endif // _H_SSDATABASE_