X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_cspdl/lib/SSDatabase.cpp?ds=inline diff --git a/libsecurity_apple_cspdl/lib/SSDatabase.cpp b/libsecurity_apple_cspdl/lib/SSDatabase.cpp deleted file mode 100644 index fe5de190..00000000 --- a/libsecurity_apple_cspdl/lib/SSDatabase.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (c) 2000-2001 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. - */ - - -// -// SSDatabase.cpp - Security Server database object -// -#include "SSDatabase.h" - -#include - -using namespace CssmClient; -using namespace SecurityServer; - -const char *const SSDatabaseImpl::DBBlobRelationName = "DBBlob"; - - -SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession, const CssmClient::DL &dl, - const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation) - : Db::Impl(dl, inDbName, inDbLocation), mClientSession(inClientSession), mSSDbHandle(noDb) -{ -} - -SSDatabaseImpl::~SSDatabaseImpl() -try -{ - if (mSSDbHandle != noDb) - mClientSession.releaseDb(mSSDbHandle); -} -catch (...) -{ -} - -SSUniqueRecord -SSDatabaseImpl::insert(CSSM_DB_RECORDTYPE recordType, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, - const CSSM_DATA *data, bool) -{ - SSUniqueRecord uniqueId(SSDatabase(this)); - check(CSSM_DL_DataInsert(handle(), recordType, - attributes, - data, uniqueId)); - // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope. - uniqueId->activate(); - return uniqueId; -} - -void -SSDatabaseImpl::authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest, - const CSSM_ACCESS_CREDENTIALS *inAccessCredentials) -{ - mClientSession.authenticateDb(dbHandle(), inAccessRequest, - AccessCredentials::overlay(inAccessCredentials)); -} - -void -SSDatabaseImpl::lock() -{ - mClientSession.lock(dbHandle()); - -} - -void -SSDatabaseImpl::unlock() -{ - mClientSession.unlock(dbHandle()); -} - -void -SSDatabaseImpl::unlock(const CSSM_DATA &password) -{ - mClientSession.unlock(dbHandle(), CssmData::overlay(password)); -} - -void -SSDatabaseImpl::stash() -{ - mClientSession.stashDb(dbHandle()); -} - -void -SSDatabaseImpl::stashCheck() -{ - mClientSession.stashDbCheck(dbHandle()); -} - -void -SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep) -{ - DBParameters parameters; - mClientSession.getDbParameters(dbHandle(), parameters); - outIdleTimeout = parameters.idleTimeout; - outLockOnSleep = parameters.lockOnSleep; -} - -void -SSDatabaseImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep) -{ - DBParameters parameters; - parameters.idleTimeout = inIdleTimeout; - parameters.lockOnSleep = inLockOnSleep; - mClientSession.setDbParameters(dbHandle(), parameters); - - // Reencode the db blob. - CssmDataContainer dbb(allocator()); - mClientSession.encodeDb(mSSDbHandle, dbb, allocator()); - getDbBlobId()->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE); -} - -bool -SSDatabaseImpl::isLocked() -{ - return mClientSession.isLocked(dbHandle()); -} - -void -SSDatabaseImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred) -{ - mClientSession.changePassphrase(dbHandle(), AccessCredentials::overlay(cred)); - - // Reencode the db blob. - CssmDataContainer dbb(allocator()); - mClientSession.encodeDb(mSSDbHandle, dbb, allocator()); - getDbBlobId()->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE); -} - -DbHandle -SSDatabaseImpl::dbHandle() -{ - activate(); - if (mForked()) { - // re-establish the dbHandle with the SecurityServer - CssmDataContainer dbb(allocator()); - getDbBlobId(&dbb); - mSSDbHandle = mClientSession.decodeDb(mIdentifier, - AccessCredentials::overlay(accessCredentials()), dbb); - } - return mSSDbHandle; -} - -void -SSDatabaseImpl::commonCreate(const DLDbIdentifier &dlDbIdentifier, bool &autoCommit) -{ - mIdentifier = dlDbIdentifier; - // Set to false if autocommit should remain off after the create. - autoCommit = true; - - // OpenParameters to use - CSSM_APPLEDL_OPEN_PARAMETERS newOpenParameters = - { - sizeof(CSSM_APPLEDL_OPEN_PARAMETERS), - CSSM_APPLEDL_OPEN_PARAMETERS_VERSION, - CSSM_FALSE, // do not auto-commit - 0 // mask - do not use following fields - }; - - // Get the original openParameters and apply them to the ones we - // are passing in. - const CSSM_APPLEDL_OPEN_PARAMETERS *inOpenParameters = - reinterpret_cast(openParameters()); - if (inOpenParameters) - { - switch (inOpenParameters->version) - { - case 1: - if (inOpenParameters->length < sizeof(CSSM_APPLEDL_OPEN_PARAMETERS)) - CssmError::throwMe(CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS); - - newOpenParameters.mask = inOpenParameters->mask; - newOpenParameters.mode = inOpenParameters->mode; - /*DROPTHROUGH*/ - case 0: - //if (inOpenParameters->length < sizeof(CSSM_APPLEDL_OPEN_PARAMETERS_V0)) - // CssmError::throwMe(CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS); - - // This will determine whether we leave autocommit off or not. - autoCommit = inOpenParameters->autoCommit == CSSM_FALSE ? false : true; - break; - - default: - CssmError::throwMe(CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS); - } - } - - // Use the new openParameters - openParameters(&newOpenParameters); - try - { - DbImpl::create(); - // Restore the original openparameters again. - openParameters(inOpenParameters); - } - catch (...) - { - // Make sure restore the original openparameters again even if - // create throws. - openParameters(inOpenParameters); - throw; - } - - // @@@ The CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO - // arguments should be optional. - createRelation(DBBlobRelationID, DBBlobRelationName, - 0, (CSSM_DB_SCHEMA_ATTRIBUTE_INFO *)42, - 0, (CSSM_DB_SCHEMA_INDEX_INFO *)42); - - // @@@ Only iff not already in mDbInfo - createRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY, "CSSM_DL_DB_RECORD_PUBLIC_KEY", - KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList, - KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList); - - // @@@ Only iff not already in mDbInfo - createRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY, "CSSM_DL_DB_RECORD_PRIVATE_KEY", - KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList, - KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList); - - // @@@ Only iff not already in mDbInfo - createRelation(CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "CSSM_DL_DB_RECORD_SYMMETRIC_KEY", - KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList, - KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList); -} - -void -SSDatabaseImpl::create(const DLDbIdentifier &dlDbIdentifier) -{ - try - { - bool autoCommit; - commonCreate(dlDbIdentifier, autoCommit); - - DBParameters dbParameters; - memset(&dbParameters, 0, sizeof(DBParameters)); - dbParameters.idleTimeout = kDefaultIdleTimeout; - dbParameters.lockOnSleep = kDefaultLockOnSleep; - - const AccessCredentials *cred = NULL; - const AclEntryInput *owner = NULL; - if (resourceControlContext()) - { - cred = AccessCredentials::overlay(resourceControlContext()->AccessCred); - owner = &AclEntryInput::overlay(resourceControlContext()->InitialAclEntry); - } - mSSDbHandle = mClientSession.createDb(dlDbIdentifier, cred, owner, dbParameters); - CssmDataContainer dbb(allocator()); - mClientSession.encodeDb(mSSDbHandle, dbb, allocator()); - Db::Impl::insert(DBBlobRelationID, NULL, &dbb); - if (autoCommit) - { - passThrough(CSSM_APPLEFILEDL_COMMIT, NULL); - passThrough(CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, - reinterpret_cast(1)); - } - } - catch(CssmError e) - { - if (e.error != CSSMERR_DL_DATASTORE_ALREADY_EXISTS) - { - DbImpl::deleteDb(); - } - throw; - } - catch(...) - { - DbImpl::deleteDb(); - throw; - } -} - -void -SSDatabaseImpl::createWithBlob(const DLDbIdentifier &dlDbIdentifier, const CSSM_DATA &blob) -{ - try - { - bool autoCommit; - commonCreate(dlDbIdentifier, autoCommit); - Db::Impl::insert(DBBlobRelationID, NULL, &blob); - if (autoCommit) - { - passThrough(CSSM_APPLEFILEDL_COMMIT, NULL); - passThrough(CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, - reinterpret_cast(1)); - } - } - catch(...) - { - DbImpl::deleteDb(); - throw; - } -} - -void -SSDatabaseImpl::open(const DLDbIdentifier &dlDbIdentifier) -{ - mIdentifier = dlDbIdentifier; - Db::Impl::open(); - - CssmDataContainer dbb(allocator()); - getDbBlobId(&dbb); - - mSSDbHandle = mClientSession.decodeDb(dlDbIdentifier, AccessCredentials::overlay(accessCredentials()), dbb); -} - -void -SSDatabaseImpl::recode(const CssmData &data, const CssmData &extraData) -{ - // Start a transaction (Implies activate()). - passThrough(CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, 0); - - try - { - CssmDataContainer dbb(allocator()); - // Make sure mSSDbHandle is valid. - CssmClient::DbUniqueRecord dbBlobId = getDbBlobId(&dbb); - if (mForked()) { - // re-establish the dbHandle with the SecurityServer - mSSDbHandle = mClientSession.decodeDb(mIdentifier, - AccessCredentials::overlay(accessCredentials()), dbb); - } - dbb.clear(); - - DbHandle successfulHdl = mClientSession.authenticateDbsForSync(data, extraData); - - // Create a newDbHandle using the master secrets from the dbBlob we are - // recoding to. - SecurityServer::DbHandle clonedDbHandle = - mClientSession.recodeDbForSync(successfulHdl, mSSDbHandle); - - // @@@ If the dbb changed since we fetched it we should abort or - // retry the operation here. - - // Recode all keys - DbCursor cursor(SSDatabase(this)); - cursor->recordType(CSSM_DL_DB_RECORD_ALL_KEYS); - CssmDataContainer keyBlob(allocator()); - CssmClient::DbUniqueRecord keyBlobId; - DbAttributes attributes; - while (cursor->next(&attributes, &keyBlob, keyBlobId)) - { - // Decode the old key - CssmKey::Header header; - KeyHandle keyHandle = - mClientSession.decodeKey(mSSDbHandle, keyBlob, header); - // Recode the key - CssmDataContainer newKeyBlob(mClientSession.returnAllocator); - mClientSession.recodeKey(mSSDbHandle, keyHandle, clonedDbHandle, - newKeyBlob); - mClientSession.releaseKey(keyHandle); - // Write the recoded key blob to the database - keyBlobId->modify(attributes.recordType(), NULL, &newKeyBlob, - CSSM_DB_MODIFY_ATTRIBUTE_NONE); - } - - // Commit the new blob to securityd, reencode the db blob, release the - // cloned db handle and commit the new blob to the db. - mClientSession.commitDbForSync(mSSDbHandle, clonedDbHandle, - dbb, allocator()); - dbBlobId->modify(DBBlobRelationID, NULL, &dbb, - CSSM_DB_MODIFY_ATTRIBUTE_NONE); - - // Commit the transaction to the db - passThrough(CSSM_APPLEFILEDL_COMMIT, NULL); - passThrough(CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, - reinterpret_cast(1)); - } - catch (...) - { - // Something went wrong rollback the transaction - passThrough(CSSM_APPLEFILEDL_ROLLBACK, NULL); - passThrough(CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, - reinterpret_cast(1)); - throw; - } -} - -void SSDatabaseImpl::getRecordIdentifier(CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord, CSSM_DATA &recordID) -{ - // the unique ID is composed of three uint32s (plus one filler word). Pull - // them out and byte swap them - recordID.Length = sizeof (uint32) * kNumIDWords; - recordID.Data = (uint8*) allocator().malloc(recordID.Length); - - // copy the data - uint32* dest = (uint32*) recordID.Data; - uint32* src = (uint32*) uniqueRecord->RecordIdentifier.Data; - - dest[0] = htonl (src[0]); - dest[1] = htonl (src[1]); - dest[2] = htonl (src[2]); - dest[3] = 0; -} - -void SSDatabaseImpl::copyBlob(CSSM_DATA &data) -{ - // get the blob from the database - CssmDataContainer dbb(allocator()); - getDbBlobId(&dbb); - - // copy the data back - data.Data = dbb.Data; - data.Length = dbb.Length; - - // zap the return structure so that we don't get zapped when dbb goes out of scope... - dbb.Data = NULL; - dbb.Length = 0; -} - -DbUniqueRecordImpl * -SSDatabaseImpl::newDbUniqueRecord() -{ - return new SSUniqueRecordImpl(SSDatabase(this)); -} - -CssmClient::DbUniqueRecord -SSDatabaseImpl::getDbBlobId(CssmDataContainer *dbb) -{ - CssmClient::DbUniqueRecord dbBlobId; - - DbCursor cursor(SSDatabase(this)); - cursor->recordType(DBBlobRelationID); - if (!cursor->next(NULL, dbb, dbBlobId)) - CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT); - - return dbBlobId; -} - - - -SSUniqueRecordImpl::SSUniqueRecordImpl(const SSDatabase &db) -: DbUniqueRecord::Impl(db) -{ -} - -SSUniqueRecordImpl::~SSUniqueRecordImpl() -{ -} - -SSDatabase -SSUniqueRecordImpl::database() const -{ - return parent(); -}