namespace Usif { static const TUint stsServerRangeCount = 5; static const TInt stsServerRanges[stsServerRangeCount] = { 0, //Range 0 - 0 to EBaseSession-1. Not used. CScsServer::EBaseSession, //Range 1 - EBaseSession to (EBaseSession+ERegisterNew)-1. ==> from ECreateTransaction to EGetId inclusive CScsServer::EBaseSession|static_cast<TInt>(ERegisterNew), //Range 2 - (EBaseSession+ERegisterNew) to (EBaseSession+ERollBackAllPending)-1 ==> from ERegisterNew to EOverwrite inclusive CScsServer::EBaseSession|static_cast<TInt>(ERollBackAllPending), //Range 3 - (EBaseSession+ERollBackAllPending) to ((EBaseSession+ERollBackAllPending)+1)-1==> only ERollBackAllPending CScsServer::EBaseSession|static_cast<TInt>(ERollBackAllPending)+1 //Range 4 - (EBaseSession+ERollBackAllPending)+1 to KMaxTInt inclusive (i.e: ScsImpl::EPreCloseSession) }; static const TUint8 stsServerElementsIndex[stsServerRangeCount] = { CPolicyServer::ENotSupported, // Range 0 : is not supported. CPolicyServer::EAlwaysPass, // Range 1 CPolicyServer::ECustomCheck, // Range 2 : custom check will be made made for each function to see if client is authorised to do that 0, // Range 3 : Can only be issued by KUidDaemon CPolicyServer::EAlwaysPass // Range 4 }; static const CPolicyServer::TPolicyElement stsServerElements[] = { {_INIT_SECURITY_POLICY_S0(KUidDaemon), CPolicyServer::EFailClient}, //special handling of function ERollBackAllPending }; static const CPolicyServer::TPolicy stsServerPolicy = { CPolicyServer::EAlwaysPass, // Allow all connects stsServerRangeCount, stsServerRanges, stsServerElementsIndex, stsServerElements, }; // //CStsServer // CStsServer::CStsServer() /** Intializes the STS server object with its version and policy. */ : CScsServer(TVersion(KStsVerMajor, KStsVerMinor, KStsVerBuild),stsServerPolicy) { //empty } CStsServer::~CStsServer() /** Destructor. Cleanup the STS server. */ { iTransactionWrapperContainer.ResetAndDestroy(); } CStsServer* CStsServer::NewLC() /** Factory function allocates new, initialized instance of CStsServer. @return New, initialized instance of CStsServer which is left on the cleanup stack. */ { CStsServer *so = new (ELeave) CStsServer(); CleanupStack::PushL(so); so->ConstructL(); return so; } void CStsServer::ConstructL() /** Second phase constructor starts the STS server. */ { // Roll back all previous transactions in case the STS process died unexpectedly // Note: error returned from RollBackAllPendingL() is ignored at this point to prevent STS server startup from failing // 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 TRAP_IGNORE(RollBackAllPendingL()); CScsServer::ConstructL(KStsServerShutdownPeriod); StartL(KStsServerName); } CScsSession* CStsServer::DoNewSessionL(const RMessage2& aMessage) /** Implement CStsServer by allocating a new instance of CStsServerSession. @param aMessage Standard server-side handle to message. @return New instance of CStsServerSession which is owned by the caller. */ { return CStsServerSession::NewL(*this, aMessage); } void CStsServer::RollBackAllPendingL() /** Rolls back all pending transactions that have persistent information stored in the transaction path in the file system. Important note: this function can only be invoked if there are no active transactions in the server as it is not intended to roll back active transactions. (ie: intended to be invoked at boot-up time and STS start up only) */ { if(iTransactionWrapperContainer.Count()!=0) { User::Leave(KErrInUse); //there can be no active transaction when this function is invoked } CIntegrityServices::RollbackAllL(); } TInt TransactionWrapperLinearOrderByIdKey(const TStsTransactionId *id, const CReferenceCountedTransactionWrapper &aSecond) { return *id-aSecond.TransactionId(); } TInt TransactionWrapperLinearOrder(const CReferenceCountedTransactionWrapper &aFirst, const CReferenceCountedTransactionWrapper &aSecond) { return aFirst.TransactionId()-aSecond.TransactionId(); } TStsTransactionId CStsServer::CreateTransactionID() { TTime currentTime; TStsTransactionId transactionID; do { currentTime.UniversalTime(); transactionID = I64LOW(currentTime.Int64()); } while(IsExistingTransaction(transactionID)); return transactionID; } TBool CStsServer::IsExistingTransaction(TStsTransactionId aTransactionID) { return (FindActiveTransaction(aTransactionID)>=0); } CIntegrityServices* CStsServer::CreateTransactionL() { TStsTransactionId id = CreateTransactionID(); CReferenceCountedTransactionWrapper* wrapper = CReferenceCountedTransactionWrapper::NewLC(id); iTransactionWrapperContainer.InsertInOrderL(wrapper, TLinearOrder<CReferenceCountedTransactionWrapper>(&TransactionWrapperLinearOrder)); CleanupStack::Pop(wrapper); return wrapper->Attach(); } CIntegrityServices* CStsServer::AttachTransactionL(TStsTransactionId aTransactionID) { TInt pos=FindActiveTransaction(aTransactionID); if(pos>=0) //joining an existing active transaction { return iTransactionWrapperContainer[pos]->Attach(); } User::Leave(KErrNotFound); return 0; } void CStsServer::ReleaseTransactionL(CIntegrityServices* &aTransactionPtr, TBool aMarkAsCompleted /*=EFalse*/) { __ASSERT_DEBUG(aTransactionPtr, User::Invariant()); TInt pos=FindActiveTransaction(aTransactionPtr->TransactionId()); __ASSERT_DEBUG(pos>=0, User::Invariant()); CReferenceCountedTransactionWrapper* wrapper=iTransactionWrapperContainer[pos]; if(aMarkAsCompleted) wrapper->SetCompleted(); //set transaction as completed (this should be done after a succesful commit or rollback) TInt refCount=wrapper->Detach(); __ASSERT_DEBUG(refCount>=0, User::Invariant()); if(refCount==0) { if(!wrapper->IsCompleted()) //do an auto roll back if and only if the transaction has not been committed or rolled-back previously aTransactionPtr->RollBackL(); delete wrapper; iTransactionWrapperContainer.Remove(pos); } aTransactionPtr=0; } /* This function is a slight optimization of CStsServer::ReleaseTransactionL() as it is intended to be called on cleanup of a committed or rolled-back transaction that obviously don't need auto rollbak again. */ void CStsServer::FinaliseTransactionL(CIntegrityServices* &aTransactionPtr) { ReleaseTransactionL(aTransactionPtr, ETrue); } TInt CStsServer::FindActiveTransaction(TStsTransactionId aTransactionID) { return iTransactionWrapperContainer.FindInOrder(aTransactionID, &TransactionWrapperLinearOrderByIdKey); } CPolicyServer::TCustomResult CStsServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/) { TInt functionId(StripScsFunctionMask(aMsg.Function())); CPolicyServer::TCustomResult ret(EFail); switch(functionId) { case ERegisterNew: case ECreateNew: case ERemove: case ERegisterTemporary: case ECreateTemporary: case EOverwrite: ret = CheckIfFileModificationAllowedL(aMsg)? EPass : EFail; break; } return ret; } /*static*/TBool CStsServer::CheckIfFileModificationAllowedL(const RMessage2& aMsg) { RBuf filePath; filePath.CreateL(KMaxFileName); filePath.CleanupClosePushL(); aMsg.ReadL(KFilePathIPCSlot, filePath, 0); // Retrieve the required capabilities for write access to this path TCapabilitySet requiredCapabilities = SecCommonUtils::FileModificationRequiredCapabilitiesL(filePath, aMsg.SecureId()); TBool result = EFalse; TBool allFilesRequired = requiredCapabilities.HasCapability(ECapabilityAllFiles); TBool tcbRequired = requiredCapabilities.HasCapability(ECapabilityTCB); // Test whether the client has at least one of the required capabilities if (allFilesRequired) result = aMsg.HasCapability(ECapabilityAllFiles); if (!result && tcbRequired) result = aMsg.HasCapability(ECapabilityTCB); if (!allFilesRequired && !tcbRequired) result = ETrue; CleanupStack::PopAndDestroy(&filePath); return result; } }//end of namespace Usif
const TInt KOpCodeRanges[KRangeCount] = { KCapabilityCustomCheck, EDbgTrcCmdCodeLast, }; const TUint8 KElementsIndex[KRangeCount] = { CPolicyServer::ECustomCheck, //Custom check for the Trk SID 0 - ETrkTcbCmdCodeLast CPolicyServer::ENotSupported, //Not Supported ETrkTcbCmdCodeLast-End }; const CPolicyServer::TPolicyElement KPolicyElements[] = { {_INIT_SECURITY_POLICY_S0(TRK_SID), CPolicyServer::EFailClient}, }; const CPolicyServer::TPolicy KDbgTrcServerPolicy = { CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass KRangeCount, KOpCodeRanges, KElementsIndex, // what each range is compared to KPolicyElements // what policies range is compared to }; #endif //
namespace UserPromptService { static const TInt upsPolicyRangeCount = 8; static const TInt upsPolicyRanges[upsPolicyRangeCount] = { 0, // Range 0 - 0 to EBaseSession-1 // Not used CScsServer::EBaseSession, // Range 1 - EBaseSession to EBaseSession | EMngmntRead-1 // // These codes used to create subsessions and to query the policy // authorisation settings. // // (ESessSubsessFromThreadId/EGetClientConfigLength/EGetClientConfigData) // CScsServer::EBaseSession | EMngmntRead, // Range 2 - EBaseSession | EMngmntRead to EBaseSession | EMngmntDelete - 1 // // Management READ APIs // CScsServer::EBaseSession | EMngmntDelete, // Range 3 - EBaseSession | EMngmntDelete to EBaseSession | EMngmntUpdate - 1 // Management DELETE API (ie. delete entire database or selected entries). // CScsServer::EBaseSession | EMngmntUpdate, // Range 4 - EBaseSession | EMngmntUpdate to EBaseSession | ESwiObserver - 1 // Management UPDATE API (ie. change an existing decision). // CScsServer::EBaseSession | ESwiObserver, // Range 5 - EBaseSession | ESwiObserver to EBaseSubSession - 1 // SWI observer management API. // CScsServer::EBaseSubSession, // Range 6 - EBaseSubSession to EBaseMustAllow-1 // // System Server APIs // Authorise - (ESubsessPreparePrompt/ESubsessExecutePrompt) CScsServer::EBaseMustAllow // Range 7 - EBaseMustAllow to KMaxTInt inclusive // // SCS internal APIs to create subsessions, cancel requests etc. }; static const TUint8 upsPolicyElementsIndex[upsPolicyRangeCount] = { CPolicyServer::ENotSupported, // Range 0 - Not used CPolicyServer::EAlwaysPass, // Range 1 - Subsess and auth policy 0, // Range 2 - Management READ APIs 1, // Range 3 - Management DELETE APIs 2, // Range 4 - Management UPDATE APIs 3, // Range 5 - SWI observer APIs 4, // Range 6 - System Server APIs CPolicyServer::EAlwaysPass // Range 7 - SCS internal }; // 0x102836C3 == Swi::KUidSwiObserver.iUid from swiobserver.h BUT we can not include that because SWI is optional // and we are not! static const TSecureId KSwiObserverSid(0x102836C3); static const CPolicyServer::TPolicyElement upsPolicyPolicyElements[5] = { {_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient}, {_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient}, {_INIT_SECURITY_POLICY_C1(ECapabilityAllFiles), CPolicyServer::EFailClient}, {_INIT_SECURITY_POLICY_S0(KSwiObserverSid), CPolicyServer::EFailClient}, {_INIT_SECURITY_POLICY_C1(ECapabilityProtServ), CPolicyServer::EFailClient} }; static const CPolicyServer::TPolicy upsPolicy = { CPolicyServer::EAlwaysPass, // Allow all connects upsPolicyRangeCount, upsPolicyRanges, upsPolicyElementsIndex, upsPolicyPolicyElements, }; _LIT_SECURITY_POLICY_S0(KAllowUpsServer, KUpsServerUid.iUid); //< Only the UPS server can update the P&S flag used to tell clients to re-read client authorisation policies _LIT_SECURITY_POLICY_C1(KAllowProtServ, ECapabilityProtServ); //< All our system server clients will have ProtServ, so limit reading of the (internal) flag to them. CUpsServer* CUpsServer::NewLC() /** Factory function allocates new, initialized instance of CUpsServer which is left on the cleanup stack. @return New, initialized instance of CUpsServer which is left on the cleanup stack. */ { CUpsServer* self = new(ELeave) CUpsServer(); CleanupStack::PushL(self); self->ConstructL(); return self; } CUpsServer::CUpsServer() /** Initializes the superclass with this server's version. */ : CScsServer(UserPromptService::Version(), upsPolicy), iPolicyCache(iFs), iDbHandle(iFs) { // empty. } void CUpsServer::ConstructL() /** Second-phase construction initializes the superclass and starts the server. */ { CScsServer::ConstructL(UserPromptService::KShutdownPeriodUs); User::LeaveIfError(iFs.Connect()); TInt r = RProperty::Define(KUpsServiceConfigProperty, RProperty::EInt, KAllowProtServ, KAllowUpsServer); if(r != KErrAlreadyExists) { User::LeaveIfError(r); } iSwiWatcher = CSwiWatcher::NewL(*this); SetupL(); StartL(UserPromptService::KUpsServerName); } void CUpsServer::SetupL() /** Setup memory variables which are not already setup. Used during intial construction and after a call to FreeUncompressableMemory. */ { if(!iPolicyCache.IsOpen()) { iPolicyCache.OpenL(); } if(!iPluginManager) { iPluginManager = CPluginManager::NewL(); } // Create/Open the database if(!iDbHandle.IsOpen()) { iDbHandle.OpenL(); } if(!iFlurryQueue) { iFlurryQueue = CAuthoriserFifo::NewL(); } if(!iFlurryQueueBeingProcessed) { iFlurryQueueBeingProcessed = CAuthoriserFifo::NewL(); } } void CUpsServer::FreeUncompressableMemory() /** Frees memory which can not be compressed down to a known level for OOM testing. */ { iDbHandle.Close(); if(iPluginManager) { iPluginManager->Unload(); delete iPluginManager; iPluginManager = 0; } iPolicyCache.Release(); } CUpsServer::~CUpsServer() /** Cleanup the server, in particular close the RFs session. */ { iDisputed.Close(); (void) RProperty::Delete(KUpsServiceConfigProperty); delete iFlurryQueueBeingProcessed; iFlurryQueueBeingProcessed = 0; delete iFlurryQueue; iFlurryQueue = 0; FreeUncompressableMemory(); delete iSwiWatcher; iSwiWatcher = 0; iFs.Close(); } CScsSession* CUpsServer::DoNewSessionL(const RMessage2& /*aMessage*/) /** Implement CScsServer by allocating a new instance of CUpsSession. @param aMessage Standard server-side handle to message. Not used. @return New instance of CUpsSession which is owned by the caller. */ { return CUpsSession::NewL(*this); } void CUpsServer::DoPreHeapMarkOrCheckL() /** This function is called by the framework just before settingchecking a heap mark. We need to compress/free memory down to a state which should be the same both before and after the test operations. */ { #ifdef _DEBUG if(iAsyncRequests.Count() != 0) { User::Leave(KErrServerBusy); } iDisputed.Compress(); iFlurryQueue->Compress(); iFlurryQueueBeingProcessed->Compress(); FreeUncompressableMemory(); #endif } void CUpsServer::DoPostHeapMarkOrCheckL() /** Called immediately after setting/checking the heap mark and therefore just after DoPreHeapMarkOrCheckL. This function needs to re-allocate uncompressable data structures which were destroyed by DoPreHeapMarkOrCheckL. */ { #ifdef _DEBUG SetupL(); #endif } void CUpsServer::GateKeeperL(CAuthoriser *aAuthoriser) /** If no dialog is in progress, the server will note one is in progress, and tell the aAuthoriser it can continue (by calling ClearedToDisplayL). Whenever a CAuthoriser finishes it MUST call our AuthoriserDone function. This will allow us to cleanup our queues and clear the next dialog to display. If a dialog is already in progress, the the aAuthoriser will be added to iFlurryQueue for later processing. @param aAuthoriser to queue */ { if(iCurrentDialog) { // Add to queue of requests requiring re-processing later. This includes requests which want to display // a dialog and ones which matches a recordId which is under dispute (i.e. Where ForcePrompt has been // called and returned yes, but the prompt hasn't been displayed yet). iFlurryQueue->PushL(aAuthoriser); return; } iCurrentDialog = aAuthoriser; iCurrentDialog->ClearedToDisplayL(); } void CUpsServer::AuthoriserDone(CAuthoriser *aAuthoriser) /** See CUpsServer::AuthoriserDoneL for documentation. */ { TRAP_IGNORE(AuthoriserDoneL(aAuthoriser)); } void CUpsServer::AuthoriserDoneL(CAuthoriser *aAuthoriser) /** The CAuthoriser has either completed the request, been cancelled, or failed somehow. If it is in either FIFO it needs removing. If it is the current display dialog, then we need to check the FIFOs, and maybe swap them, and call WakeupNextPending. */ { // Remove from lists. // Note the FIFO object does NOT leave if the object is not found. iFlurryQueue->RemoveL(aAuthoriser); iFlurryQueueBeingProcessed->RemoveL(aAuthoriser); if(aAuthoriser == iCurrentDialog) { iCurrentDialog = 0; if(iFlurryQueueBeingProcessed->IsEmpty()) { // Swap queues CAuthoriserFifo *tmp = iFlurryQueue; iFlurryQueue = iFlurryQueueBeingProcessed; iFlurryQueueBeingProcessed = tmp; } WakeupNextPendingL(); } } void CUpsServer::WakeupNextPendingL() /** This function does the following:- 1) If iFlurryQueueBeingProcessed is empty it returns. 2) Removes the first authoriser from iFlurryQueueBeingProcessed and calls SetPending to mark it as no longer pending. 3) Increases its priority to EPriorityUserInput (this makes sure it will be handled ahead of any incoming requests) 4) Sets it active and completes it so it runs. It will run BEFORE any incoming requests. The first thing it must do is call this function again. This ensures all pending requests are re-processed in order. Normally it will then re-lookup its fingerprints in the database, if found it may complete client request. If it decides it still needs to display a dialog it should call GateKeeper again. */ { if(iFlurryQueueBeingProcessed->IsEmpty()) { return; } CAuthoriser *authoriser = iFlurryQueueBeingProcessed->PopL(); // Set priority of authoriser to EPriorityHigh-1. This is higher // than any incoming work, but lower than deferred deletes. authoriser->SetPriority(CActive::EPriorityHigh - 1); authoriser->Wakeup(); } void CUpsServer::DisputeRecordIdL(TUint32 aRecordId) /** Add the specified record to the list of disputed record IDs. */ { DEBUG_PRINTF2(_L8("CUpsServer::DisputeRecordIdL(%d)\n"), aRecordId); User::LeaveIfError(iDisputed.InsertInOrder(aRecordId)); } void CUpsServer::UnDisputeRecordIdL(TUint32 aRecordId) /** Deletes the specified record from the list of disputed record IDs. */ { DEBUG_PRINTF2(_L8("CUpsServer::UnDisputeRecordIdL(%d)\n"), aRecordId); TInt i = iDisputed.FindInOrderL(aRecordId); User::LeaveIfError(i); iDisputed.Remove(i); } TBool CUpsServer::IsRecordIdDisputed(TUint32 aRecordId) const /** Checks if the specified record is under dispute. A record is disputed if the evaluator ForcePromptL call for a match on that record return ETrue to force a prompt to be displayed. */ { TBool disputed = iDisputed.FindInOrder(aRecordId) >= 0; //RDebug::Printf("CUpsServer::IsRecordIdDisputed(%d) - returning %s\n", // aRecordId, // (disputed)?("EFalse"):("EFalse")); return disputed; } // // Implementation of CSwiWatcher // CSwiWatcher *CSwiWatcher::NewL(CUpsServer &aUpsServer) { CSwiWatcher *self = new(ELeave) CSwiWatcher(aUpsServer); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(self); return self; } CSwiWatcher::CSwiWatcher(CUpsServer &aUpsServer) : CActive(CActive::EPriorityHigh), iUpsServer(aUpsServer) { CActiveScheduler::Add(this); } void CSwiWatcher::ConstructL() /** Subscribe for notification for writes to the SWI P&S property. We do not check the actual value because it is not guaranteed that we will run for every change. */ { User::LeaveIfError(iSwiProperty.Attach(KUidSystemCategory, KSAUidSoftwareInstallKeyValue)); iSwiProperty.Subscribe(iStatus); SetActive(); } void CSwiWatcher::RunL() /** SWI has changed state, so unload any unused plugins. We do this for EVERY state change which we manage to run for, which is overkill, but the unload call is cheap/free if there are no plugins which require unloading. */ { User::LeaveIfError(iStatus.Int()); iSwiProperty.Subscribe(iStatus); SetActive(); // Tell the plugin manager to unload plugins which are NOT in use. iUpsServer.iPluginManager->Unload(); } void CSwiWatcher::DoCancel() { iSwiProperty.Cancel(); } CSwiWatcher::~CSwiWatcher() { Cancel(); iSwiProperty.Close(); } } // End of namespace UserPromptService
EASAltOpCodeLast, }; const TUint8 KElementsIndex[KRangeCount] = { CPolicyServer::EAlwaysPass, //Always passing no capability required (Notify, NotifyCancel) KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (Visible,SetState, SetAlarm, SetDeferTime) CPolicyServer::EAlwaysPass, //Always passing no capability required (GetUserTime, Logon) KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (StartPlayingSound, StopPlayingSound, VisibleAll, SetStateAll, StopPlayingSoundAll, DeleteAlarm) CPolicyServer::EAlwaysPass, //Always passing no capability required (GetEndQuietTime, GetMaxAlarms) CPolicyServer::ENotSupported, //Not Supported [EASAltOpCodeLast-End] }; const CPolicyServer::TPolicyElement KPolicyElements[] = { {_INIT_SECURITY_POLICY_S0(KAlarmServerSid), CPolicyServer::EFailClient} }; const CPolicyServer::TPolicy KEikServAlarmAlertServerPolicy = { CPolicyServer::EAlwaysPass, KRangeCount, KEikServAlarmAlertServerRanges, KElementsIndex, KPolicyElements }; // // class CEikServAlarmAlertServer //
Ranges of policies */ const TInt CDMUtilServer::tcRanges[DMUTILSERVER_NUMBER_OF_POLICIES] = {0, EPerformDMUtilRFS, ERemoveACL}; /** Number of elements */ const TUint8 CDMUtilServer::tcElementsIndex[DMUTILSERVER_NUMBER_OF_POLICIES] = {0, 1, 2}; /** Elements for each range */ const CPolicyServer::TPolicyElement CDMUtilServer::tcElements[DMUTILSERVER_NUMBER_OF_POLICIES] = { { _INIT_SECURITY_POLICY_PASS }, { _INIT_SECURITY_POLICY_S0(0x102073EA) }, // RFs SID { _INIT_SECURITY_POLICY_S0(0x10207814) } }; /** The policy */ CPolicyServer::TPolicy CDMUtilServer::iTcConnectionPolicy = { CPolicyServer::ECustomCheck, // On connection, check for policies 1, tcRanges, tcElementsIndex, tcElements };
Specifies the appropriate action for each range in KRanges. The nth element of KElementsIndex specifies the appropriate action for the nth range in KRanges. */ const TUint8 KElementsIndex[KRangeCount] = { CPolicyServer::ENotSupported, KSsmServerSidCheck, CPolicyServer::ENotSupported, }; /** Array containing the different security checks performed by this server */ const CPolicyServer::TPolicyElement KPolicyElements[] = { {_INIT_SECURITY_POLICY_S0(KSsmServerSid), CPolicyServer::EFailClient} //lint !e778 suppress Constant expression evaluates to 0 in operation '+' }; /** Setup a security policy which requires all caps to be used by the SsmServer for all requests including creating a connection. The caller's SID is matched against SsmServer's SID in each ServiceL call */ const CPolicyServer::TPolicy KSsmSwpPolicyServerPolicy = { KSsmServerSidCheck, // map connection attempts as well to index [0] in KPolicyElements[] KRangeCount, KRanges, KElementsIndex, KPolicyElements };