installationservices/swtransactionservices/source/server/stsserver.cpp
changeset 24 84a16765cd86
equal deleted inserted replaced
6:aba6b8104af3 24:84a16765cd86
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * Implements CStsServer.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**
       
    21  @file
       
    22  @internalComponent
       
    23  @released
       
    24 */
       
    25 
       
    26 #include "stsserver.h"
       
    27 #include "stsserversession.h"
       
    28 #include "usiflog.h"
       
    29 #include <scs/securityutils.h>
       
    30 
       
    31 namespace Usif
       
    32 {
       
    33 static const TUint stsServerRangeCount = 5;
       
    34 
       
    35 static const TInt stsServerRanges[stsServerRangeCount] =
       
    36 	{
       
    37 	0,							                                      //Range 0 - 0 to EBaseSession-1. Not used.
       
    38 	CScsServer::EBaseSession,	                                      //Range 1 - EBaseSession to (EBaseSession+ERegisterNew)-1. ==> from ECreateTransaction to EGetId inclusive
       
    39 	CScsServer::EBaseSession|static_cast<TInt>(ERegisterNew),         //Range 2 - (EBaseSession+ERegisterNew) to (EBaseSession+ERollBackAllPending)-1 ==> from ERegisterNew to EOverwrite inclusive
       
    40 	CScsServer::EBaseSession|static_cast<TInt>(ERollBackAllPending),  //Range 3 - (EBaseSession+ERollBackAllPending) to ((EBaseSession+ERollBackAllPending)+1)-1==> only ERollBackAllPending
       
    41 	CScsServer::EBaseSession|static_cast<TInt>(ERollBackAllPending)+1 //Range 4 - (EBaseSession+ERollBackAllPending)+1 to KMaxTInt inclusive  (i.e: ScsImpl::EPreCloseSession)
       
    42 	};
       
    43 
       
    44 static const TUint8 stsServerElementsIndex[stsServerRangeCount] =
       
    45 	{
       
    46 	CPolicyServer::ENotSupported, // Range 0 : is not supported.
       
    47 	CPolicyServer::EAlwaysPass,   // Range 1
       
    48 	CPolicyServer::ECustomCheck,  // Range 2 : custom check will be made made for each function to see if client is authorised to do that
       
    49 	0,                            // Range 3 : Can only be issued by KUidDaemon
       
    50 	CPolicyServer::EAlwaysPass    // Range 4
       
    51 	};							
       
    52 
       
    53 static const CPolicyServer::TPolicyElement stsServerElements[] =
       
    54 	{
       
    55 	{_INIT_SECURITY_POLICY_S0(KUidDaemon), CPolicyServer::EFailClient}, //special handling of function ERollBackAllPending 
       
    56 	};
       
    57 
       
    58 static const CPolicyServer::TPolicy stsServerPolicy =
       
    59 	{
       
    60 	CPolicyServer::EAlwaysPass, // Allow all connects
       
    61 	stsServerRangeCount,
       
    62 	stsServerRanges,
       
    63 	stsServerElementsIndex,
       
    64 	stsServerElements,
       
    65 	};
       
    66 
       
    67 //
       
    68 //CStsServer
       
    69 //
       
    70 
       
    71 CStsServer::CStsServer()
       
    72 /**
       
    73 	Intializes the STS server object with its version and policy.
       
    74  */
       
    75 	:	CScsServer(TVersion(KStsVerMajor, KStsVerMinor, KStsVerBuild),stsServerPolicy)
       
    76 		{
       
    77 		//empty
       
    78 		}
       
    79 
       
    80 CStsServer::~CStsServer()
       
    81 /**
       
    82 	Destructor. Cleanup the STS server.
       
    83  */
       
    84 	{
       
    85 	iTransactionWrapperContainer.ResetAndDestroy();
       
    86 	}
       
    87 	
       
    88 	
       
    89 CStsServer* CStsServer::NewLC()
       
    90 /**
       
    91 	Factory function allocates new, initialized instance of CStsServer.
       
    92 
       
    93 	@return		New, initialized instance of CStsServer
       
    94 				which is left on the cleanup stack.
       
    95  */
       
    96 	{
       
    97 	CStsServer *so = new (ELeave) CStsServer();
       
    98 	CleanupStack::PushL(so);
       
    99 	so->ConstructL();
       
   100 	return so;
       
   101 	}
       
   102 
       
   103 
       
   104 void CStsServer::ConstructL()
       
   105 /**
       
   106 	Second phase constructor starts the STS server.
       
   107  */
       
   108 	{
       
   109 	// Roll back all previous transactions in case the STS process died unexpectedly
       
   110 	// Note: error returned from RollBackAllPendingL() is ignored at this point to prevent STS server startup from failing
       
   111 	// It is important to roll back before calling CScsServer::ConstructL as the roll back may be longer than the shutdown period for the timer started by that function
       
   112 	TRAP_IGNORE(RollBackAllPendingL());
       
   113 	
       
   114 	CScsServer::ConstructL(KStsServerShutdownPeriod); 
       
   115 		
       
   116 	StartL(KStsServerName);
       
   117 	}
       
   118 
       
   119 
       
   120 CScsSession* CStsServer::DoNewSessionL(const RMessage2& aMessage)
       
   121 /**
       
   122 	Implement CStsServer by allocating a new instance of CStsServerSession.
       
   123 
       
   124 	@param	aMessage	Standard server-side handle to message.
       
   125 	@return				New instance of CStsServerSession which is owned by the caller.
       
   126  */
       
   127 	{
       
   128 	return CStsServerSession::NewL(*this, aMessage);
       
   129 	}
       
   130 
       
   131 void CStsServer::RollBackAllPendingL()
       
   132 /**
       
   133 	Rolls back all pending transactions that have persistent information stored in the transaction
       
   134 	path in the file system.
       
   135 	Important note: this function can only be invoked if there are no active transactions in the server as it is
       
   136 	not intended to roll back active transactions. (ie: intended to be invoked at boot-up time and STS start up only) 
       
   137  */
       
   138 	{
       
   139 	if(iTransactionWrapperContainer.Count()!=0) 
       
   140 		{
       
   141 		User::Leave(KErrInUse); //there can be no active transaction when this function is invoked 
       
   142 		}
       
   143 	CIntegrityServices::RollbackAllL();
       
   144 	}
       
   145 
       
   146 TInt TransactionWrapperLinearOrderByIdKey(const TStsTransactionId *id, const CReferenceCountedTransactionWrapper &aSecond)
       
   147 	{
       
   148 	return *id-aSecond.TransactionId();
       
   149 	}
       
   150 
       
   151 TInt TransactionWrapperLinearOrder(const CReferenceCountedTransactionWrapper &aFirst, const CReferenceCountedTransactionWrapper &aSecond)
       
   152 	{
       
   153 	return aFirst.TransactionId()-aSecond.TransactionId();
       
   154 	}
       
   155 
       
   156 TStsTransactionId CStsServer::CreateTransactionID()
       
   157 	{
       
   158 	TTime currentTime;
       
   159 	TStsTransactionId transactionID;
       
   160 	do
       
   161 		{
       
   162 		currentTime.UniversalTime();
       
   163 		transactionID = I64LOW(currentTime.Int64());
       
   164 		}
       
   165     while(IsExistingTransaction(transactionID));
       
   166     return transactionID;
       
   167 	}
       
   168 
       
   169 TBool CStsServer::IsExistingTransaction(TStsTransactionId aTransactionID)
       
   170 	{
       
   171 	return (FindActiveTransaction(aTransactionID)>=0);
       
   172 	} 
       
   173 
       
   174 CIntegrityServices* CStsServer::CreateTransactionL()
       
   175 	{
       
   176 	TStsTransactionId id = CreateTransactionID();
       
   177 	CReferenceCountedTransactionWrapper* wrapper = CReferenceCountedTransactionWrapper::NewLC(id);
       
   178 	iTransactionWrapperContainer.InsertInOrderL(wrapper, TLinearOrder<CReferenceCountedTransactionWrapper>(&TransactionWrapperLinearOrder));
       
   179 	CleanupStack::Pop(wrapper);
       
   180 	return wrapper->Attach();
       
   181 	}
       
   182 
       
   183 CIntegrityServices* CStsServer::AttachTransactionL(TStsTransactionId aTransactionID)
       
   184 	{
       
   185 	TInt pos=FindActiveTransaction(aTransactionID);
       
   186 	if(pos>=0) //joining an existing active transaction
       
   187 		{
       
   188 		return iTransactionWrapperContainer[pos]->Attach();
       
   189 		}
       
   190 	User::Leave(KErrNotFound);
       
   191 	return 0;
       
   192 	}
       
   193 
       
   194 void CStsServer::ReleaseTransactionL(CIntegrityServices* &aTransactionPtr, TBool aMarkAsCompleted /*=EFalse*/)
       
   195 	{
       
   196 	__ASSERT_DEBUG(aTransactionPtr, User::Invariant());
       
   197 	TInt pos=FindActiveTransaction(aTransactionPtr->TransactionId());
       
   198 	__ASSERT_DEBUG(pos>=0, User::Invariant());
       
   199 	CReferenceCountedTransactionWrapper* wrapper=iTransactionWrapperContainer[pos];
       
   200 	if(aMarkAsCompleted)
       
   201 		wrapper->SetCompleted(); //set transaction as completed (this should be done after a succesful commit or rollback) 
       
   202 	TInt refCount=wrapper->Detach();
       
   203 	__ASSERT_DEBUG(refCount>=0, User::Invariant());
       
   204 	if(refCount==0) 
       
   205 		{
       
   206 		if(!wrapper->IsCompleted()) //do an auto roll back if and only if the transaction has not been committed or rolled-back previously
       
   207 			aTransactionPtr->RollBackL();
       
   208 		delete wrapper;
       
   209 		iTransactionWrapperContainer.Remove(pos);
       
   210 		}
       
   211 	aTransactionPtr=0;
       
   212 	}
       
   213 /*
       
   214  This function is a slight optimization of CStsServer::ReleaseTransactionL() as it is intended to be called
       
   215  on cleanup of a committed or rolled-back transaction that obviously don't need auto rollbak again.
       
   216  */
       
   217 void CStsServer::FinaliseTransactionL(CIntegrityServices* &aTransactionPtr)
       
   218 	{
       
   219 	ReleaseTransactionL(aTransactionPtr, ETrue);
       
   220 	}
       
   221 
       
   222 TInt CStsServer::FindActiveTransaction(TStsTransactionId aTransactionID)
       
   223 	{
       
   224 	return iTransactionWrapperContainer.FindInOrder(aTransactionID, &TransactionWrapperLinearOrderByIdKey);
       
   225 	}
       
   226 
       
   227 CPolicyServer::TCustomResult CStsServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/)		
       
   228 	{
       
   229 	TInt functionId(StripScsFunctionMask(aMsg.Function()));
       
   230 	CPolicyServer::TCustomResult ret(EFail);
       
   231 		
       
   232 	switch(functionId)
       
   233 		{
       
   234 		case ERegisterNew:
       
   235 		case ECreateNew:
       
   236 		case ERemove:
       
   237 		case ERegisterTemporary:
       
   238 		case ECreateTemporary:
       
   239 		case EOverwrite:
       
   240 			ret = CheckIfFileModificationAllowedL(aMsg)? EPass : EFail;
       
   241 			break;
       
   242 		}
       
   243 	return ret;
       
   244 	}
       
   245 
       
   246 /*static*/TBool CStsServer::CheckIfFileModificationAllowedL(const RMessage2& aMsg)
       
   247 	{
       
   248 	RBuf filePath;
       
   249 	filePath.CreateL(KMaxFileName);
       
   250 	filePath.CleanupClosePushL();
       
   251 	aMsg.ReadL(KFilePathIPCSlot, filePath, 0);
       
   252 
       
   253 	// Retrieve the required capabilities for write access to this path
       
   254 	TCapabilitySet requiredCapabilities = SecCommonUtils::FileModificationRequiredCapabilitiesL(filePath, aMsg.SecureId());
       
   255 	
       
   256 	TBool result = EFalse;
       
   257 	TBool allFilesRequired = requiredCapabilities.HasCapability(ECapabilityAllFiles);
       
   258 	TBool tcbRequired = requiredCapabilities.HasCapability(ECapabilityTCB);
       
   259 	
       
   260 	// Test whether the client has at least one of the required capabilities
       
   261 	if (allFilesRequired)
       
   262 		result = aMsg.HasCapability(ECapabilityAllFiles);
       
   263 	if (!result && tcbRequired)
       
   264 		result = aMsg.HasCapability(ECapabilityTCB);
       
   265 	if (!allFilesRequired && !tcbRequired)
       
   266 		result = ETrue;
       
   267 	
       
   268 	CleanupStack::PopAndDestroy(&filePath);
       
   269 	return result;
       
   270 	}	
       
   271 }//end of namespace Usif