--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/security/SC_Policy.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,655 @@
+// Copyright (c) 2004-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:
+// CPolicyBase, CDbPolicy, CTblPolicy, CPolicyDomain classes
+//
+//
+
+#include "SC_Policy.h"
+
+namespace DBSC
+{
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//CPolicyBase class
+
+/**
+*/
+CPolicyBase::~CPolicyBase()
+ {
+ iPolicyCollection.Close();//Collection of R/W/S security policies
+ }
+
+#ifdef __DBDUMP__
+/**
+Dumps the content of a CPolicyBase instance to a text file.
+@param aFile A reference to RFile object, which has to be used for the output.
+*/
+void CPolicyBase::Dump(RFile& aFile) const
+ {
+ DB_INVARIANT();
+
+ _LIT8(KClassName, "Class: CPolicyBase. this=%X");
+ _LIT8(KCount, "Security Policy, Count=%d");
+ _LIT8(KCrLf, "\r\n");
+ _LIT8(KPolicyType, "Policy type: ");
+ _LIT8(KRead, "Read, ");
+ _LIT8(KWrite, "Write, ");
+ _LIT8(KSchema, "Schema, ");
+ _LIT8(KPolicyData, "Policy data: ");
+ _LIT8(KFmt, "%02X ");
+ TBuf8<100> buf;
+
+ buf.Format(KClassName, this);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+
+ TInt cnt = iPolicyCollection.Count();
+ buf.Format(KCount, TInt32(cnt));
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+
+ for(TInt i=0;i<cnt;++i)
+ {
+ const TPolicy& policy = iPolicyCollection[i];
+ (void)aFile.Write(KPolicyType);
+ switch(policy.iType)
+ {
+ case EPTRead:
+ (void)aFile.Write(KRead);
+ break;
+ case EPTWrite:
+ (void)aFile.Write(KWrite);
+ break;
+ case EPTSchema:
+ (void)aFile.Write(KSchema);
+ break;
+ default:
+ __ASSERT(0);
+ break;
+ }
+ (void)aFile.Write(KPolicyData);
+ TPtrC8 packet = policy.iData.Package();
+ TInt len = packet.Length();
+ for(TInt j=0;j<len;++j)
+ {
+ buf.Format(KFmt, packet[j]);
+ (void)aFile.Write(buf);
+ }
+ (void)aFile.Write(KCrLf);
+ }
+ }
+#endif//__DBDUMP__
+
+/**
+Standard phase-two construction method for CPolicyBase instance.
+@param aPolicyCollection A const reference to a collection of R/W/S policies, which has to
+ be used to control the access to a database object, controlled by CPolicyBase
+ instance.
+*/
+void CPolicyBase::ConstructL(const CPolicyBase::RPolicyCollection& aPolicyCollection)
+ {
+ iPolicyCollection.Reset();
+ TInt cnt = aPolicyCollection.Count();
+ for(TInt i=0;i<cnt;++i)
+ {
+ __LEAVE_IF_ERROR(iPolicyCollection.Append(aPolicyCollection[i]));
+ }
+ DB_INVARIANT();
+ }
+
+/**
+It is used in the production code.
+If the object data is not in a consistent state, the method will leave
+with KErrGeneral error.
+@leave KErrGeneral, if the object data is not in a consistent state
+*/
+void CPolicyBase::InvariantL() const
+ {
+ TUint32 mask = 0;
+ for(TInt i=(iPolicyCollection.Count()-1);i>-1;--i)
+ {
+ TPolicy& policy = const_cast <TPolicy&> (iPolicyCollection[i]);
+ if(policy.iType == EPTNone)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ if(mask & policy.iType) //This security policy is duplicated
+ {
+ __LEAVE(KErrGeneral);
+ }
+ TPtrC8 packet = policy.iData.Package();
+ if(policy.iData.Set(packet) != KErrNone)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ mask |= policy.iType;
+ }
+ }
+
+/**
+This method implements pure virtual MPolicy::Get().
+It searches object's policy collection for a policy of type aPolicyType
+and initializes aPolicy parameter with the found policy.
+@param aPolicyType Type of the requested security policy: read/write/schema
+@param aPolicy Outout parameter, which will be initialized with the found security policy data.
+@return System-wide error code, including KErrNotFound if the requested policy was not found.
+*/
+TInt CPolicyBase::Get(TPolicyType aPolicyType, TSecurityPolicy& aPolicy) const
+ {
+ DB_INVARIANT();
+ TInt err = KErrNotFound;
+ const TSecurityPolicy* securityPolicy = Policy(aPolicyType);
+ if(securityPolicy)
+ {
+ err = aPolicy.Set(securityPolicy->Package());
+ }
+ return err;
+ }
+
+#ifdef __DBINVARIANT__
+/**
+Asserts the internal state of CPolicyBase instance.
+It can be used for pre- or post- condition checks in CPolicyBase methods implementations.
+*/
+void CPolicyBase::Invariant() const
+ {
+ TRAPD(err, InvariantL());
+ DB_INVARIANT_ASSERT(err == KErrNone);
+ }
+#endif//__DBINVARIANT__
+
+/**
+The method traverses the policies collection and searches for a policy of aPolicyType type.
+If such a policy exists, a const pointer to it will be returned, otherwise - NULL.
+@param aPolicyType Policy type - R/W/S
+@return A const pointer to the found policy or NULL if not found.
+*/
+const TSecurityPolicy* CPolicyBase::Policy(TPolicyType aPolicyType) const
+ {
+ __ASSERT(aPolicyType != EPTNone);
+ const TSecurityPolicy* policy = NULL;
+ for(TInt i=(iPolicyCollection.Count()-1);i>-1;--i)
+ {
+ if(iPolicyCollection[i].iType == aPolicyType)
+ {
+ policy = &iPolicyCollection[i].iData;
+ break;
+ }
+ }
+ return policy;
+ }
+
+/**
+Asserts caller capabilities/SID/VID.
+@param aMessage An object whith caller capabilities/SID/VID, which has to be checked.
+@param aPolicyType Policy type - R/W/S.
+@return EPCNotFound - the policy cannot be found
+ EPCPassed - policy check passed
+ EPCNotPassed - policy check not passed
+*/
+CPolicyBase::TPolicyCheckResult CPolicyBase::DoCheck(const RMessage2& aMessage, TPolicyType aPolicyType) const
+ {
+ const TSecurityPolicy* securityPolicy = Policy(aPolicyType);
+
+ if(!securityPolicy)
+ {
+ return EPCNotFound;
+ }
+
+ return securityPolicy->CheckPolicy(aMessage) ? EPCPassed : EPCNotPassed;
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//CDbPolicy class
+
+/**
+*/
+CDbPolicy::~CDbPolicy()
+ {
+ }
+
+/**
+Asserts caller capabilities/SID/VID.
+@param aMessage An object whith caller capabilities/SID/VID, which has to be checked.
+@param aPolicyType Policy type - R/W/S.
+@return ETrue The caller capabilities/SID/VID satisfy the specified security policy.
+ EFalse The check not passed.
+@panic EDBSCPolicyNotFound, if there is no such policy
+*/
+TBool CDbPolicy::Check(const RMessage2& aMessage, TPolicyType aPolicyType) const
+ {
+ __ASSERT(aPolicyType != EPTNone);
+ DB_INVARIANT();
+ TPolicyCheckResult res = DoCheck(aMessage, aPolicyType);
+ __ASSERT(res != EPCNotFound);
+ return res == EPCPassed ? ETrue : EFalse;
+ }
+
+/**
+Standard phase-one factory method for CDbPolicy instance.
+@param aPolicyCollection A const reference to a collection of R/W/S policies, which has to
+ be used to control the access to the database, controlled by CDbPolicy instance.
+@return A pointer to just created CDbPolicy instance.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CDbPolicy* CDbPolicy::NewLC(const CPolicyBase::RPolicyCollection& aPolicyCollection)
+ {
+ CDbPolicy* self = new (ELeave) CDbPolicy;
+ CleanupStack::PushL(self);
+ self->ConstructL(aPolicyCollection);
+ return self;
+ }
+
+#ifdef __DBDUMP__
+/**
+Dumps the content of a CDbPolicy instance to a text file.
+@param aFile A reference to RFile object, which has to be used for the output.
+*/
+void CDbPolicy::Dump(RFile& aFile) const
+ {
+ DB_INVARIANT();
+
+ _LIT8(KClassName, "Class: CDbPolicy. this=%X");
+ _LIT8(KCrLf, "\r\n");
+ _LIT8(KObjType, "Object: Database");
+ _LIT8(KEnd, "==========================");
+ TBuf8<40> buf;
+
+ buf.Format(KClassName, this);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ (void)aFile.Write(KObjType);
+ (void)aFile.Write(KCrLf);
+ CPolicyBase::Dump(aFile);
+ (void)aFile.Write(KEnd);
+ (void)aFile.Write(KCrLf);
+ }
+#endif//__DBDUMP__
+
+/**
+It is used in the production code.
+If the object data is not in a consistent state, the method will leave
+with KErrGeneral error.
+@leave KErrGeneral, if the object data is not in a consistent state
+*/
+void CDbPolicy::InvariantL() const
+ {
+ for(TInt c=0;c<KPolicyTypesCount;++c)
+ {
+ TPolicyType t = static_cast <TPolicyType> (1 << c);
+ if(Policy(t) == NULL)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ }
+ CPolicyBase::InvariantL();
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//CTblPolicy class
+
+/**
+*/
+CTblPolicy::~CTblPolicy()
+ {
+ delete iTblName;
+ }
+
+/**
+Asserts caller capabilities/SID/VID.
+@param aMessage An object whith caller capabilities/SID/VID, which has to be checked.
+@param aPolicyType Policy type - R/W/S.
+@return ETrue The caller capabilities/SID/VID satisfy the specified security policy.
+ EFalse The check not passed.
+@panic EDBSCPolicyNotFound, if there is no such policy
+*/
+TBool CTblPolicy::Check(const RMessage2& aMessage, TPolicyType aPolicyType) const
+ {
+ __ASSERT(aPolicyType != EPTNone);
+ __ASSERT(iDbPolicy);
+ DB_INVARIANT();
+ TPolicyCheckResult res = EPCNotPassed;
+ //1. Check database security policy
+ if(iDbPolicy->Check(aMessage, aPolicyType))
+ {
+ //2. Check table security policy
+ res = DoCheck(aMessage, aPolicyType);
+ }
+ //If there is no table security policy of the requested type - no problem, the database
+ //security policy of that type has been checked already and the check passed.
+ return res == EPCNotPassed ? EFalse : ETrue;
+ }
+
+/**
+This method implements pure virtual MPolicy::Get().
+It searches object's policy collection for a policy of type aPolicyType
+and initializes aPolicy parameter with the found policy.
+@param aPolicyType Type of the requested security policy: read/write
+@param aPolicy Outout parameter, which will be initialized with the found security policy data.
+@return System-wide error codes, including KErrNotSupported, if the request is for a schema policy.
+*/
+TInt CTblPolicy::Get(TPolicyType aPolicyType, TSecurityPolicy& aPolicy) const
+ {
+ if(aPolicyType == EPTSchema)
+ {
+ return KErrNotSupported;
+ }
+ DB_INVARIANT();
+ TInt err = CPolicyBase::Get(aPolicyType, aPolicy);
+ if(err == KErrNotFound)
+ {
+ err = iDbPolicy->Get(aPolicyType, aPolicy);
+ }
+ __ASSERT(err != KErrNotFound);
+ return err;
+ }
+
+/**
+Standard phase-one factory method for CTblPolicy instance.
+@param aTblName Name of the controlled by this instance database table.
+@param aPolicyCollection A const reference to a collection of R/W/S policies, which has to
+ be used to control the access to the table, controlled by CTblPolicy instance.
+@param aDbPolicy The related for the table database policy.
+ CTblPolicy instance does not take the ownership on aDbPolicy pointer!
+@return A pointer to just created CTblPolicy instance.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CTblPolicy* CTblPolicy::NewLC(const TDesC& aTblName,
+ const CPolicyBase::RPolicyCollection& aPolicyCollection,
+ const CDbPolicy* aDbPolicy)
+ {
+ CTblPolicy* self = new (ELeave) CTblPolicy(aDbPolicy);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTblName, aPolicyCollection);
+ return self;
+ }
+
+#ifdef __DBDUMP__
+/**
+Dumps the content of a CTblPolicy instance to a text file.
+@param aFile A reference to RFile object, which has to be used for the output.
+*/
+void CTblPolicy::Dump(RFile& aFile) const
+ {
+ DB_INVARIANT();
+
+ _LIT8(KClassName, "Class: CTblPolicy. this=%X");
+ _LIT8(KDbPolicyPtr, "Db policy ptr=%X");
+ _LIT8(KCrLf, "\r\n");
+ _LIT8(KName, "Table name: ");
+ _LIT8(KObjType, "Object: Table");
+ _LIT8(KEnd, "==========================");
+ TBuf8<100> buf;
+
+ buf.Format(KClassName, this);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ (void)aFile.Write(KObjType);
+ (void)aFile.Write(KCrLf);
+ buf.Format(KDbPolicyPtr, iDbPolicy);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ buf.Copy(KName);
+ buf.Append(*iTblName);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ CPolicyBase::Dump(aFile);
+ (void)aFile.Write(KEnd);
+ (void)aFile.Write(KCrLf);
+ }
+#endif//__DBDUMP__
+
+/**
+It is used in the production code.
+If the object data is not in a consistent state, the method will leave
+with KErrGeneral error.
+@leave KErrGeneral, if the object data is not in a consistent state
+*/
+void CTblPolicy::InvariantL() const
+ {
+ if(iDbPolicy == NULL)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ if(iTblName == NULL || iTblName->Length() == 0)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ if(Policy(EPTSchema) != NULL)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ CPolicyBase::InvariantL();
+ }
+
+/**
+Standard phase-two construction method for CTblPolicy instance.
+@param aTblName Name of the controlled by this instance database table.
+@param aPolicyCollection A const reference to a collection of R/W/S policies, which has to
+ be used to control the access to the table object, controlled by CTblPolicy
+ instance.
+*/
+void CTblPolicy::ConstructL(const TDesC& aTblName, const CPolicyBase::RPolicyCollection& aPolicyCollection)
+ {
+ iTblName = HBufC::NewL(aTblName.Length());
+ *iTblName = aTblName;
+ CPolicyBase::ConstructL(aPolicyCollection);
+ DB_INVARIANT();
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//CPolicyDomain class
+
+/**
+Standard phase-one factory method for CPolicyDomain instance.
+@param aUid UID of the controlled by this instance security policy domain.
+@param aPDLoader A reference to an implementation of MPolicyDomainLoader interface,
+ which is used to load and add security policies to the controlled collection.
+@return A pointer to just created CPolicyDomain instance.
+@leave System-wide error codes, including KErrNoMemory.
+*/
+CPolicyDomain* CPolicyDomain::NewLC(TUid aUid, MPolicyDomainLoader& aPDLoader)
+ {
+ CPolicyDomain* self = new (ELeave) CPolicyDomain(aUid);
+ CleanupStack::PushL(self);
+ self->InternalizeL(aPDLoader);
+ return self;
+ }
+
+/**
+*/
+CPolicyDomain::~CPolicyDomain()
+ {
+ Destroy();
+ }
+
+/**
+The method returns the database policy interface.
+@return A const pointer to the database policy interface in CPolicyDomain.
+*/
+const MPolicy* CPolicyDomain::DbPolicy() const
+ {
+ DB_INVARIANT();
+ return iDbPolicy;
+ }
+
+/**
+The method returns a table policy interface, identified by aTblName parameter.
+@param aTblName Name of the table, which policy interface has to be retrieved.
+@return A const pointer to the table policy interface, which is identified by aTblName parameter.
+*/
+const MPolicy* CPolicyDomain::TblPolicy(const TDesC& aTblName) const
+ {
+ __ASSERT(aTblName.Length() > 0);
+ DB_INVARIANT();
+ const MPolicy* policy = NULL;
+ TInt cnt = iTPCollection.Count();
+ for(TInt i=0;i<cnt;++i)
+ {
+ CTblPolicy* tblPolicy = iTPCollection[i];
+ __ASSERT(tblPolicy);
+ if(aTblName.CompareF(tblPolicy->TableName()) == 0)
+ {
+ policy = tblPolicy;
+ break;
+ }
+ }
+ if(!policy)
+ {
+ policy = iDbPolicy;
+ }
+ __ASSERT(policy);
+ return policy;
+ }
+
+/**
+Externalizes the security policy collection using MPolicyDomainPersister interface as an
+persister.
+@param aPDPersister A reference to an MPolicyDomainPersister implementation, which will
+ persist the controlled collection of security policies.
+*/
+void CPolicyDomain::ExternalizeL(MPolicyDomainPersister& aPDPersister) const
+ {
+ DB_INVARIANT();
+ TPolicyDomainReader reader(*this);
+ aPDPersister.RunL(reader);
+ }
+
+#ifdef __DBDUMP__
+/**
+Dumps the content of a CPolicyDomain instance to a text file.
+@param aFile A reference to RFile object, which has to be used for the output.
+*/
+void CPolicyDomain::Dump(RFile& aFile) const
+ {
+ DB_INVARIANT();
+
+ _LIT8(KClassName, "Class: CPolicyDomain. this=%X");
+ _LIT8(KUidFmt, "UID=%X");
+ _LIT8(KCrLf, "\r\n");
+ _LIT8(KEnd, "==========================");
+ _LIT8(KBackupSIDFmt, "BackupSID=%X");
+ TBuf8<40> buf;
+
+ buf.Format(KClassName, this);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ buf.Format(KUidFmt, iUid.iUid);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ (void)aFile.Write(KEnd);
+ (void)aFile.Write(KCrLf);
+ iDbPolicy->Dump(aFile);
+ TInt cnt = iTPCollection.Count();
+ for(TInt i=0;i<cnt;++i)
+ {
+ __ASSERT(iTPCollection[i]);
+ iTPCollection[i]->Dump(aFile);
+ }
+ (void)aFile.Write(KEnd);
+ buf.Format(KBackupSIDFmt, iBackupSID.iUid);
+ (void)aFile.Write(buf);
+ (void)aFile.Write(KCrLf);
+ }
+#endif//__DBDUMP__
+
+/**
+It is used in the production code.
+If the object data is not in a consistent state, the method will leave
+with KErrGeneral error.
+@leave KErrGeneral, if the object data is not in a consistent state
+*/
+void CPolicyDomain::InvariantL() const
+ {
+ if(iUid == KNullUid)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ if(iDbPolicy == NULL)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ iDbPolicy->InvariantL();
+
+ TInt cnt = iTPCollection.Count();
+ TInt i;
+ for(i=0;i<cnt;++i)
+ {
+ if(iTPCollection[i] == NULL)
+ {
+ __LEAVE(KErrGeneral);
+ }
+ iTPCollection[i]->InvariantL();
+ }
+ //Check that each represented table has unique name
+ for(i=0;i<(cnt-1);++i)
+ {
+ for(TInt j=(i+1);j<cnt;++j)
+ {
+ if(iTPCollection[i]->TableName() == iTPCollection[j]->TableName())
+ {
+ __LEAVE(KErrGeneral);
+ }
+ }
+ }
+ }
+
+#ifdef __DBINVARIANT__
+/**
+Asserts the internal state of CPolicyDomain instance.
+It can be used for pre- or post- condition checks in CPolicyDomain methods implementations.
+*/
+void CPolicyDomain::Invariant() const
+ {
+ TRAPD(err, InvariantL());
+ DB_INVARIANT_ASSERT(err == KErrNone);
+ }
+#endif//__DBINVARIANT__
+
+/**
+Creates the collection of security policies using MPolicyDomainLoader interface as a security
+policy loader.
+@param aPDLoader A reference to MPolicyDomainLoader implementation, which is used to load
+ and add security policies to the controlled collection.
+@leave System-wide error code including KErrGeneral if the data is not consistent
+*/
+void CPolicyDomain::InternalizeL(MPolicyDomainLoader& aPDLoader)
+ {
+ TPolicyDomainBuilder builder(*this);
+ aPDLoader.RunL(builder);
+#ifdef __DBINVARIANT__
+ Invariant();
+#else
+ InvariantL();
+#endif
+ }
+
+/**
+The method destroys the controlled by CPolicyDomain collection of security policies.
+*/
+void CPolicyDomain::Destroy()
+ {
+ TInt cnt = iTPCollection.Count();
+ for(TInt i=0;i<cnt;++i)
+ {
+ __ASSERT(iTPCollection[i]);
+ delete iTPCollection[i];
+ }
+ iTPCollection.Close();
+ delete iDbPolicy;
+ iDbPolicy = NULL;
+ }
+
+} //end of - namespace DBSC
+