X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_filedb/lib/AppleDatabase.h?ds=inline diff --git a/libsecurity_filedb/lib/AppleDatabase.h b/libsecurity_filedb/lib/AppleDatabase.h deleted file mode 100644 index 738b9126..00000000 --- a/libsecurity_filedb/lib/AppleDatabase.h +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Copyright (c) 2000-2001, 2003 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS - * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT - * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the - * specific language governing rights and limitations under the License. - */ - - -// -// AppleDatabase.h - Description t.b.d. -// -#ifndef _H_APPLEDATABASE -#define _H_APPLEDATABASE - -#include "MetaRecord.h" -#include "SelectionPredicate.h" -#include "DbIndex.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Security -{ - -// Abstract database Cursor class. -class Cursor; -class DbVersion; -class CssmAutoQuery; - -struct AppleDatabaseTableName -{ - uint32 mTableId; - const char *mTableName; - - // indices of meta-table entries in an array of table names - - enum { - kSchemaInfo = 0, - kSchemaAttributes, - kSchemaIndexes, - kSchemaParsingModule, - kNumRequiredTableNames - }; -}; - -// -// This is what the CDSA standard refers to as a Relation. We use -// the more conventional term Table. -// -class Table -{ - NOCOPY(Table) -public: - // Type used to refer to a table. - typedef CSSM_DB_RECORDTYPE Id; - - Table(const ReadSection &inTableSection); - ~Table(); - - // Return a newly created cursor satisfying inQuery on the receiving table - // The returned Cursor may or may not use indexes depending on their availability. - Cursor *createCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion) const; - - const ReadSection getRecordSection(uint32 inRecordNumber) const; - - const RecordId getRecord(const RecordId &inRecordId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - Allocator &inAllocator) const; - - // Return the number of recordNumbers in use by this table including empty slots. - uint32 recordNumberCount() const { return mRecordNumbersCount; } - uint32 freeListHead() const { return mFreeListHead; } - - // Return the record number corresponding to aFreeListHead and update - // aFreeListHead to point to the next availble recordNumber slot. - uint32 popFreeList(uint32 &aFreeListHead) const; - - MetaRecord &getMetaRecord() { return mMetaRecord; } - const MetaRecord &getMetaRecord() const { return mMetaRecord; } - - uint32 getRecordsCount() const { return mRecordsCount; } - const ReadSection getRecordsSection() const; - - const ReadSection &getTableSection() const { return mTableSection; } - - bool matchesTableId(Id inTableId) const; - - void readIndexSection(); - - enum - { - OffsetSize = AtomSize * 0, - OffsetId = AtomSize * 1, - OffsetRecordsCount = AtomSize * 2, - OffsetRecords = AtomSize * 3, - OffsetIndexesOffset = AtomSize * 4, - OffsetFreeListHead = AtomSize * 5, - OffsetRecordNumbersCount = AtomSize * 6, - OffsetRecordNumbers = AtomSize * 7 - }; -protected: - friend class ModifiedTable; - - MetaRecord mMetaRecord; - const ReadSection mTableSection; - - uint32 mRecordsCount; - uint32 mFreeListHead; - // Number of record numbers (including freelist slots) in this table. - uint32 mRecordNumbersCount; - - // all the table's indexes, mapped by index id - typedef map ConstIndexMap; - ConstIndexMap mIndexMap; -}; - -class ModifiedTable -{ - NOCOPY(ModifiedTable) -public: - ModifiedTable(const Table *inTable); - ModifiedTable(MetaRecord *inMetaRecord); // Take over ownership of inMetaRecord - ~ModifiedTable(); - - // Mark the record with inRecordId as deleted. - void deleteRecord(const RecordId &inRecordId); - const RecordId insertRecord(uint32 inVersionId, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData); - const RecordId updateRecord(const RecordId &inRecordId, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData, - CSSM_DB_MODIFY_MODE inModifyMode); - const RecordId getRecord(const RecordId &inRecordId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - Allocator &inAllocator) const; - - // Return the MetaRecord this table should use for writes. - const MetaRecord &getMetaRecord() const; - - // find, and create if needed, an index with the given id - DbMutableIndex &findIndex(uint32 indexId, const MetaRecord &metaRecord, bool isUniqueIndex); - - // Write this table to inOutputFile at inSectionOffset and return the new offset. - uint32 writeTable(AtomicTempFile &inAtomicTempFile, uint32 inSectionOffset); - -private: - // Return the next available record number for this table. - uint32 nextRecordNumber(); - - // Return the number of recordNumbers in use by this table including empty slots. - uint32 recordNumberCount() const; - - void modifyTable(); - void createMutableIndexes(); - uint32 writeIndexSection(WriteSection &tableSection, uint32 offset); - - // Optional, this is merly a reference, we do not own this object. - const Table *mTable; - - // Optional, New MetaRecord. This is only present if it is different from the - // MetaRecord of mTable or mTable is nil. - const MetaRecord *mNewMetaRecord; - - // Set of Records that have been deleted or modified. - typedef set DeletedSet; - DeletedSet mDeletedSet; - - // Set of Records that have been inserted or modified. - typedef map InsertedMap; - InsertedMap mInsertedMap; - - // Next lowest available RecordNumber - uint32 mRecordNumberCount; - // Head of the free list (if there is one) or 0 if either we have no - // mTable of the free list has been exhausted. - uint32 mFreeListHead; - - // has this table actually been modified? - bool mIsModified; - - typedef map MutableIndexMap; - MutableIndexMap mIndexMap; -}; - -// -// Read only snapshot of a database. -// -class Metadata -{ - NOCOPY(Metadata) -protected: - Metadata() {} - enum - { - HeaderOffset = 0, // Absolute offset of header. - OffsetMagic = AtomSize * 0, - OffsetVersion = AtomSize * 1, - OffsetAuthOffset = AtomSize * 2, - OffsetSchemaOffset = AtomSize * 3, - HeaderSize = AtomSize * 4, - - HeaderMagic = FOUR_CHAR_CODE('kych'), - HeaderVersion = 0x00010000 - }; - - enum - { - OffsetSchemaSize = AtomSize * 0, - OffsetTablesCount = AtomSize * 1, - OffsetTables = AtomSize * 2 - }; -}; - -// -// Read only representation of a database -// -class DbVersion : public Metadata, public RefCount -{ - NOCOPY(DbVersion) -public: - DbVersion(const class AppleDatabase &db, const RefPointer &inAtomicBufferedFile); - ~DbVersion(); - - uint32 getVersionId() const { return mVersionId; } - const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId, - CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes, - CssmData *inoutData, Allocator &inAllocator) const; - Cursor *createCursor(const CSSM_QUERY *inQuery) const; -protected: - const Table &findTable(Table::Id inTableId) const; - Table &findTable(Table::Id inTableId); - -private: - void open(); // Part of constructor contract. - - ReadSection mDatabase; - uint32 mVersionId; - - friend class DbModifier; // XXX Fixme - typedef map TableMap; - TableMap mTableMap; - const class AppleDatabase &mDb; - RefPointer mBufferedFile; - -public: - typedef Table value_type; - typedef const Table &const_reference; - typedef const Table *const_pointer; - - // A const forward iterator. - class const_iterator - { - public: - const_iterator(const TableMap::const_iterator &it) : mIterator(it) {} - - // Use default copy consturctor and assignment operator. - //const_iterator(const const_iterator &it) : mIterator(it.mIterator) {} - //const_iterator &operator=(const const_iterator &it) { mIterator = it.mIterator; return *this; } - const_reference operator*() const { return *mIterator->second; } - const_iterator &operator++() { mIterator.operator++(); return *this; } - const_iterator operator++(int i) { return const_iterator(mIterator.operator++(i)); } - bool operator!=(const const_iterator &other) const { return mIterator != other.mIterator; } - bool operator==(const const_iterator &other) const { return mIterator == other.mIterator; } - - const_pointer operator->() const { return mIterator->second; } // Not really needed. - - private: - TableMap::const_iterator mIterator; - }; - - const_iterator begin() const { return const_iterator(mTableMap.begin()); } - const_iterator end() const { return const_iterator(mTableMap.end()); } - - bool hasTable(Table::Id inTableId) const; -}; - -// -// Cursor -// -class Cursor : public HandleObject -{ -public: - Cursor(); - Cursor(const DbVersion &inDbVersion); - virtual ~Cursor(); - virtual bool next(Table::Id &outTableId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, - CssmData *outData, - Allocator &inAllocator, - RecordId &recordId); -protected: - const RefPointer mDbVersion; -}; - - -// -// LinearCursor -// -class LinearCursor : public Cursor -{ - NOCOPY(LinearCursor) -public: - LinearCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion, - const Table &inTable); - virtual ~LinearCursor(); - virtual bool next(Table::Id &outTableId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, - CssmData *outData, - Allocator &inAllocator, - RecordId &recordId); - -private: - uint32 mRecordsCount; - uint32 mRecord; - const ReadSection mRecordsSection; - uint32 mReadOffset; - const MetaRecord &mMetaRecord; - - CSSM_DB_CONJUNCTIVE mConjunctive; - CSSM_QUERY_FLAGS mQueryFlags; // If CSSM_QUERY_RETURN_DATA is set return the raw key bits; - typedef vector PredicateVector; - - PredicateVector mPredicates; -}; - -// -// A cursor that uses an index. -// - -class IndexCursor : public Cursor -{ - NOCOPY(IndexCursor) -public: - IndexCursor(DbQueryKey *queryKey, const DbVersion &inDbVersion, - const Table &table, const DbConstIndex *index); - virtual ~IndexCursor(); - - virtual bool next(Table::Id &outTableId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, - CssmData *outData, - Allocator &inAllocator, - RecordId &recordId); - -private: - auto_ptr mQueryKey; - const Table &mTable; - const DbConstIndex *mIndex; - - DbIndexIterator mBegin, mEnd; -}; - -// -// MultiCursor -// -class MultiCursor : public Cursor -{ - NOCOPY(MultiCursor) -public: - MultiCursor(const CSSM_QUERY *inQuery, const DbVersion &inDbVersion); - virtual ~MultiCursor(); - virtual bool next(Table::Id &outTableId, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR outAttributes, - CssmData *outData, - Allocator &inAllocator, - RecordId &recordId); -private: - auto_ptr mQuery; - - DbVersion::const_iterator mTableIterator; - auto_ptr mCursor; -}; - -// -// A DbModifier contains all pending changes to be made to a DB. -// It also contains a DbVersion representing the state of the Database before any such changes -// No read-style operations are supported by DbModifier. If a DbModifier exists for a -// particular Database and a client wishes to perform a query commit() must be called and -// the client should perform the new query on the current database version after the commit. -// Otherwise a client will not see changes made since the DbModifier was instanciated. -// -class DbModifier : public Metadata -{ - NOCOPY(DbModifier) -public: - DbModifier(AtomicFile &inAtomicFile, const class AppleDatabase &db); - ~DbModifier(); - - // Whole database affecting members. - void createDatabase(const CSSM_DBINFO &inDbInfo, - const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry, - mode_t mode); - void openDatabase(); // This is optional right now. - void closeDatabase(); - void deleteDatabase(); - - void commit(); - void rollback() throw(); - - // Record changing members - void deleteRecord(Table::Id inTableId, const RecordId &inRecordId); - const RecordId insertRecord(Table::Id inTableId, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData); - const RecordId updateRecord(Table::Id inTableId, const RecordId &inRecordId, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData, - CSSM_DB_MODIFY_MODE inModifyMode); - - // Schema changing members - void insertTable(Table::Id inTableId, const string &inTableName, - uint32 inNumberOfAttributes, - const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, - uint32 inNumberOfIndexes, - const CSSM_DB_SCHEMA_INDEX_INFO *inIndexInfo); - void deleteTable(Table::Id inTableId); - - // Record reading members - const RecordId getRecord(Table::Id inTableId, const RecordId &inRecordId, - CSSM_DB_RECORD_ATTRIBUTE_DATA *inoutAttributes, - CssmData *inoutData, Allocator &inAllocator); - Cursor *createCursor(const CSSM_QUERY *inQuery); - - bool hasTable(Table::Id inTableid); - -protected: - void modifyDatabase(); - const RefPointer getDbVersion(bool force); - - ModifiedTable *createTable(MetaRecord *inMetaRecord); // Takes over ownership of inMetaRecord - - void insertTableSchema(const CssmDbRecordAttributeInfo &inInfo, - const CSSM_DB_RECORD_INDEX_INFO *inIndexInfo = NULL); - - void insertTable(const CssmDbRecordAttributeInfo &inInfo, - const CSSM_DB_RECORD_INDEX_INFO * inIndexInfo = NULL, - const CSSM_DB_PARSING_MODULE_INFO * inParsingModule = NULL); - - ModifiedTable &findTable(Table::Id inTableId); - - uint32 writeAuthSection(uint32 inSectionOffset); - uint32 writeSchemaSection(uint32 inSectionOffset); - -private: - - /* mDbVersion is the current DbVersion of this database before any changes - we are going to make. mNotifyCount holds the value of gNotifyCount at - the time mDbVersion was created. mDbLastRead is the time at which we - last checked if the file from which mDbVersion was read has changed. - mDbVersionLock protects the other 3 fields. */ - RefPointer mDbVersion; - int32_t mNotifyCount; - CFAbsoluteTime mDbLastRead; - Mutex mDbVersionLock; - - AtomicFile &mAtomicFile; - uint32 mVersionId; - RefPointer mAtomicTempFile; - - typedef map ModifiedTableMap; - ModifiedTableMap mModifiedTableMap; - - const class AppleDatabase &mDb; -}; - -// -// AppleDatabaseManager -// -class AppleDatabaseManager : public DatabaseManager -{ -public: - AppleDatabaseManager(const AppleDatabaseTableName *tableNames); - Database *make(const DbName &inDbName); - -protected: - const AppleDatabaseTableName *mTableNames; -}; - -// -// AppleDbContext -// -class AppleDbContext : public DbContext -{ -public: - AppleDbContext(Database &inDatabase, - DatabaseSession &inDatabaseSession, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const AccessCredentials *inAccessCred, - const void *inOpenParameters); - virtual ~AppleDbContext(); - bool autoCommit() const { return mAutoCommit; } - void autoCommit(bool on) { mAutoCommit = on; } - mode_t mode() const { return mMode; } - -private: - bool mAutoCommit; - mode_t mMode; -}; - -// -// AppleDatabase -// -class AppleDatabase : public Database -{ -public: - AppleDatabase(const DbName &inDbName, const AppleDatabaseTableName *tableNames); - virtual ~AppleDatabase(); - - virtual void - dbCreate(DbContext &inDbContext, const CSSM_DBINFO &inDBInfo, - const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry); - - virtual void - dbOpen(DbContext &inDbContext); - - virtual void - dbClose(); - - virtual void - dbDelete(DatabaseSession &inDatabaseSession, - const AccessCredentials *inAccessCred); - - virtual void - createRelation(DbContext &inDbContext, - CSSM_DB_RECORDTYPE inRelationID, - const char *inRelationName, - uint32 inNumberOfAttributes, - const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, - uint32 inNumberOfIndexes, - const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo); - - virtual void - destroyRelation(DbContext &inDbContext, - CSSM_DB_RECORDTYPE inRelationID); - - virtual void - authenticate(DbContext &inDbContext, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const AccessCredentials &inAccessCred); - - virtual void - getDbAcl(DbContext &inDbContext, - const CSSM_STRING *inSelectionTag, - uint32 &outNumberOfAclInfos, - CSSM_ACL_ENTRY_INFO_PTR &outAclInfos); - - virtual void - changeDbAcl(DbContext &inDbContext, - const AccessCredentials &inAccessCred, - const CSSM_ACL_EDIT &inAclEdit); - - virtual void - getDbOwner(DbContext &inDbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner); - - virtual void - changeDbOwner(DbContext &inDbContext, - const AccessCredentials &inAccessCred, - const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner); - - virtual char * - getDbNameFromHandle(const DbContext &inDbContext) const; - - virtual CSSM_DB_UNIQUE_RECORD_PTR - dataInsert(DbContext &inDbContext, - CSSM_DB_RECORDTYPE RecordType, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData); - - virtual void - dataDelete(DbContext &inDbContext, - const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier); - - virtual void - dataModify(DbContext &inDbContext, - CSSM_DB_RECORDTYPE inRecordType, - CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified, - const CssmData *inDataToBeModified, - CSSM_DB_MODIFY_MODE inModifyMode); - - virtual CSSM_HANDLE - dataGetFirst(DbContext &inDbContext, - const CssmQuery *inQuery, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord); - - virtual bool - dataGetNext(DbContext &inDbContext, - CSSM_HANDLE inResultsHandle, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord); - - virtual void - dataAbortQuery(DbContext &inDbContext, - CSSM_HANDLE inResultsHandle); - - virtual void - dataGetFromUniqueRecordId(DbContext &inDbContext, - const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData); - - virtual void - freeUniqueRecord(DbContext &inDbContext, - CSSM_DB_UNIQUE_RECORD &inUniqueRecord); - - virtual void passThrough(DbContext &dbContext, - uint32 passThroughId, - const void *inputParams, - void **outputParams); - - // Subclasses must implement this method. - virtual DbContext *makeDbContext(DatabaseSession &inDatabaseSession, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const AccessCredentials *inAccessCred, - const void *inOpenParameters); - - const CssmDbRecordAttributeInfo schemaRelations; - const CssmDbRecordAttributeInfo schemaAttributes; - const CssmDbRecordAttributeInfo schemaIndexes; - const CssmDbRecordAttributeInfo schemaParsingModule; - - const char *recordName(CSSM_DB_RECORDTYPE inRecordType) const; - -private: - static void - updateUniqueRecord(DbContext &inDbContext, - CSSM_DB_RECORDTYPE inTableId, - const RecordId &inRecordId, - CSSM_DB_UNIQUE_RECORD &inoutUniqueRecord); - - CSSM_DB_UNIQUE_RECORD_PTR - createUniqueRecord(DbContext &inDbContext, CSSM_DB_RECORDTYPE inTableId, - const RecordId &inRecordId); - const RecordId parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, - CSSM_DB_RECORDTYPE &outTableId); - - Mutex mWriteLock; - AtomicFile mAtomicFile; - DbModifier mDbModifier; - const AppleDatabaseTableName *mTableNames; -}; - -} // end namespace Security - -#endif //_H_APPLEDATABASE