diff -r 000000000000 -r 08ec8eefde2f persistentstorage/sql/SRC/Security/SqlSecurityImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/SRC/Security/SqlSecurityImpl.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,414 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "SqlSecurityImpl.h" +#include "SqlUtil.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////// CSqlSecurityPolicy implementation //////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** +Casts aPolicyType parameter to an integer value, which is used as policy index. + +@param aPolicyType Security policy type: schema, write, read + +@return Security policy type casted to an integer value, which is used as a poicy index +*/ +inline TInt CSqlSecurityPolicy::PolicyType2Index(RSqlSecurityPolicy::TPolicyType aPolicyType) + { + return static_cast (aPolicyType); + } + +/** +Returns a pointer to the data of the current flat buffer cell. The pointer type is CSqlSecurityPolicy::TPolicyItem. + +@param aBegin Points to the beginning of flat buffer header +@param aCurrent Points to a cell in the flat buffer header, to which data a pointer will be cast and returned. + +@return CSqlSecurityPolicy::TPolicyItem pointer, which can be used for R/W operations on the database security policy data. +*/ +inline CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::PolicyItemPtr(const RSqlBufFlat::TCell* aBegin, const RSqlBufFlat::TCell* aCurrent) + { + __SQLASSERT(aBegin != NULL && aCurrent != NULL, ESqlPanicBadArgument); + __SQLASSERT(aCurrent->iPos != 0, ESqlPanicBadArgument); + const TUint8* begin = reinterpret_cast (aBegin); + return reinterpret_cast (const_cast (begin) + aCurrent->iPos); + } + +/** +Searhes the flat buffer for an entry, which "object type" and "object name" attributes match aObjectType and aObjectName parameters. +If such entry exists, a pointer to the entry's data will be returned. + +@param aObjectType Database object type +@param aObjectName Database object name + +@return A pointer to the data of an entry which "object type" and "object name" attributes match aObjectType and aObjectName parameters. + If no such entry exists, the function returns NULL. +*/ +const CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::FindPolicyItemPtr(RSqlSecurityPolicy::TObjectType aObjectType, + const TDesC& aObjectName) const + { + const RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + const RSqlBufFlat::TCell* end = begin + Count(); + const RSqlBufFlat::TCell* current = begin + CSqlSecurityPolicy::EDbPolicyIdx;//ignore default and database policiy types ("current" points before the first non-database policy) + while(++current < end) + { + if(current->iPos > 0 && current->Type() == (TInt)aObjectType) //if present and the same type as aObjectType + { + const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, current); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + __SQLASSERT(((current->Size() - sizeof(CSqlSecurityPolicy::TPolicyItem) - sizeof(TInt)) / sizeof(TUint16)) == item->NameSize(), ESqlPanicInternalError); + if(::CompareNoCase16(aObjectName, TPtrC(item->NamePtr(), item->NameSize())) == 0) + { + return item; + } + } + } + return NULL; + } + +/** +Standard, phase-one CSqlSecurityPolicy factory method. + +@param aDefaultPolicy Default security policy which will be used as a default replacement for all database and + database object security policies. + +@return A pointer to the created CSqlSecurityPolicy instance. + +@leave KErrNoMemory, an out of memory condition has occurred; +*/ +CSqlSecurityPolicy* CSqlSecurityPolicy::NewL(const TSecurityPolicy& aDefaultPolicy) + { + CSqlSecurityPolicy* self = CSqlSecurityPolicy::NewLC(aDefaultPolicy); + CleanupStack::Pop(self); + return self; + } + +/** +Standard, phase-one CSqlSecurityPolicy factory method. + +@param aDefaultPolicy Default security policy which will be used as a default replacement for all database and + database object security policies. + +@return A pointer to the created CSqlSecurityPolicy instance. + +@leave KErrNoMemory, an out of memory condition has occurred; +*/ +CSqlSecurityPolicy* CSqlSecurityPolicy::NewLC(const TSecurityPolicy& aDefaultPolicy) + { + CSqlSecurityPolicy* self = new (ELeave) CSqlSecurityPolicy; + CleanupStack::PushL(self); + self->ConstructL(aDefaultPolicy); + return self; + } + +/** +*/ +CSqlSecurityPolicy::~CSqlSecurityPolicy() + { + iBufFlat.Close(); + } + +/** +@return A const reference to the flat buffer +*/ +const RSqlBufFlat& CSqlSecurityPolicy::BufFlat() const + { + return iBufFlat; + } + +/** +@return A reference to the flat buffer +*/ +RSqlBufFlat& CSqlSecurityPolicy::BufFlat() + { + return iBufFlat; + } + +/** +@return Database security policy entry count. This number is at least 2, because every CSqlSecurityPolicy object has by default + one default security policy entry and one database security policy entry. +*/ +TInt CSqlSecurityPolicy::Count() const + { + const RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + return *reinterpret_cast (reinterpret_cast (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos); + } + +/** +Sets the number of database security entries. +*/ +void CSqlSecurityPolicy::SetCount(TInt aCount) + { + __SQLASSERT(aCount >= 0, ESqlPanicBadArgument); + RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + *reinterpret_cast (reinterpret_cast (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos) = aCount; + } + +/** +Sets the default policy. +*/ +void CSqlSecurityPolicy::SetDefaultPolicy(const TSecurityPolicy& aPolicy) + { + RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + item->iPolicy[0] = aPolicy; + } + +/** +@param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, + RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy. +@param aPolicy Security policy data used for setting the related database security policy. + +@return KErrNone + +@panic SqlDb 4 In _DEBUG mode. Invalid policy type. +*/ +TInt CSqlSecurityPolicy::SetDbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy) + { + const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); + __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); + RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + //KPolicyIndex value is tested at the beginning of the function + //coverity[overrun-local] + item->iPolicy[KPolicyIndex] = aPolicy; + return KErrNone; + } + +/** +If there is no entry in the container for the object with aObjectName name, a new entry for this object will be +created and all object security policies will be initialized with the default security policy. aPolicyType object +policy will be reinitialized with aPolicy argument after that. + +If an entry for aObjectName object already exists, its aPolicyType security policy will be reinitialized with aPolicy +argument. + +@param aObjectType Database object type. At the moment there is only one database object type allowed for use with + SetPolicy() - RSqlSecurityPolicy::ETable. +@param aObjectName Database object name. It cannot be a null descriptor. +@param aPolicyType Database object security policy type: RSqlSecurityPolicy::EReadPolicy, + RSqlSecurityPolicy::EWritePolicy. +@param aPolicy Security policy data used for setting the related database object security policy type. + +@return KErrNone, operation completed successfully; + KErrNoMemory, an out of memory condition has occurred; + KErrNotSupported, the count of the security policies is too big. + +@panic SqlDb 4 In _DEBUG mode. Invalid policy type. +@panic SqlDb 4 In _DEBUG mode. Invalid database object name (Null descriptor). +*/ +TInt CSqlSecurityPolicy::SetPolicy(RSqlSecurityPolicy::TObjectType aObjectType, const TDesC& aObjectName, + RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy) + { + const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); + __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); + __SQLASSERT(aObjectName.Length() > 0, ESqlPanicBadArgument); + CSqlSecurityPolicy::TPolicyItem* item = const_cast (FindPolicyItemPtr(aObjectType, aObjectName)); + if(item) + {//There is a field in the flat buffer for {aObjectType, aObjectName}. Set the policy. + //KPolicyIndex value is tested at the beginning of the function + //coverity[overrun-local] + item->iPolicy[KPolicyIndex] = aPolicy; + return KErrNone; + } + //No field in the flat buffer for {aObjectType, aObjectName}. + TInt idx = Count(); + if(idx >= iBufFlat.Count()) + { + return KErrNotSupported; + } + //Create and fill a new CSqlSecurityPolicy::TPolicyItem object. + const TInt KPolicyDataLen = TPolicyItem::CalcSize(aObjectName.Length()); + TUint8* buf = new TUint8[KPolicyDataLen]; + if(!buf) + { + return KErrNoMemory; + } + item = reinterpret_cast (buf); + //coverity[DEADCODE] + //The ASSERT might be useful in catching future defect in this function + __SQLASSERT(item != NULL, ESqlPanicInternalError); + TSecurityPolicy defaultPolicy = DefaultPolicy(); + for(TInt i=0;iiPolicy[i] = defaultPolicy; + } + item->iPolicy[KPolicyIndex] = aPolicy; + //Set the object name length and the object name. + *item->NameSizePtr() = aObjectName.Length(); + TPtr name(item->NamePtr(), item->NameSize()); + name.Copy(aObjectName); + //Copy the item in iBufFlat and release the allocated memory. + TInt err = iBufFlat.SetField(idx, (TInt)aObjectType, item, KPolicyDataLen); + delete [] buf; + if(err == KErrNone) + { + SetCount(idx + 1); + } + return err; + } + +/** +@return The default security policy. +*/ +TSecurityPolicy CSqlSecurityPolicy::DefaultPolicy() const + { + const RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + return item->iPolicy[0]; + } + +/** +@param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, + RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy. + +Note: By default all database security policies will be initialized with the default security policy. + +@return The requested database security policy. + +@panic SqlDb 4 In _DEBUG mode. Invalid policy type. +*/ +TSecurityPolicy CSqlSecurityPolicy::DbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType) const + { + const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); + __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); + const RSqlBufFlat::TCell* begin = iBufFlat.Header(); + __SQLASSERT(begin != NULL, ESqlPanicInternalError); + const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + //KPolicyIndex value is tested at the beginning of the function + //coverity[overrun-local] + return item->iPolicy[KPolicyIndex]; + } + +/** +Searches the container for an entry belonging to an object with aObjectName name and aObjectType type. If such entry +exists the method returns aPolicyType object security policy. + +If there is no entry for the object with aObjectName name, the default security policy will be returned. + +@param aObjectType Database object type. At the moment there is only one database object type allowed for use with + Policy() - RSqlSecurityPolicy::ETable. +@param aObjectName Database object name. It cannot be a null descriptor. +@param aPolicyType Database object security policy type: RSqlSecurityPolicy::ERead, RSqlSecurityPolicy::EWrite. + +Note: By default all database object security policies will be initialized with the default security policy. + +@return The requested security policy + +@panic SqlDb 4 In _DEBUG mode. Invalid policy type. +@panic SqlDb 4 In _DEBUG mode. Invalid onject name (Null descriptor). +*/ +TSecurityPolicy CSqlSecurityPolicy::Policy(RSqlSecurityPolicy::TObjectType aObjectType, + const TDesC& aObjectName, RSqlSecurityPolicy::TPolicyType aPolicyType) + { + const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); + __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); + __SQLASSERT(aObjectName.Length() > 0, ESqlPanicBadArgument); + const CSqlSecurityPolicy::TPolicyItem* item = FindPolicyItemPtr(aObjectType, aObjectName); + //KPolicyIndex value is tested at the beginning of the function + //coverity[overrun-local] + return item ? item->iPolicy[KPolicyIndex] : DefaultPolicy(); + } + +/** +*/ +CSqlSecurityPolicy::CSqlSecurityPolicy() + { + } + +/** +Standard, phase-two CSqlSecurityPolicy construction method. + +Note: By default all database security policies will be initialized with the default security policy. + +@param aDefaultPolicy Security policy data used for setting the default database security policy and + database security policies. + +@leave KErrNoMemory, an out of memory condition has occurred; +*/ +void CSqlSecurityPolicy::ConstructL(const TSecurityPolicy& aDefaultPolicy) + { + //Create the policy flat buffer. + __SQLLEAVE_IF_ERROR(iBufFlat.SetCount(CSqlSecurityPolicy::EMaxCount)); + //Reserve places for the default policy and database policies. + CSqlSecurityPolicy::TPolicyItem item; + for(TInt i=0;i= CSqlSecurityPolicy::EPolicyTypeCount) + { + iCurPolicyIdx = static_cast (RSqlSecurityPolicy::EReadPolicy); + if(++iCurrent >= iEnd) + { + return EFalse; + } + } + const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(iBegin, iCurrent); + __SQLASSERT(item != NULL, ESqlPanicInternalError); + aObjectType = static_cast (iCurrent->Type()); + aPolicyType = static_cast (iCurPolicyIdx); + aPolicy = item->iPolicy[iCurPolicyIdx]; + aObjectName.Set(item->NamePtr(), item->NameSize()); + return ETrue; + }