sl@0: // Copyright (c) 2004-2009 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: // CPolicyProxy class sl@0: // sl@0: // sl@0: sl@0: #include "SD_STD.H" sl@0: #include "Sd_PolicyProxy.h" sl@0: #include "D32SQL.H" sl@0: sl@0: using namespace DBSC; sl@0: sl@0: /** sl@0: TDbsFunction enum value is used as an index in KDbsFunc2SecurityPolicyMask array. sl@0: For each TDbsFunction enum value there is a set of security policies, sl@0: which have to be satisified by the caller capabilities (at least one of them) - sl@0: before the related operation to be executed. sl@0: @internalComponent sl@0: */ sl@0: static const TUint8 KDbsFunc2SecurityPolicyMask[EDbsLast] = sl@0: { sl@0: /*EDbsResourceMark*/ EPTNone, sl@0: /*EDbsResourceCheck*/ EPTNone, sl@0: /*EDbsResourceCount*/ EPTNone, sl@0: /*EDbsSetHeapFailure*/ EPTNone, sl@0: /*EDbsOpenDatabase*/ EPTRead | EPTWrite | EPTSchema, //---The caller capabilities will be asserted later, when the db security uid is known sl@0: /*EDbsClose*/ EPTNone, //---EDbsClose may be used to close every possible type of server side dbms object sl@0: /*EDbsDatabaseAuthenticate*/EPTNone, //---Not supported for secure shared databases sl@0: /*EDbsDatabaseDestroy*/ EPTSchema, //---Only admin can destroy the database sl@0: /*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 sl@0: /*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 sl@0: /*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 sl@0: /*EDbsDatabaseProperty*/ EPTNone, sl@0: /*EDbsDatabaseCreateTable*/ EPTSchema, sl@0: /*EDbsDatabaseTables*/ EPTNone, sl@0: /*EDbsDatabaseColumns*/ EPTNone, sl@0: /*EDbsDatabaseIndexes*/ EPTNone, sl@0: /*EDbsDatabaseKeys*/ EPTNone, sl@0: /*EDbsDatabaseOpenObserver*/EPTNone, sl@0: /*EDbsDatabaseOpenUtility*/ EPTWrite, //---Compact/Recover operations sl@0: /*EDbsDatabaseOpenDropTable*/EPTSchema, sl@0: /*EDbsDatabaseOpenAlterTable*/EPTSchema, sl@0: /*EDbsDatabaseOpenCreateIndex*/EPTSchema, sl@0: /*EDbsDatabaseOpenDropIndex*/EPTSchema, sl@0: /*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. sl@0: /*EDbsDatabasePrepareView*/ EPTRead, //---"SELECT" sql string sl@0: /*EDbsDatabaseOpenTable*/ EPTRead | EPTWrite, //---If the caller neither have capabilities for read or write table security policies, then the the caller cannot open the table. sl@0: /*EDbsObserverNotify*/ EPTNone, sl@0: /*EDbsObserverCancel*/ EPTNone, sl@0: /*EDbsIncrementalNext*/ EPTNone, sl@0: /*EDbsCursorColumnTypes*/ EPTNone, sl@0: /*EDbsCursorReset*/ EPTNone, //---Moves the cursor at the beginning of the table/dataset sl@0: /*EDbsCursorEvaluate*/ EPTNone, sl@0: /*EDbsCursorUnevaluated*/ EPTNone, sl@0: /*EDbsCursorSetIndex*/ EPTRead, sl@0: /*EDbsCursorSeek*/ EPTRead, sl@0: /*EDbsCursorAtBeginning*/ EPTNone, sl@0: /*EDbsCursorAtEnd*/ EPTNone, sl@0: /*EDbsCursorAtRow*/ EPTNone, sl@0: /*EDbsCursorCount*/ EPTRead | EPTWrite, sl@0: /*EDbsCursorGotoPos*/ EPTRead, sl@0: /*EDbsCursorBookmark*/ EPTRead, sl@0: /*EDbsCursorGotoBookmark*/ EPTRead, sl@0: /*EDbsCursorGet*/ EPTRead, sl@0: /*EDbsCursorInsert*/ EPTWrite, sl@0: /*EDbsCursorUpdate*/ EPTWrite, sl@0: /*EDbsCursorRetrieveRow*/ EPTNone, //---Used by "Insert" operations sometime sl@0: /*EDbsCursorCancel*/ EPTNone, sl@0: /*EDbsCursorPut*/ EPTWrite, sl@0: /*EDbsCursorDelete*/ EPTWrite, sl@0: /*EDbsCursorColumns*/ EPTNone, sl@0: /*EDbsCursorColumnDef*/ EPTNone, sl@0: /*EDbsCursorSetNull*/ EPTWrite, sl@0: /*EDbsCursorColumnSize*/ EPTNone, sl@0: /*EDbsCursorColumnSource*/ EPTRead, //---Used for large BLOB fields - read ops sl@0: /*EDbsCursorColumnSink*/ EPTWrite, //---Used for large BLOB fields - write ops sl@0: /*EDbsCursorOpenConstraint*/EPTRead, sl@0: /*EDbsCursorMatch*/ EPTRead, sl@0: /*EDbsCursorFind*/ EPTRead, sl@0: /*EDbsStreamRead*/ EPTNone, sl@0: /*EDbsStreamWrite*/ EPTNone, sl@0: /*EDbsStreamSize*/ EPTNone, sl@0: /*EDbsStreamSynch*/ EPTNone, sl@0: /*EDbsCreateDatabase*/ EPTSchema, sl@0: /*EDbsDatabaseList*/ EPTNone, sl@0: /*EDbsCopyDatabase*/ EPTSchema, sl@0: /*EDbsDeleteDatabase*/ EPTSchema, sl@0: /*EDbsGetSecurityPolicy*/ EPTNone, sl@0: /*EDbsReserveDriveSpace*/ EPTNone, sl@0: /*EDbsFreeReservedSpace*/ EPTNone, sl@0: /*EDbsReserveGetAccess*/ EPTNone, sl@0: /*EDbsReserveReleaseAccess*/EPTNone, sl@0: /*EDbsGetBackupPath*/ EPTNone, sl@0: /*EDbsGetBackupPaths*/ EPTNone sl@0: }; sl@0: sl@0: /** sl@0: This function returns bit-field mask value, containing security policies types (R/W/S) sl@0: Each security policy contains a set of Capabilities/SID/VID. sl@0: In order particular database operation to be executed, the caller Capabilities/SID/VID have sl@0: to be checked against security policy Capabilities/SID/VID. sl@0: Don't forget to map new DBMS functions here! sl@0: @param aFunction DBMS server function code sl@0: @return An integer mask with a set of security policy types. The caller has to satisfy at least sl@0: one of of them. sl@0: */ sl@0: static TUint DbsFunction2PolicyMask(TDbsFunction aFunction) sl@0: { sl@0: __ASSERT(aFunction < EDbsLast); sl@0: return KDbsFunc2SecurityPolicyMask[aFunction]; sl@0: } sl@0: sl@0: /** sl@0: Extracts DBMS server function code from aMessage argument. sl@0: @param aMessage DBMS server message sl@0: @return DBMS server function code sl@0: @internalComponent sl@0: */ sl@0: static TDbsFunction Message2Function(const RMessage2& aMessage) sl@0: { sl@0: TDbsFunction func = ::DbsFunction(aMessage.Function()); sl@0: return static_cast (func & ~KDbsObjectReturn); sl@0: } sl@0: sl@0: /** sl@0: */ sl@0: inline CPolicyProxy::CPolicyProxy(RFs& aFs):iFs(aFs) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Standard phase-one factory method for CPolicyProxy instances. sl@0: @param aFs A file server session instance sl@0: @param aPrivatePath DBMS server private data path sl@0: @return A pointer to the created CPolicyProxy instance. sl@0: @leave KErrNoMemory sl@0: */ sl@0: CPolicyProxy* CPolicyProxy::NewL(RFs& aFs,const TDesC& aPrivatePath) sl@0: { sl@0: CPolicyProxy* self = new (ELeave) CPolicyProxy(aFs); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aPrivatePath); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: */ sl@0: CPolicyProxy::~CPolicyProxy() sl@0: { sl@0: if(iPolicySpace) //iPolicySpace can be NULL in OOM tests sl@0: { sl@0: iPolicySpace->Release(); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Returns requested database security policy interface, which cannot be NULL. sl@0: @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID sl@0: @return A const pointer to the related UID security policy object. sl@0: */ sl@0: const MPolicy* CPolicyProxy::DbPolicyL(const TDbPolicyRequest& aDbPolicyRequest) sl@0: { sl@0: return iPolicySpace->DbPolicyL(aDbPolicyRequest); sl@0: } sl@0: sl@0: /** sl@0: Returns requested table security policy interface, which cannot be NULL. sl@0: @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID sl@0: @param aTblName Database table name sl@0: @return A const pointer to the related table security policy object. sl@0: */ sl@0: const MPolicy* CPolicyProxy::TblPolicyL(const TDbPolicyRequest& aDbPolicyRequest, sl@0: const TDesC& aTblName) sl@0: { sl@0: return iPolicySpace->TblPolicyL(aDbPolicyRequest, aTblName); sl@0: } sl@0: sl@0: /** sl@0: This method is used to get the SQL related MPolicy interface and the related security sl@0: policy type. sl@0: If aUPRequest.iRqAccess is EATNonSecure, then the default security policy will be returned. sl@0: Currently the DBMS can process the following SQL strings: sl@0: 1)DDL - CREATE/DROP/ALTER SQL statements - EPTSchema database access level. sl@0: 2)DML - INSERT/UPDATE/DELETE SQL statements. Only one table can be put after the "FROM" sl@0: SQL keyword. EPTWrite table access level. sl@0: 3)QUERY- SELECT SQL statements. Only one table can be out after the "FROM" SQL keyword. sl@0: EPTRead table access level. sl@0: @param aDbPolicyRequest A const reference to an object packing security policy uid and the request type: sl@0: secure/non-secure. sl@0: @param aSql SQL string sl@0: @param aPolicyType An output parameter, referencing the location, where the policy type will be stored. sl@0: @return A const pointer to the related policy interface. It cannot be NULL, and must not be deleted. sl@0: @leave One of the system-wide error codes. sl@0: */ sl@0: const MPolicy* CPolicyProxy::SqlPolicyL(const TDbPolicyRequest& aDbPolicyRequest, const TDesC& aSql, sl@0: TPolicyType& aPolicyType) sl@0: { sl@0: const MPolicy* policy = NULL; sl@0: aPolicyType = EPTNone; sl@0: //Get table name and sql type. sl@0: TSqlParser2 sqlParser; sl@0: sqlParser.ParseL(aSql); sl@0: Sql::TStatementType sqlType = sqlParser.StatementType(); sl@0: //Reinitialize aSqlSecurityPolicyData, which is sql type dependent. sl@0: switch(sqlType) sl@0: { sl@0: case Sql::EDDL: sl@0: //Database EPTSchema access level sl@0: policy = DbPolicyL(aDbPolicyRequest); sl@0: aPolicyType = EPTSchema; sl@0: break; sl@0: case Sql::EDML: sl@0: default: sl@0: {//Table access level - EPTRead or EPTWrite. sl@0: const TDesC& tblName = sqlParser.TableName(); sl@0: __ASSERT(tblName.Length() > 0); sl@0: TBuf tblNameBuf; sl@0: tblNameBuf.Copy(tblName); sl@0: policy = TblPolicyL(aDbPolicyRequest, tblNameBuf); sl@0: aPolicyType = sqlType == Sql::EDML ? EPTWrite : EPTRead; sl@0: } sl@0: break; sl@0: } sl@0: __ASSERT(policy); sl@0: return policy; sl@0: } sl@0: sl@0: /** sl@0: Returns backup&restore SID for the databases, the access to which is controlled by the sl@0: security policy, identified by aDbUid parameter. sl@0: @param aDbUid Domain UID sl@0: @return Backup&restore SID for the supplied domain UID sl@0: @leave KErrArgument if there is no security policy domain for the supplied UID. sl@0: */ sl@0: TSecureId CPolicyProxy::BackupSIDL(TUid aDbUid) const sl@0: { sl@0: return iPolicySpace->BackupSIDL(aDbUid); sl@0: } sl@0: sl@0: /** sl@0: Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy sl@0: managed by aPolicy parameter. The caller has to satisfy at least one of the related to sl@0: the message security policies. sl@0: @param aMessage An object whith caller capabilities/SID/VID, which has to be checked. sl@0: @param aPolicy A const reference to the security policy object. sl@0: @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation sl@0: */ sl@0: void CPolicyProxy::CheckL(const RMessage2& aMessage, const MPolicy& aPolicy) const sl@0: { sl@0: TDbsFunction func = ::Message2Function(aMessage); sl@0: TUint mask = ::DbsFunction2PolicyMask(func); sl@0: if(mask != EPTNone) sl@0: { sl@0: for(TInt c=0;c (1 << c); sl@0: if(policyType & mask) sl@0: { sl@0: if(aPolicy.Check(aMessage, policyType)) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: __LEAVE(KErrPermissionDenied); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy sl@0: managed by aPolicy parameter. sl@0: @param aPolicyType The policy type, against which the check has to be done. sl@0: @param aMessage An object whith caller capabilities/SID/VID, which has to be checked. sl@0: @param aPolicy A const reference to the security policy object. sl@0: @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation sl@0: */ sl@0: void CPolicyProxy::CheckL(TPolicyType aPolicyType, const RMessage2& aMessage, const MPolicy& aPolicy) const sl@0: { sl@0: if(aPolicyType != EPTNone) sl@0: { sl@0: if(!aPolicy.Check(aMessage, aPolicyType)) sl@0: { sl@0: __LEAVE(KErrPermissionDenied); sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Standard phase-two construction method for CPolicyProxy instances. sl@0: @param aPrivatePath DBMS server private data path sl@0: @leave KErrNoMemory sl@0: */ sl@0: void CPolicyProxy::ConstructL(const TDesC& aPrivatePath) sl@0: { sl@0: iPolicySpace = TPolicySpaceFactory::NewPolicySpaceL(iFs, aPrivatePath); sl@0: } sl@0: