os/persistentdata/persistentstorage/sql/SRC/Security/SqlSecurityImpl.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <s32buf.h>
    17 #include "SqlSecurityImpl.h"
    18 #include "SqlUtil.h"
    19 
    20 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    21 ////////////////////////////    CSqlSecurityPolicy implementation      ////////////////////////////////////////
    22 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    23 
    24 /**
    25 Casts aPolicyType parameter to an integer value, which is used as policy index.
    26 
    27 @param aPolicyType Security policy type: schema, write, read
    28 
    29 @return Security policy type casted to an integer value, which is used as a poicy index
    30 */
    31 inline TInt CSqlSecurityPolicy::PolicyType2Index(RSqlSecurityPolicy::TPolicyType aPolicyType)
    32 	{
    33 	return static_cast <TInt> (aPolicyType);
    34 	}
    35 
    36 /**
    37 Returns a pointer to the data of the current flat buffer cell. The pointer type is CSqlSecurityPolicy::TPolicyItem.
    38 
    39 @param aBegin Points to the beginning of flat buffer header
    40 @param aCurrent Points to a cell in the flat buffer header, to which data a pointer will be cast and returned.
    41 
    42 @return CSqlSecurityPolicy::TPolicyItem pointer, which can be used for R/W operations on the database security policy data.
    43 */
    44 inline CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::PolicyItemPtr(const RSqlBufFlat::TCell* aBegin, const RSqlBufFlat::TCell* aCurrent)
    45 	{
    46 	__ASSERT_DEBUG(aBegin != NULL && aCurrent != NULL, __SQLPANIC2(ESqlPanicBadArgument));
    47 	__ASSERT_DEBUG(aCurrent->iPos != 0, __SQLPANIC2(ESqlPanicBadArgument));
    48 	const TUint8* begin = reinterpret_cast <const TUint8*> (aBegin);
    49 	return reinterpret_cast <CSqlSecurityPolicy::TPolicyItem*> (const_cast <TUint8*> (begin) + aCurrent->iPos);
    50 	}
    51 
    52 /**
    53 Searhes the flat buffer for an entry, which "object type" and "object name" attributes match aObjectType and aObjectName parameters.
    54 If such entry exists, a pointer to the entry's data will be returned.
    55 
    56 @param aObjectType Database object type
    57 @param aObjectName Database object name
    58 
    59 @return A pointer to the data of an entry which "object type" and "object name" attributes match aObjectType and aObjectName parameters.
    60 		If no such entry exists, the function returns NULL.
    61 */
    62 const CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::FindPolicyItemPtr(RSqlSecurityPolicy::TObjectType aObjectType, 
    63 																	   		 const TDesC& aObjectName) const
    64 	{
    65 	const RSqlBufFlat::TCell* begin = iBufFlat.Header();
    66 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
    67 	const RSqlBufFlat::TCell* end = begin + Count();
    68 	const RSqlBufFlat::TCell* current = begin + CSqlSecurityPolicy::EDbPolicyIdx;//ignore default and database policiy types ("current" points before the first non-database policy)
    69 	while(++current < end)
    70 		{
    71 		if(current->iPos > 0 && current->Type() == (TInt)aObjectType) //if present and the same type as aObjectType
    72 			{
    73 			const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, current);
    74 			__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
    75 			__ASSERT_DEBUG(((current->Size() - sizeof(CSqlSecurityPolicy::TPolicyItem) - sizeof(TInt)) / sizeof(TUint16)) == item->NameSize(), __SQLPANIC(ESqlPanicInternalError));
    76 			if(::CompareNoCase16(aObjectName, TPtrC(item->NamePtr(), item->NameSize())) == 0)
    77 				{
    78 				return item;	
    79 				}
    80 			}
    81 		}
    82 	return NULL;
    83 	}
    84 		
    85 /**
    86 Standard, phase-one CSqlSecurityPolicy factory method.
    87 
    88 @param aDefaultPolicy Default security policy which will be used as a default replacement for all database and
    89                       database object security policies.
    90 
    91 @return A pointer to the created CSqlSecurityPolicy instance.
    92 
    93 @leave KErrNoMemory, an out of memory condition has occurred;
    94 */
    95 CSqlSecurityPolicy* CSqlSecurityPolicy::NewL(const TSecurityPolicy& aDefaultPolicy)
    96 	{
    97 	CSqlSecurityPolicy* self = CSqlSecurityPolicy::NewLC(aDefaultPolicy);
    98 	CleanupStack::Pop(self);
    99 	return self;
   100 	}
   101 
   102 /**
   103 Standard, phase-one CSqlSecurityPolicy factory method.
   104 
   105 @param aDefaultPolicy Default security policy which will be used as a default replacement for all database and
   106                       database object security policies.
   107 
   108 @return A pointer to the created CSqlSecurityPolicy instance.
   109 
   110 @leave KErrNoMemory, an out of memory condition has occurred;
   111 */
   112 CSqlSecurityPolicy* CSqlSecurityPolicy::NewLC(const TSecurityPolicy& aDefaultPolicy)
   113 	{
   114 	CSqlSecurityPolicy* self = new (ELeave) CSqlSecurityPolicy;
   115 	CleanupStack::PushL(self);
   116 	self->ConstructL(aDefaultPolicy);
   117 	return self;
   118 	}
   119 
   120 /**
   121 */
   122 CSqlSecurityPolicy::~CSqlSecurityPolicy()
   123 	{
   124 	iBufFlat.Close();
   125 	}
   126 
   127 /**
   128 @return A const reference to the flat buffer
   129 */
   130 const RSqlBufFlat& CSqlSecurityPolicy::BufFlat() const
   131 	{
   132 	return iBufFlat;
   133 	}
   134 
   135 /**
   136 @return A reference to the flat buffer
   137 */
   138 RSqlBufFlat& CSqlSecurityPolicy::BufFlat()
   139 	{
   140 	return iBufFlat;
   141 	}
   142 
   143 /**
   144 @return Database security policy entry count. This number is at least 2, because every CSqlSecurityPolicy object has by default
   145         one default security policy entry and one database security policy entry.
   146 */
   147 TInt CSqlSecurityPolicy::Count() const
   148 	{
   149 	const RSqlBufFlat::TCell* begin = iBufFlat.Header();
   150 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   151 	return *reinterpret_cast <const TInt*> (reinterpret_cast <const TUint8*> (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos);
   152 	}
   153 
   154 /**
   155 Sets the number of database security entries.
   156 */
   157 void CSqlSecurityPolicy::SetCount(TInt aCount)
   158 	{
   159 	__ASSERT_DEBUG(aCount >= 0, __SQLPANIC(ESqlPanicBadArgument));
   160 	RSqlBufFlat::TCell* begin = iBufFlat.Header();
   161 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   162 	*reinterpret_cast <TInt*> (reinterpret_cast <TUint8*> (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos) = aCount;
   163 	}
   164 
   165 /**
   166 Sets the default policy.
   167 */
   168 void CSqlSecurityPolicy::SetDefaultPolicy(const TSecurityPolicy& aPolicy)
   169 	{
   170 	RSqlBufFlat::TCell* begin = iBufFlat.Header();
   171 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   172 	CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx);
   173 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   174 	item->iPolicy[0] = aPolicy;
   175 	}
   176 	
   177 /**
   178 @param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, 
   179 				   RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy.
   180 @param aPolicy Security policy data used for setting the related database security policy.
   181 
   182 @panic SqlDb 4 In _DEBUG mode. Invalid policy type.
   183 */
   184 void CSqlSecurityPolicy::SetDbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy)
   185 	{
   186 	const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType);
   187 	__ASSERT_DEBUG((TUint)KPolicyIndex < EPolicyTypeCount, __SQLPANIC(ESqlPanicBadArgument));
   188 	RSqlBufFlat::TCell* begin = iBufFlat.Header();
   189 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   190 	CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx);
   191 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   192 	//KPolicyIndex value is tested at the beginning of the function
   193 	//coverity[overrun-local]
   194 	item->iPolicy[KPolicyIndex] = aPolicy;
   195 	}
   196 
   197 /**
   198 If there is no entry in the container for the object with aObjectName name, a new entry for this object will be 
   199 created and all object security policies will be initialized with the default security policy. aPolicyType object 
   200 policy will be reinitialized with aPolicy argument after that.
   201 
   202 If an entry for aObjectName object already exists, its aPolicyType security policy will be reinitialized with aPolicy
   203 argument.
   204 
   205 @param aObjectType Database object type. At the moment there is only one database object type allowed for use with
   206 					SetPolicy() - RSqlSecurityPolicy::ETable.
   207 @param aObjectName Database object name. It cannot be a null descriptor.
   208 @param aPolicyType Database object security policy type: RSqlSecurityPolicy::EReadPolicy, 
   209 				   RSqlSecurityPolicy::EWritePolicy.
   210 @param aPolicy Security policy data used for setting the related database object security policy type.
   211 
   212 @return KErrNone, operation completed successfully;
   213 		KErrNoMemory, an out of memory condition has occurred;
   214 		KErrNotSupported, the count of the security policies is too big.
   215 
   216 @panic SqlDb 4 In _DEBUG mode. Invalid policy type.
   217 @panic SqlDb 4 In _DEBUG mode. Invalid database object name (Null descriptor).
   218 */
   219 TInt CSqlSecurityPolicy::SetPolicy(RSqlSecurityPolicy::TObjectType aObjectType, const TDesC& aObjectName,
   220 							   	   RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy)
   221 	{
   222 	const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType);
   223 	__ASSERT_DEBUG((TUint)KPolicyIndex < EPolicyTypeCount, __SQLPANIC(ESqlPanicBadArgument));
   224 	__ASSERT_DEBUG(aObjectName.Length() > 0, __SQLPANIC(ESqlPanicBadArgument));
   225 	CSqlSecurityPolicy::TPolicyItem* item = const_cast <CSqlSecurityPolicy::TPolicyItem*> (FindPolicyItemPtr(aObjectType, aObjectName));
   226 	if(item)
   227 		{//There is a field in the flat buffer for {aObjectType, aObjectName}. Set the policy.
   228 		//KPolicyIndex value is tested at the beginning of the function
   229 		//coverity[overrun-local]
   230 		item->iPolicy[KPolicyIndex] = aPolicy;
   231 		return KErrNone;
   232 		}
   233 	//No field in the flat buffer for {aObjectType, aObjectName}.
   234 	TInt idx = Count();
   235 	if(idx >= iBufFlat.Count())
   236 		{
   237 		return KErrNotSupported;
   238 		}
   239 	//Create and fill a new CSqlSecurityPolicy::TPolicyItem object.
   240 	const TInt KPolicyDataLen = TPolicyItem::CalcSize(aObjectName.Length());
   241 	TUint8* buf = new TUint8[KPolicyDataLen];
   242 	if(!buf)
   243 		{
   244 		return KErrNoMemory;	
   245 		}
   246 	item = reinterpret_cast <CSqlSecurityPolicy::TPolicyItem*> (buf);
   247 	//coverity[DEADCODE]
   248 	//The ASSERT might be useful in catching future defect in this function
   249 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   250 	TSecurityPolicy defaultPolicy = DefaultPolicy();
   251 	for(TInt i=0;i<CSqlSecurityPolicy::EPolicyTypeCount;++i)
   252 		{
   253 		item->iPolicy[i] = defaultPolicy;
   254 		}
   255 	item->iPolicy[KPolicyIndex] = aPolicy;
   256 	//Set the object name length and the object name.
   257 	*item->NameSizePtr() = aObjectName.Length();
   258 	TPtr name(item->NamePtr(), item->NameSize());
   259 	name.Copy(aObjectName);
   260 	//Copy the item in iBufFlat and release the allocated memory.
   261 	TInt err = iBufFlat.SetField(idx, (TInt)aObjectType, item, KPolicyDataLen);
   262 	delete [] buf;
   263 	if(err == KErrNone)
   264 		{
   265 		SetCount(idx + 1);
   266 		}
   267 	return err;
   268 	}
   269 
   270 /**
   271 @return The default security policy.
   272 */
   273 TSecurityPolicy CSqlSecurityPolicy::DefaultPolicy() const
   274 	{
   275 	const RSqlBufFlat::TCell* begin = iBufFlat.Header();
   276 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   277 	const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx);
   278 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   279 	return item->iPolicy[0];
   280 	}
   281 	
   282 /**
   283 @param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, 
   284 				   RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy.
   285 
   286 Note: By default all database security policies will be initialized with the default security policy.
   287 
   288 @return The requested database security policy.
   289 				   
   290 @panic SqlDb 4 In _DEBUG mode. Invalid policy type.
   291 */
   292 TSecurityPolicy CSqlSecurityPolicy::DbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType) const
   293 	{
   294 	const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType);
   295 	__ASSERT_DEBUG((TUint)KPolicyIndex < EPolicyTypeCount, __SQLPANIC(ESqlPanicBadArgument));
   296 	const RSqlBufFlat::TCell* begin = iBufFlat.Header();
   297 	__ASSERT_DEBUG(begin != NULL, __SQLPANIC(ESqlPanicInternalError));
   298 	const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx);
   299 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   300 	//KPolicyIndex value is tested at the beginning of the function
   301 	//coverity[overrun-local]
   302 	return item->iPolicy[KPolicyIndex];
   303 	}
   304 	
   305 /**
   306 Searches the container for an entry belonging to an object with aObjectName name and aObjectType type. If such entry
   307 exists the method returns aPolicyType object security policy.
   308 
   309 If there is no entry for the object with aObjectName name, the default security policy will be returned.
   310 
   311 @param aObjectType Database object type. At the moment there is only one database object type allowed for use with
   312 					Policy() - RSqlSecurityPolicy::ETable.
   313 @param aObjectName Database object name. It cannot be a null descriptor.
   314 @param aPolicyType Database object security policy type: RSqlSecurityPolicy::ERead, RSqlSecurityPolicy::EWrite.
   315 
   316 Note: By default all database object security policies will be initialized with the default security policy. 
   317 	  
   318 @return The requested security policy
   319 
   320 @panic SqlDb 4 In _DEBUG mode. Invalid policy type.
   321 @panic SqlDb 4 In _DEBUG mode. Invalid onject name (Null descriptor).
   322 */
   323 TSecurityPolicy CSqlSecurityPolicy::Policy(RSqlSecurityPolicy::TObjectType aObjectType, 
   324 										   const TDesC& aObjectName, RSqlSecurityPolicy::TPolicyType aPolicyType)
   325 	{
   326 	const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType);
   327 	__ASSERT_DEBUG((TUint)KPolicyIndex < EPolicyTypeCount, __SQLPANIC(ESqlPanicBadArgument));
   328 	__ASSERT_DEBUG(aObjectName.Length() > 0, __SQLPANIC(ESqlPanicBadArgument));
   329 	const CSqlSecurityPolicy::TPolicyItem* item = FindPolicyItemPtr(aObjectType, aObjectName);
   330 	//KPolicyIndex value is tested at the beginning of the function
   331 	//coverity[overrun-local]
   332 	return item ? item->iPolicy[KPolicyIndex] : DefaultPolicy();
   333 	}
   334 
   335 /**
   336 */
   337 CSqlSecurityPolicy::CSqlSecurityPolicy()
   338 	{
   339 	}
   340 
   341 /**
   342 Standard, phase-two CSqlSecurityPolicy construction method.
   343 
   344 Note: By default all database security policies will be initialized with the default security policy.
   345 
   346 @param aDefaultPolicy Security policy data used for setting the default database security policy and
   347                       database security policies.
   348 
   349 @leave KErrNoMemory, an out of memory condition has occurred;
   350 */
   351 void CSqlSecurityPolicy::ConstructL(const TSecurityPolicy& aDefaultPolicy)
   352 	{
   353 	//Create the policy flat buffer.
   354 	__SQLLEAVE_IF_ERROR(iBufFlat.SetCount(CSqlSecurityPolicy::EMaxCount));
   355 	//Reserve places for the default policy and database policies.
   356 	CSqlSecurityPolicy::TPolicyItem item;
   357 	for(TInt i=0;i<CSqlSecurityPolicy::EPolicyTypeCount;++i)
   358 		{
   359 		item.iPolicy[i]	= aDefaultPolicy;
   360 		}
   361 	TInt count = CSqlSecurityPolicy::EDbPolicyIdx + 1;//count + default policy + database policy;
   362 	__SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::ECountIdx, 0, &count, sizeof(count)));
   363 	__SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::EDefaultPolicyIdx, 0, &item, sizeof(item) - sizeof(TSecurityPolicy) * (CSqlSecurityPolicy::EPolicyTypeCount - 1)));
   364 	__SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::EDbPolicyIdx, 0, &item, sizeof(item)));
   365 	}
   366 
   367 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   368 ////////////////////           TSqlSecurityPolicyIterator  implementation        //////////////////////////////
   369 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   370 
   371 /**
   372 @param aSecuritySettings Const reference to CSqlSecurityPolicy object on which content the iterator will work.
   373 */
   374 TSqlSecurityPolicyIterator::TSqlSecurityPolicyIterator(const CSqlSecurityPolicy& aSqlSecurityPolicy) :
   375 	iBegin(aSqlSecurityPolicy.iBufFlat.Header()),
   376 	iCurrent(iBegin + CSqlSecurityPolicy::EDbPolicyIdx),//ignore the default and database policies
   377 	iEnd(iBegin + aSqlSecurityPolicy.Count()),
   378 	iCurPolicyIdx(CSqlSecurityPolicy::EPolicyTypeCount)
   379 	{
   380 	__ASSERT_DEBUG(iBegin != NULL, __SQLPANIC(ESqlPanicInternalError));
   381 	}
   382 	
   383 /**
   384 Moves the iterator one step forward and gives a read-only access to the next database object security policy.
   385 
   386 @param aObjectType Output parameter. Next database object type, if the iteration was successful.
   387 @param aObjectName Output parameter. Set to point to the next database object name, if the iteration was successful.
   388 @param aPolicyType Output parameter. Next database object security policy type, if the iteration was successful.
   389 @param aPolicy     Output parameter. Next database object security policy, if the iteration was successful.
   390 
   391 @return Non-zero - successful iteration step, zero otherwise (no more security policies in the CSqlSecurityPolicy container).
   392 */
   393 TBool TSqlSecurityPolicyIterator::Next(RSqlSecurityPolicy::TObjectType& aObjectType, TPtrC& aObjectName, 
   394 									   RSqlSecurityPolicy::TPolicyType& aPolicyType, TSecurityPolicy& aPolicy)
   395 	{
   396 	if(++iCurPolicyIdx >= CSqlSecurityPolicy::EPolicyTypeCount)
   397 		{
   398 		iCurPolicyIdx = static_cast <TInt> (RSqlSecurityPolicy::EReadPolicy);
   399 		if(++iCurrent >= iEnd)
   400 			{
   401 			return EFalse;	
   402 			}
   403 		}
   404 	const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(iBegin, iCurrent);
   405 	__ASSERT_DEBUG(item != NULL, __SQLPANIC(ESqlPanicInternalError));
   406 	aObjectType = static_cast <RSqlSecurityPolicy::TObjectType> (iCurrent->Type());
   407 	aPolicyType = static_cast <RSqlSecurityPolicy::TPolicyType> (iCurPolicyIdx);
   408 	aPolicy = item->iPolicy[iCurPolicyIdx];
   409 	aObjectName.Set(item->NamePtr(), item->NameSize());
   410 	return ETrue;		
   411 	}