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