]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_filedb/lib/MetaRecord.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_filedb / lib / MetaRecord.cpp
diff --git a/libsecurity_filedb/lib/MetaRecord.cpp b/libsecurity_filedb/lib/MetaRecord.cpp
deleted file mode 100644 (file)
index 9fc54a9..0000000
+++ /dev/null
@@ -1,580 +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.
- */
-
-
-//
-// MetaRecord.cpp
-//
-
-#include "MetaRecord.h"
-#include <security_utilities/trackingallocator.h>
-#include <security_cdsa_utilities/cssmbridge.h>
-
-
-MetaRecord::MetaRecord(CSSM_DB_RECORDTYPE inRecordType) :
-    mRecordType(inRecordType)
-{
-}
-
-MetaRecord::MetaRecord(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo)
-:      mRecordType(inInfo.DataRecordType)
-{
-       try
-       {
-               setRecordAttributeInfo(inInfo);
-       }
-       catch (...)
-       {
-               for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
-       }
-}
-
-MetaRecord::MetaRecord(CSSM_DB_RECORDTYPE inRelationID,
-                       uint32 inNumberOfAttributes,
-                                          const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo) :
-    mRecordType(inRelationID)
-{
-       try {
-               for (uint32 anIndex = 0; anIndex < inNumberOfAttributes; anIndex++)
-               {
-                       string aName;
-                       if (inAttributeInfo[anIndex].AttributeName)
-                               aName = string(inAttributeInfo[anIndex].AttributeName);
-                               
-                       const CssmData *aNameID = NULL;
-                       if (inAttributeInfo[anIndex].AttributeNameID.Length > 0)
-                               aNameID = &CssmData::overlay(inAttributeInfo[anIndex].AttributeNameID);
-
-                       uint32 aNumber = inAttributeInfo[anIndex].AttributeId;
-                       createAttribute(
-                               inAttributeInfo[anIndex].AttributeName ? &aName : NULL,
-                               aNameID, aNumber,
-                               inAttributeInfo[anIndex].DataType);
-               }
-       }
-       catch (...)
-       {
-               for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
-       }
-}
-
-MetaRecord::~MetaRecord()
-{
-       // for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
-       AttributeVector::iterator it = mAttributeVector.begin();
-       while (it != mAttributeVector.end())
-       {
-               MetaAttribute* mat = *it++;
-               if (mat != NULL)
-               {
-                       delete mat;
-               }
-       }
-}
-
-void
-MetaRecord::setRecordAttributeInfo(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo)
-{
-    for (uint32 anIndex = 0; anIndex < inInfo.NumberOfAttributes; anIndex++)
-    {
-        switch (inInfo.AttributeInfo[anIndex].AttributeNameFormat)
-        {
-            case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
-            {
-                string aName(inInfo.AttributeInfo[anIndex].Label.AttributeName);
-                createAttribute(&aName, nil, anIndex,
-                                                               inInfo.AttributeInfo[anIndex].AttributeFormat);
-                break;
-            }
-            case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
-            {
-                const CssmData &aNameID = CssmOid::overlay(inInfo.AttributeInfo[anIndex].Label.AttributeOID);
-                createAttribute(nil, &aNameID, anIndex,
-                                                               inInfo.AttributeInfo[anIndex].AttributeFormat);
-                break;
-            }
-            case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
-            {
-                uint32 aNumber = inInfo.AttributeInfo[anIndex].Label.AttributeID;
-                createAttribute(nil, nil, aNumber,
-                                                               inInfo.AttributeInfo[anIndex].AttributeFormat);
-                break;
-            }
-            default:
-                CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
-                break;
-        }
-    }
-}
-
-void
-MetaRecord::createAttribute(const string *inAttributeName,
-                                                       const CssmOid *inAttributeOID,
-                            uint32 inAttributeID,
-                                                       CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
-{
-       // Index of new element is current size of vector
-    uint32 anAttributeIndex = (uint32)mAttributeVector.size();
-    bool aInsertedAttributeName = false;
-    bool aInsertedAttributeOID = false;
-    bool aInsertedAttributeID = false;
-
-    if (inAttributeName)
-    {
-        if (!mNameStringMap.insert(NameStringMap::value_type(*inAttributeName, anAttributeIndex)).second)
-            CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
-        aInsertedAttributeName = true;
-    }
-    try
-    {
-        if (inAttributeOID)
-        {
-            if (!mNameOIDMap.insert(NameOIDMap::value_type(*inAttributeOID, anAttributeIndex)).second)
-                CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
-            aInsertedAttributeOID = true;
-        }
-
-               if (!mNameIntMap.insert(NameIntMap::value_type(inAttributeID, anAttributeIndex)).second)
-                       CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
-               aInsertedAttributeID = true;
-
-               // Note: this no longer throws INVALID_FIELD_NAME since the attribute will always have
-               // an attribute ID by which it is known
-
-               mAttributeVector.push_back(MetaAttribute::create(inAttributeFormat,
-                       anAttributeIndex, inAttributeID));
-    }
-    catch(...)
-    {
-        if (aInsertedAttributeName)
-            mNameStringMap.erase(*inAttributeName);
-        if (aInsertedAttributeOID)
-            mNameOIDMap.erase(*inAttributeOID);
-        if (inAttributeID)
-            mNameIntMap.erase(inAttributeID);
-               
-        throw;
-    }
-}
-
-
-// Create a packed record from the given inputs.
-void
-MetaRecord::packRecord(WriteSection &inWriteSection,
-                       const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
-                       const CssmData *inData) const
-{
-    uint32 aDataSize;
-    if (inData)
-        aDataSize = (uint32)inData->Length;
-    else
-        aDataSize = 0;
-
-    inWriteSection.put(OffsetDataSize, aDataSize);
-    uint32 anOffset = (uint32)(OffsetAttributeOffsets + AtomSize * mAttributeVector.size());
-    if (aDataSize)
-        anOffset = inWriteSection.put(anOffset, aDataSize, inData->Data);
-
-    vector<uint32> aNumValues(mAttributeVector.size(), ~(uint32)0);
-    vector<CSSM_DATA_PTR> aValues(mAttributeVector.size());
-    uint32 anIndex;
-
-    if (inAttributes == NULL)
-        inWriteSection.put(OffsetSemanticInformation, 0);
-    else
-    {
-        inWriteSection.put(OffsetSemanticInformation, inAttributes->SemanticInformation);
-
-        // Put the supplied attribute values into the list of attributes
-        // and values.
-        anIndex = inAttributes->NumberOfAttributes;
-        // Make sure that AttributeData is a valid array.
-               if (anIndex > 0)
-                       Required(inAttributes->AttributeData);
-
-        while (anIndex-- > 0)
-        {
-            CSSM_DB_ATTRIBUTE_DATA &anAttribute = inAttributes->AttributeData[anIndex];
-            uint32 anAttributeIndex = attributeIndex(anAttribute.Info);
-                       // Make sure that the caller specified the attribute values in the correct format.
-                       if (anAttribute.Info.AttributeFormat != mAttributeVector[anAttributeIndex]->attributeFormat())
-                               CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
-
-            // If this attribute was specified before, throw.
-            if (aNumValues[anAttributeIndex] != ~(uint32)0)
-                CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
-
-            aNumValues[anAttributeIndex] = anAttribute.NumberOfValues;
-            aValues[anAttributeIndex] = anAttribute.Value;
-        }
-    }
-
-    for (anIndex = 0; anIndex < mAttributeVector.size(); ++anIndex)
-    {
-        const MetaAttribute &aMetaAttribute = *mAttributeVector[anIndex];
-        uint32 aNumberOfValues = aNumValues[anIndex];
-        // Now call the parsingmodule for each attribute that
-        // wasn't explicitly specified and that has a parsingmodule.
-        if (aNumberOfValues == ~(uint32)0)
-            aNumberOfValues = aDataSize == 0 ? 0 : aMetaAttribute.parse(*inData, aValues[anIndex]);
-
-        // XXX When do we throw CSSMERR_DL_MISSING_VALUE?  Maybe if an
-               // attribute is part of a unique index.
-
-        // Now we have a valuelist for this attribute.  Let's encode it.
-        aMetaAttribute.packAttribute(inWriteSection, anOffset, aNumberOfValues, aValues[anIndex]);
-    }
-
-       inWriteSection.put(OffsetRecordSize, anOffset);
-    inWriteSection.size(anOffset);
-}
-
-inline void
-MetaRecord::unpackAttribute(const ReadSection &inReadSection,
-                                                       Allocator &inAllocator,
-                            CSSM_DB_ATTRIBUTE_DATA &inoutAttribute) const
-{
-    const MetaAttribute &aMetaAttribute = metaAttribute(inoutAttribute.Info);
-    // XXX: See ISSUES on whether AttributeFormat should be an outputvalue or not.
-       inoutAttribute.Info.AttributeFormat = aMetaAttribute.attributeFormat();
-    aMetaAttribute.unpackAttribute(inReadSection, inAllocator,
-                                   inoutAttribute.NumberOfValues,
-                                                                  inoutAttribute.Value);
-}
-
-void
-MetaRecord::unpackRecord(const ReadSection &inReadSection,
-                                                Allocator &inAllocator,
-                         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
-                         CssmData *inoutData,
-                                                CSSM_QUERY_FLAGS inQueryFlags) const
-{
-       // XXX Use POD wrapper for inoutAttributes here.
-       TrackingAllocator anAllocator(inAllocator);
-       
-       try
-       {
-               if (inoutData)
-               {
-                       // XXX Treat KEY records specially.
-
-                       // If inQueryFlags & CSSM_QUERY_RETURN_DATA is true return the raw
-                       // key bits in the CSSM_KEY structure
-                       Range aDataRange = dataRange(inReadSection);
-                       inoutData->Length = aDataRange.mSize;
-                       inoutData->Data = inReadSection.allocCopyRange(aDataRange, anAllocator);
-               }
-
-               if (inoutAttributes)
-               {
-                       inoutAttributes->DataRecordType = dataRecordType();
-                       inoutAttributes->SemanticInformation = semanticInformation(inReadSection);
-                       uint32 anIndex = inoutAttributes->NumberOfAttributes;
-
-                       // Make sure that AttributeData is a valid array.
-                       if (anIndex > 0 && inoutAttributes->AttributeData == NULL)
-                               CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
-
-                       while (anIndex-- > 0)
-                       {
-                               unpackAttribute(inReadSection, anAllocator,
-                                                               inoutAttributes->AttributeData[anIndex]);
-                       }
-               }
-       }
-       catch (CssmError e)
-       {
-               if (e.osStatus() != CSSMERR_DL_DATABASE_CORRUPT)
-               {
-                       // clear all pointers so that nothing dangles back to the user
-                       if (inoutData)
-                       {
-                               inoutData->Data = NULL;
-                       }
-                       
-                       if (inoutAttributes)
-                       {
-                               unsigned i;
-                               for (i = 0; i < inoutAttributes->NumberOfAttributes; ++i)
-                               {
-                                       CSSM_DB_ATTRIBUTE_DATA& data = inoutAttributes->AttributeData[i];
-                                       
-                                       unsigned j;
-                                       for (j = 0; j < data.NumberOfValues; ++j)
-                                       {
-                                               data.Value[j].Data = NULL;
-                                       }
-                                       
-                                       data.Value = NULL;
-                                       
-                                       if (data.Info.AttributeNameFormat == CSSM_DB_ATTRIBUTE_NAME_AS_STRING)
-                                       {
-                                               data.Info.Label.AttributeName = NULL;
-                                       }
-                               }
-                       }
-               }
-               
-               throw;
-       }
-       catch (...)
-       {
-               // clear all pointers so that nothing dangles back to the user
-               if (inoutData)
-               {
-                       inoutData->Data = NULL;
-               }
-               
-               if (inoutAttributes)
-               {
-                       unsigned i;
-                       for (i = 0; i < inoutAttributes->NumberOfAttributes; ++i)
-                       {
-                               CSSM_DB_ATTRIBUTE_DATA& data = inoutAttributes->AttributeData[i];
-                               
-                               unsigned j;
-                               for (j = 0; j < data.NumberOfValues; ++j)
-                               {
-                                       data.Value[j].Data = NULL;
-                               }
-                               
-                               data.Value = NULL;
-                               
-                               if (data.Info.AttributeNameFormat == CSSM_DB_ATTRIBUTE_NAME_AS_STRING)
-                               {
-                                       data.Info.Label.AttributeName = NULL;
-                               }
-                       }
-               }
-               
-               throw;
-       }
-       
-
-       // Don't free anything the trackingAllocator allocated when it is destructed.
-       anAllocator.commit();
-}
-
-// Return the index (0 though NumAttributes - 1) of the attribute
-// represented by inAttributeInfo
-
-#ifndef        NDEBUG
-#define LOG_NAME_AS_STRING_FAIL                
-#endif
-uint32
-MetaRecord::attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
-{
-       uint32 anIndex;
-       switch (inAttributeInfo.AttributeNameFormat)
-       {
-           case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
-               {
-                       string aName(inAttributeInfo.Label.AttributeName);
-                       assert(aName.size() < 500);             // MDS leak debug
-                       NameStringMap::const_iterator it = mNameStringMap.find(aName);
-                       if (it == mNameStringMap.end()) {
-                               #ifdef  LOG_NAME_AS_STRING_FAIL
-                               printf("NAME_AS_STRING failure; attrName %s\n", 
-                                       inAttributeInfo.Label.AttributeName);
-                               for(it = mNameStringMap.begin();
-                                   it != mNameStringMap.end();
-                                       it++) {
-                                               printf("name %s val %d\n", it->first.c_str(), it->second);
-                               }
-                               #endif
-                               CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
-                       }
-                       anIndex = it->second;
-                       break;
-               }
-           case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
-           {
-                       const CssmOid &aName = CssmOid::overlay(inAttributeInfo.Label.AttributeOID);
-                       NameOIDMap::const_iterator it = mNameOIDMap.find(aName);
-                       if (it == mNameOIDMap.end())
-                               CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
-                       anIndex = it->second;
-                       break;
-               }
-               case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
-               {
-                       uint32 aName = inAttributeInfo.Label.AttributeID;
-                       NameIntMap::const_iterator it = mNameIntMap.find(aName);
-                       if (it == mNameIntMap.end())
-                               CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
-                       anIndex = it->second;
-                       break;
-               }
-               default:
-                       CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
-                       break;
-       }
-
-       return anIndex;
-}
-
-const MetaAttribute &
-MetaRecord::metaAttribute(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
-{
-       return *mAttributeVector[attributeIndex(inAttributeInfo)];
-}
-
-// Create a packed record from the given inputs and the old packed record inReadSection.
-void
-MetaRecord::updateRecord(const ReadSection &inReadSection,
-                                                WriteSection &inWriteSection,
-                                                const CssmDbRecordAttributeData *inAttributes,
-                                                const CssmData *inData,
-                                                CSSM_DB_MODIFY_MODE inModifyMode) const
-{
-       TrackingAllocator anAllocator(Allocator::standard());
-
-       // modify the opaque data associated with the record
-       
-    uint32 aDataSize;
-       const uint8 *aDataData = NULL;
-    
-       if (inData)
-       {
-               // prepare to write new data
-        aDataSize = (uint32)inData->Length;
-               aDataData = inData->Data;
-       }
-    else
-       {
-               // prepare to copy old data
-        Range aDataRange = dataRange(inReadSection);
-       aDataSize = aDataRange.mSize;
-               if (aDataSize)
-                       aDataData = inReadSection.range(aDataRange);
-       }
-
-       // compute the data offset; this will keep a running total of the record size
-        uint32 anOffset = (uint32)(OffsetAttributeOffsets + AtomSize * mAttributeVector.size());
-       
-       // write the appropriate data to the new record
-       inWriteSection.put(OffsetDataSize, aDataSize);
-       if (aDataSize)
-               anOffset = inWriteSection.put(anOffset, aDataSize, aDataData);
-
-       // unpack the old attributes since some of them may need to be preserved
-       
-       auto_array<CssmDbAttributeData> attributeData(mAttributeVector.size());
-
-       for (size_t anAttributeIndex = mAttributeVector.size(); anAttributeIndex-- > 0; )
-       {
-               // unpack the old attribute data for this attribute index
-               const MetaAttribute &attribute = *mAttributeVector[anAttributeIndex];
-               attribute.unpackAttribute(inReadSection, anAllocator,
-                                                                 attributeData[anAttributeIndex].NumberOfValues,
-                                                                 attributeData[anAttributeIndex].Value);
-       }
-       
-       // retrieve the currrent semantic information
-       
-       uint32 oldSemanticInformation = semanticInformation(inReadSection);
-       
-       // process each input attribute as necessary, based on the modification mode
-       
-       if (inAttributes == NULL)
-       {
-               // make sure the modification mode is NONE, otherwise it's an
-               // error accordining to the spec
-               if (inModifyMode != CSSM_DB_MODIFY_ATTRIBUTE_NONE)
-                       CssmError::throwMe(CSSMERR_DL_INVALID_MODIFY_MODE);
-       }
-
-       else {
-       
-               // modify the semantic information
-
-               uint32 inSemanticInformation = inAttributes ? inAttributes->SemanticInformation : 0;
-
-               if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_ADD)
-                       oldSemanticInformation |= inSemanticInformation;
-
-               else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_DELETE)
-                       oldSemanticInformation &= ~inSemanticInformation;
-               
-               else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_REPLACE)
-                       oldSemanticInformation = inSemanticInformation;
-
-               uint32 anIndex = inAttributes->NumberOfAttributes;
-               if (anIndex > 0)
-                       Required(inAttributes->AttributeData);
-
-               // modify the attributes
-
-               while (anIndex-- > 0) {
-       
-                       const CssmDbAttributeData &anAttribute = inAttributes->at(anIndex);
-                       uint32 anAttributeIndex = attributeIndex(anAttribute.info());
-                       if (anAttribute.format() != mAttributeVector[anAttributeIndex]->attributeFormat())
-                               CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
-
-                       CssmDbAttributeData &oldAttribute = attributeData[anAttributeIndex];
-               
-                       // if the modify mode is ADD, merge new values with pre-existing values
-               
-                       if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_ADD)
-                               oldAttribute.add(anAttribute, anAllocator);
-
-                       // if the modify mode is DELETE, remove the indicated values, or remove
-                       // all values if none are specified
-
-                       else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_DELETE)
-                       {
-                               if (anAttribute.size() == 0)
-                                       oldAttribute.deleteValues(anAllocator);
-                               else
-                                       oldAttribute.deleteValues(anAttribute, anAllocator);
-                       }
-               
-                       // if the modify mode is REPLACE, then replace the specified values, or
-                       // delete all values if no values are specified
-               
-                       else if (inModifyMode == CSSM_DB_MODIFY_ATTRIBUTE_REPLACE)
-                       {
-                               oldAttribute.deleteValues(anAllocator);
-                               if (anAttribute.size() > 0)
-                                       oldAttribute.add(anAttribute, anAllocator);
-                               else
-                                       // The spec says "all values are deleted or the the value is replaced
-                                       // with the default" but doesn't say which. We could call the parsing
-                                       // module for the attribute here...if they were implemented! But instead
-                                       // we choose "all values are deleted" and leave it at that.
-                                       ;
-                       }
-               }
-       }
-
-       // write the resulting attributes into the new record
-       
-       inWriteSection.put(OffsetSemanticInformation, oldSemanticInformation);
-
-       for (uint32 anIndex = 0; anIndex < mAttributeVector.size(); ++anIndex)
-       {
-               const MetaAttribute &metaAttribute = *mAttributeVector[anIndex];
-               metaAttribute.packAttribute(inWriteSection, anOffset,
-                                                                   attributeData[anIndex].NumberOfValues,
-                                                                       attributeData[anIndex].Value);
-       }
-       
-       inWriteSection.put(OffsetRecordSize, anOffset);
-       inWriteSection.size(anOffset);
-}
-