persistentstorage/dbms/sdbms/Sd_PolicyProxy2.cpp
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2004-2009 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 // CPolicyProxy class
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "SD_STD.H"
       
    19 #include "Sd_PolicyProxy.h"
       
    20 #include "D32SQL.H"
       
    21 
       
    22 using namespace DBSC;
       
    23 
       
    24 /**
       
    25 TDbsFunction enum value is used as an index in KDbsFunc2SecurityPolicyMask array.
       
    26 For each TDbsFunction enum value there is a set of security policies,
       
    27 which have to be satisified by the caller capabilities (at least one of them) - 
       
    28 before the related operation to be executed.
       
    29 @internalComponent
       
    30 */
       
    31 static const TUint8 KDbsFunc2SecurityPolicyMask[EDbsLast] = 
       
    32 	{
       
    33 /*EDbsResourceMark*/		EPTNone,
       
    34 /*EDbsResourceCheck*/		EPTNone,
       
    35 /*EDbsResourceCount*/		EPTNone,
       
    36 /*EDbsSetHeapFailure*/		EPTNone,
       
    37 /*EDbsOpenDatabase*/		EPTRead | EPTWrite | EPTSchema, //---The caller capabilities will be asserted later, when the db security uid is known
       
    38 /*EDbsClose*/				EPTNone,						//---EDbsClose may be used to close every possible type of server side dbms object
       
    39 /*EDbsDatabaseAuthenticate*/EPTNone,						//---Not supported for secure shared databases
       
    40 /*EDbsDatabaseDestroy*/		EPTSchema,						//---Only admin can destroy the database
       
    41 /*EDbsDatabaseBegin*/		EPTRead | EPTWrite | EPTSchema,	//---Begin transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations
       
    42 /*EDbsDatabaseCommit*/		EPTRead | EPTWrite | EPTSchema,	//---Commit transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations
       
    43 /*EDbsDatabaseRollback*/	EPTRead | EPTWrite | EPTSchema,	//---Rollback transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations
       
    44 /*EDbsDatabaseProperty*/	EPTNone,
       
    45 /*EDbsDatabaseCreateTable*/	EPTSchema,
       
    46 /*EDbsDatabaseTables*/		EPTNone,
       
    47 /*EDbsDatabaseColumns*/		EPTNone,
       
    48 /*EDbsDatabaseIndexes*/		EPTNone,
       
    49 /*EDbsDatabaseKeys*/		EPTNone,
       
    50 /*EDbsDatabaseOpenObserver*/EPTNone,
       
    51 /*EDbsDatabaseOpenUtility*/	EPTWrite, 						//---Compact/Recover operations
       
    52 /*EDbsDatabaseOpenDropTable*/EPTSchema,
       
    53 /*EDbsDatabaseOpenAlterTable*/EPTSchema,					
       
    54 /*EDbsDatabaseOpenCreateIndex*/EPTSchema,
       
    55 /*EDbsDatabaseOpenDropIndex*/EPTSchema,
       
    56 /*EDbsDatabaseExecute*/		EPTWrite | EPTSchema,			//---either CREATE/DROP/ALTER database operations or INSERT/UPDATE/DELETE table operations. An additional caller capabilities check will be made after the parsing of the sql string.
       
    57 /*EDbsDatabasePrepareView*/	EPTRead,						//---"SELECT" sql string
       
    58 /*EDbsDatabaseOpenTable*/	EPTRead | EPTWrite,				//---If the caller neither have capabilities for read or write table security policies, then the the caller cannot open the table.
       
    59 /*EDbsObserverNotify*/		EPTNone,
       
    60 /*EDbsObserverCancel*/		EPTNone,
       
    61 /*EDbsIncrementalNext*/		EPTNone,
       
    62 /*EDbsCursorColumnTypes*/	EPTNone,
       
    63 /*EDbsCursorReset*/			EPTNone,						//---Moves the cursor at the beginning of the table/dataset
       
    64 /*EDbsCursorEvaluate*/		EPTNone,
       
    65 /*EDbsCursorUnevaluated*/	EPTNone,
       
    66 /*EDbsCursorSetIndex*/		EPTRead,
       
    67 /*EDbsCursorSeek*/			EPTRead,
       
    68 /*EDbsCursorAtBeginning*/	EPTNone,
       
    69 /*EDbsCursorAtEnd*/			EPTNone,
       
    70 /*EDbsCursorAtRow*/			EPTNone,
       
    71 /*EDbsCursorCount*/			EPTRead | EPTWrite,
       
    72 /*EDbsCursorGotoPos*/		EPTRead,
       
    73 /*EDbsCursorBookmark*/		EPTRead,
       
    74 /*EDbsCursorGotoBookmark*/	EPTRead,
       
    75 /*EDbsCursorGet*/			EPTRead,
       
    76 /*EDbsCursorInsert*/		EPTWrite,
       
    77 /*EDbsCursorUpdate*/		EPTWrite,
       
    78 /*EDbsCursorRetrieveRow*/	EPTNone,						//---Used by "Insert" operations sometime
       
    79 /*EDbsCursorCancel*/		EPTNone,
       
    80 /*EDbsCursorPut*/			EPTWrite,
       
    81 /*EDbsCursorDelete*/		EPTWrite,
       
    82 /*EDbsCursorColumns*/		EPTNone,
       
    83 /*EDbsCursorColumnDef*/		EPTNone,
       
    84 /*EDbsCursorSetNull*/		EPTWrite,
       
    85 /*EDbsCursorColumnSize*/	EPTNone,
       
    86 /*EDbsCursorColumnSource*/	EPTRead,						//---Used for large BLOB fields - read ops
       
    87 /*EDbsCursorColumnSink*/	EPTWrite,						//---Used for large BLOB fields - write ops
       
    88 /*EDbsCursorOpenConstraint*/EPTRead,
       
    89 /*EDbsCursorMatch*/			EPTRead,
       
    90 /*EDbsCursorFind*/			EPTRead,
       
    91 /*EDbsStreamRead*/			EPTNone,
       
    92 /*EDbsStreamWrite*/			EPTNone,
       
    93 /*EDbsStreamSize*/			EPTNone,
       
    94 /*EDbsStreamSynch*/			EPTNone,
       
    95 /*EDbsCreateDatabase*/		EPTSchema,
       
    96 /*EDbsDatabaseList*/		EPTNone,
       
    97 /*EDbsCopyDatabase*/		EPTSchema,
       
    98 /*EDbsDeleteDatabase*/		EPTSchema,
       
    99 /*EDbsGetSecurityPolicy*/	EPTNone,
       
   100 /*EDbsReserveDriveSpace*/	EPTNone,
       
   101 /*EDbsFreeReservedSpace*/	EPTNone,
       
   102 /*EDbsReserveGetAccess*/	EPTNone,
       
   103 /*EDbsReserveReleaseAccess*/EPTNone,
       
   104 /*EDbsGetBackupPath*/		EPTNone,			
       
   105 /*EDbsGetBackupPaths*/		EPTNone
       
   106 	};
       
   107 
       
   108 /**
       
   109 This function returns bit-field mask value, containing security policies types (R/W/S)
       
   110 Each security policy contains a set of Capabilities/SID/VID.
       
   111 In order particular database operation to be executed, the caller Capabilities/SID/VID have
       
   112 to be checked against security policy Capabilities/SID/VID.
       
   113 Don't forget to map new DBMS functions here!
       
   114 @param aFunction DBMS server function code
       
   115 @return An integer mask with a set of security policy types. The caller has to satisfy at least 
       
   116         one of of them.
       
   117 */
       
   118 static TUint DbsFunction2PolicyMask(TDbsFunction aFunction)
       
   119 	{
       
   120 	__ASSERT(aFunction < EDbsLast);
       
   121 	return KDbsFunc2SecurityPolicyMask[aFunction];
       
   122 	}
       
   123 
       
   124 /**
       
   125 Extracts DBMS server function code from aMessage argument.
       
   126 @param aMessage DBMS server message
       
   127 @return DBMS server function code
       
   128 @internalComponent
       
   129 */
       
   130 static TDbsFunction Message2Function(const RMessage2& aMessage)
       
   131 	{
       
   132 	TDbsFunction func = ::DbsFunction(aMessage.Function());
       
   133 	return static_cast <TDbsFunction> (func & ~KDbsObjectReturn);
       
   134 	}
       
   135 
       
   136 /**
       
   137 */
       
   138 inline CPolicyProxy::CPolicyProxy(RFs& aFs):iFs(aFs)
       
   139 	{
       
   140 	}
       
   141 
       
   142 /**
       
   143 Standard phase-one factory method for CPolicyProxy instances.
       
   144 @param aFs A file server session instance
       
   145 @param aPrivatePath DBMS server private data path
       
   146 @return A pointer to the created CPolicyProxy instance.
       
   147 @leave KErrNoMemory
       
   148 */
       
   149 CPolicyProxy* CPolicyProxy::NewL(RFs& aFs,const TDesC& aPrivatePath)
       
   150 	{
       
   151 	CPolicyProxy* self = new (ELeave) CPolicyProxy(aFs);
       
   152 	CleanupStack::PushL(self);
       
   153 	self->ConstructL(aPrivatePath);
       
   154 	CleanupStack::Pop(self);
       
   155 	return self;
       
   156 	}
       
   157 
       
   158 /**
       
   159 */
       
   160 CPolicyProxy::~CPolicyProxy()
       
   161 	{
       
   162 	if(iPolicySpace) //iPolicySpace can be NULL in OOM tests
       
   163 		{
       
   164 		iPolicySpace->Release();
       
   165 		}
       
   166 	}
       
   167 
       
   168 /**
       
   169 Returns requested database security policy interface, which cannot be NULL.
       
   170 @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID
       
   171 @return A const pointer to the related UID security policy object.
       
   172 */
       
   173 const MPolicy* CPolicyProxy::DbPolicyL(const TDbPolicyRequest& aDbPolicyRequest)
       
   174 	{
       
   175 	return iPolicySpace->DbPolicyL(aDbPolicyRequest);
       
   176 	}
       
   177 
       
   178 /**
       
   179 Returns requested table security policy interface, which cannot be NULL.
       
   180 @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID
       
   181 @param aTblName Database table name
       
   182 @return A const pointer to the related table security policy object.
       
   183 */
       
   184 const MPolicy* CPolicyProxy::TblPolicyL(const TDbPolicyRequest& aDbPolicyRequest, 
       
   185 										const TDesC& aTblName)
       
   186 	{
       
   187 	return iPolicySpace->TblPolicyL(aDbPolicyRequest, aTblName);
       
   188 	}
       
   189 
       
   190 /**
       
   191 This method is used to get the SQL related MPolicy interface and the related security 
       
   192 policy type.
       
   193 If aUPRequest.iRqAccess is EATNonSecure, then the default security policy will be returned.
       
   194 Currently the DBMS can process the following SQL strings:
       
   195 1)DDL  - CREATE/DROP/ALTER SQL statements - EPTSchema database access level.
       
   196 2)DML  - INSERT/UPDATE/DELETE SQL statements. Only one table can be put after the "FROM"
       
   197          SQL keyword. EPTWrite table access level.
       
   198 3)QUERY- SELECT SQL statements. Only one table can be out after the "FROM" SQL keyword.
       
   199          EPTRead table access level.
       
   200 @param aDbPolicyRequest A const reference to an object packing security policy uid and the request type:
       
   201                   secure/non-secure.
       
   202 @param aSql SQL string
       
   203 @param aPolicyType An output parameter, referencing the location, where the policy type will be stored.
       
   204 @return A const pointer to the related policy interface. It cannot be NULL, and must not be deleted.
       
   205 @leave One of the system-wide error codes.
       
   206 */
       
   207 const MPolicy* CPolicyProxy::SqlPolicyL(const TDbPolicyRequest& aDbPolicyRequest, const TDesC& aSql, 
       
   208 										TPolicyType& aPolicyType)
       
   209 	{
       
   210 	const MPolicy* policy = NULL;
       
   211 	aPolicyType = EPTNone;
       
   212 	//Get table name and sql type.
       
   213 	TSqlParser2 sqlParser;
       
   214 	sqlParser.ParseL(aSql);
       
   215 	Sql::TStatementType sqlType = sqlParser.StatementType();
       
   216 	//Reinitialize aSqlSecurityPolicyData, which is sql type dependent.
       
   217 	switch(sqlType)
       
   218 		{
       
   219 		case Sql::EDDL:
       
   220 			//Database EPTSchema access level
       
   221 			policy = DbPolicyL(aDbPolicyRequest);
       
   222 			aPolicyType = EPTSchema;
       
   223 			break;
       
   224 		case Sql::EDML:
       
   225 		default:
       
   226 			{//Table access level - EPTRead or EPTWrite.
       
   227 			const TDesC& tblName = sqlParser.TableName();
       
   228 			__ASSERT(tblName.Length() > 0);
       
   229 			TBuf<KDbMaxName> tblNameBuf;
       
   230 			tblNameBuf.Copy(tblName);
       
   231 			policy = TblPolicyL(aDbPolicyRequest, tblNameBuf);
       
   232 			aPolicyType = sqlType == Sql::EDML ? EPTWrite : EPTRead;
       
   233 			}
       
   234 			break;
       
   235 		}
       
   236 	__ASSERT(policy);
       
   237 	return policy;
       
   238 	}
       
   239 
       
   240 /**
       
   241 Returns backup&restore SID for the databases, the access to which is controlled by the
       
   242 security policy, identified by aDbUid parameter.
       
   243 @param aDbUid Domain UID
       
   244 @return Backup&restore SID for the supplied domain UID
       
   245 @leave KErrArgument if there is no security policy domain for the supplied UID.
       
   246 */
       
   247 TSecureId CPolicyProxy::BackupSIDL(TUid aDbUid) const
       
   248 	{
       
   249 	return iPolicySpace->BackupSIDL(aDbUid);
       
   250 	}
       
   251 	
       
   252 /**
       
   253 Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy
       
   254 managed by aPolicy parameter. The caller has to satisfy at least one of the related to 
       
   255 the message security policies.
       
   256 @param aMessage An object whith caller capabilities/SID/VID, which has to be checked.
       
   257 @param aPolicy A const reference to the security policy object. 
       
   258 @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation
       
   259 */
       
   260 void CPolicyProxy::CheckL(const RMessage2& aMessage, const MPolicy& aPolicy) const
       
   261 	{
       
   262 	TDbsFunction func = ::Message2Function(aMessage);
       
   263 	TUint mask = ::DbsFunction2PolicyMask(func);
       
   264 	if(mask != EPTNone)
       
   265 		{
       
   266 		for(TInt c=0;c<KPolicyTypesCount;++c)
       
   267 			{
       
   268 			TPolicyType policyType = static_cast <TPolicyType> (1 << c);
       
   269 			if(policyType & mask)
       
   270 				{
       
   271 				if(aPolicy.Check(aMessage, policyType))
       
   272 					{
       
   273 					return;
       
   274 					}
       
   275 				}
       
   276 			}
       
   277 		__LEAVE(KErrPermissionDenied);
       
   278 		}
       
   279 	}
       
   280 
       
   281 /**
       
   282 Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy
       
   283 managed by aPolicy parameter. 
       
   284 @param aPolicyType The policy type, against which the check has to be done.
       
   285 @param aMessage An object whith caller capabilities/SID/VID, which has to be checked.
       
   286 @param aPolicy A const reference to the security policy object. 
       
   287 @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation
       
   288 */
       
   289 void CPolicyProxy::CheckL(TPolicyType aPolicyType, const RMessage2& aMessage, const MPolicy& aPolicy) const
       
   290 	{
       
   291 	if(aPolicyType != EPTNone)
       
   292 		{
       
   293 		if(!aPolicy.Check(aMessage, aPolicyType))
       
   294 			{
       
   295 			__LEAVE(KErrPermissionDenied);
       
   296 			}
       
   297 		}
       
   298 	}
       
   299 
       
   300 /**
       
   301 Standard phase-two construction method for CPolicyProxy instances.
       
   302 @param aPrivatePath DBMS server private data path
       
   303 @leave KErrNoMemory
       
   304 */
       
   305 void CPolicyProxy::ConstructL(const TDesC& aPrivatePath)
       
   306 	{
       
   307 	iPolicySpace = TPolicySpaceFactory::NewPolicySpaceL(iFs, aPrivatePath);
       
   308 	}
       
   309