policymanagement/policyengine/policyengineserver/src/PolicyManager.cpp
changeset 0 b497e44ab2fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/policymanagement/policyengine/policyengineserver/src/PolicyManager.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1285 @@
+/*
+* Copyright (c) 2002-2004 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: Implementation of policymanagement components
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "PolicyManager.h"
+#include "elements.h"
+#include "DataTypes.h"
+#include "PolicyParser.h"
+#include "ElementBase.h"
+#include "PolicyProcessor.h"
+#include "TrustedSession.h"
+#include "ErrorCodes.h"
+#include "OperationParser.h"
+#include "OperationParserConstants.h"
+#include "SettingEnforcementManager.h"
+#include "PolicyEngineServer.h"
+#include "PolicyEngineXACML.h"
+#include "debug.h"
+
+
+#include "DMUtilClient.h"
+#include <PolicyEngineClientServer.h>
+#include <ManagementContext.h>
+
+
+// CONSTANTS
+const TInt KMaxServerIdLength = 250;
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CPolicyManager()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager::CPolicyManager( CPolicyProcessor * aPolicyProcessor)
+	: CActive( EPriorityLow),  iPolicyProcessor( aPolicyProcessor)
+{
+	iPolicyStorage = CPolicyStorage::PolicyStorage();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::~CPolicyManager()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager::~CPolicyManager()
+{
+	//CSettingEnforcementManager
+	delete iSEManager;
+
+	//descriptors used in operations 
+	delete iActiveChildList;
+	delete iActiveXACMLContent;
+	delete iActiveElementList;
+	delete iOperationParser;
+	delete iCurrentManagementCommand;
+	
+	CPolicyEngineServer::RemoveActiveObject( this);
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::ConstructL()
+{
+	CPolicyEngineServer::AddActiveObjectL( this);
+	iSEManager = CSettingEnforcementManager::NewL();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyStorage::NewL()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager * CPolicyManager::NewL( CPolicyProcessor * aPolicyProcessor)
+{
+	CPolicyManager * self = new(ELeave) CPolicyManager( aPolicyProcessor);
+	
+	CleanupStack::PushL( self);
+	self->ConstructL();
+	CleanupStack::Pop( self);
+	
+	return self;
+	
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ExecuteOperationL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::ExecuteOperation( CTrustedSession * aSession, const RMessage2& aMessage)
+{
+	iMessage = &aMessage;
+
+	//Only one management session is accepted
+	if ( CPolicyEngineServer::StatusFlags()->iManagementActive )
+	{
+		CompleteOperation( KErrInUse);
+		return;
+	}
+	
+	CPolicyEngineServer::StatusFlags()->iManagementActive = ETrue;
+
+
+	//set pointer to trusted session and save reference to RMessage
+	iTrustedSession = aSession;
+	
+	//initialize states
+	iOperationStatus = 0;
+	iUseBearerCertificate = EFalse;
+	iCertificateUpdates = EFalse;
+
+	
+	//Add this active object active scheduler	
+	if ( !IsAdded())
+	{
+		CActiveScheduler::Add( this);
+	}
+	
+	//Complete own request
+	SetActive();
+	TRequestStatus * status = &iStatus;
+	User::RequestComplete( status, KErrNone);
+}
+
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::RunL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::RunL()
+{
+	CPolicyEngineServer::SetActiveSubSession( this);	
+
+	//management operations are allowed only when server is free
+ 	if ( CPolicyEngineServer::StatusFlags()->iProcessorActive )
+	{
+		SetActive();
+		TRequestStatus * status = &iStatus;
+		User::RequestComplete( status, KErrNone);
+		return;		
+	}
+
+	if ( iOperationStatus == 0)
+	{
+		//Start management session for next operations
+		iPolicyStorage->StartCommitSessionL();
+	
+		iCurrentManagementCommand = HBufC8::NewL( iMessage->GetDesLength(0));
+		//Read policy description	
+		TPtr8 ptr = iCurrentManagementCommand->Des(); 
+		iMessage->ReadL(0, ptr, 0);
+		iOperationParser = COperationParser::NewL( ptr);
+	
+		//parse operations, "iMsg" stores error message
+		iOperationParser->ParseOperationsL( iMsg);
+	}
+	else if ( (iOperationStatus - 1) < iOperationParser->OperationCount())
+	{
+		//Execute operations, "this" is pointer to callback function 
+		iCertificateUpdates = EFalse;
+		iOperationParser->ExecuteL( iOperationStatus - 1, this);
+		
+		if ( iCertificateUpdates)
+		{
+			CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+		}			
+	}
+	
+	if ( iOperationStatus == iOperationParser->OperationCount() + 2)
+	{
+		//Finish management session and commit changes in repository
+		iMsg = ManagementErrors::OperationOk;
+		
+		if ( iStatus.Int() == KErrNone)
+		{
+			CommitChangesL();	
+			CompleteOperation( iStatus.Int());
+			CPolicyStorage::PolicyStorage()->ReleaseElements();
+		}
+		else
+		{
+			RunError( iStatus.Int());			
+		}
+		
+	}
+	else
+	if ( iOperationStatus == iOperationParser->OperationCount() + 1)
+	{
+		//Make setting enforcements...
+		MakeEnforcementL( KErrNone);
+	}
+	else
+	{
+		SetActive();
+		TRequestStatus * status = &iStatus;
+		User::RequestComplete( status, KErrNone);
+	}
+
+	iOperationStatus++;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::DoCancel()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::DoCancel()
+{
+	RunError( KErrAbort);
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::DoCancel()
+// -----------------------------------------------------------------------------
+//
+
+TInt CPolicyManager::RunError( TInt aError)
+{
+	RDEBUG("CPolicyManager::RunError");
+	RDEBUG8_2("Policy engine operation error message: %S", &iMsg);
+
+	//restores possible changes in policy storage
+	TRAPD( err, iPolicyStorage->CommitChangesL( EFalse))
+	
+	if ( err != KErrNone )
+	{
+		aError = err;	
+	}
+
+	//complete operation
+	CompleteOperation( aError);	
+	
+	return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::MakeEnforcementL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::MakeEnforcementL( TInt aError)
+{
+	//initialize enforcement session
+	iSEManager->StartEnforcementSessionL( iStatus, iTrustedSession->SessionCertificate());
+
+	//get modified elements 
+	iPolicyStorage->GetEditedElementsL( iSEManager);
+	
+	//start enforcement session enforcement policies
+	if ( aError == KErrNone)
+	{
+		iSEManager->ExecuteEnforcementSessionL();
+	}
+
+	
+	//set active (waiting for enforcement completing)
+	SetActive();	
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CompleteOperation()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::CompleteOperation( TInt aError )
+	{
+	RDEBUG_2("CPolicyManager::CompleteOperation( %d )", aError );
+
+	if( aError != KErrNone && aError != KErrParser && KErrOpParser != aError && KErrPolicyManager != aError)
+		{
+		iMsg = KNullDesC8;
+		aError = KErrGeneral;
+		}
+	else
+		{
+		aError = KErrNone;
+		}
+
+	//finish storage session and enforcement session
+	iPolicyStorage->ResetEditableMemory();
+	iSEManager->EndEnforcementSession( KErrNone == aError );
+
+	if ( iCertificateUpdates )
+		{
+		CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+		}	
+
+	CPolicyEngineServer::StatusFlags()->iManagementActive = EFalse;
+	
+	//release resources
+	delete iOperationParser;
+	iOperationParser = NULL;
+	delete iCurrentManagementCommand;
+	iCurrentManagementCommand = NULL;
+
+	//write return message to client process
+	TParserResponse response( iMsg);
+	TPckgC<TParserResponse> retPack(response);
+	TRAPD( err, iMessage->WriteL( 1, retPack ) );
+	if( err != KErrNone )
+		{
+		iMessage->Complete( err );
+		return;
+		}
+
+	iMessage->Complete( aError);
+	}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::UpdateStateFlags()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::UpdateStateFlagsL()
+{
+	RDEBUG("CPolicyManager::UpdateStateFlagsL - start");
+
+	RDMUtil dmutil;
+	User::LeaveIfError( dmutil.Connect());
+	CleanupClosePushL( dmutil);
+	TBool securityActive = EFalse;
+	User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( EPolicyChanged));
+	
+	//Check is terminal security activated
+	CElementBase * iElement = iPolicyStorage->GetElementL( PolicyLanguage::Constants::RolesMappingPolicy);	
+	if (iElement)
+	{
+		TElementReserver reserver(iElement);
+
+		iPolicyStorage->CheckElementL(iElement);
+
+		
+		//check child elements, any rule child means that terminal security is acticated
+		for (TInt i(0); i < iElement->ElementCount(); i++) {
+			CElementBase * element = iElement->Element(i);
+
+			if (element->ElementType() == ERule) {
+				RDEBUG("CPolicyManager::UpdateStateFlagsL -> securityActive = ETrue");
+				securityActive = ETrue;
+				break;
+			}
+		}
+		reserver.Release();
+	}
+	
+	//update policy management flags	
+	if ( securityActive)
+	{
+		User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( ETerminalSecurityActive));
+	}
+	else
+	{
+		User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( ETerminalSecurityDeactive));
+	}
+
+	
+	CleanupStack::PopAndDestroy( &dmutil);
+
+	RDEBUG("CPolicyManager::UpdateStateFlagsL - end");
+}
+
+
+
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CommitChangesL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::CommitChangesL()
+{
+	//Accept or decline changes to storage...
+	iPolicyStorage->SaveEditableMemoryL();
+
+	//This ensures that enforcement settings are committed
+	iSEManager->CommitChanges();	
+		
+	//This ensures that all changes are commited (also enforcement)
+	iPolicyStorage->CommitChangesL( ETrue);	
+	
+	//update state flags
+	UpdateStateFlagsL();
+	
+	RDEBUG8_2("Policy engine operation message: %S", &iMsg);
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::NewPolicy()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::NewElementL( const TInt& aLineOffset, const TDesC8& aTargetElement, const TDesC8& aElementDescription, const TBool& aUseBearerCertificate )
+{
+	RDEBUG("PolicyEngineServer: CPolicyManager::NewElementL");
+
+	//initialize policy parser...
+	CPolicyParser * parser = CPolicyParser::NewL( iPolicyStorage);
+	CleanupStack::PushL( parser);
+	parser->SetExternalIdChecked( KNoExternalIdConflictsAllowed);
+	parser->SetLineOffset( aLineOffset);
+	iUseBearerCertificate = aUseBearerCertificate;
+
+	//Parse native model from XACML description
+	TInt err(KErrNone);	
+	TBuf8<KMaxReturnMessageLength> msg;
+	CElementBase * element = parser->ParseXACMLObjects( err, aElementDescription, msg);	
+	CleanupStack::PopAndDestroy( parser); //Parser
+
+	if ( err != KErrNone )
+	{
+		iMsg = msg;
+		User::Leave( KErrParser);	
+	}
+	
+
+	//Add element to policy storage (storage take responsibility to delete object)
+	RDEBUG_2("PolicyEngineServer: Element parsed and id created(id %d)", element->GetId());
+
+	element->CreateIdL();
+	element->CreateExternalId();
+	iPolicyStorage->AddNewElementL( element);
+	TElementReserver newElement( element);
+		
+	//Check is the policy valid and if so, add element to temporary storage
+	AssignElementL( aTargetElement, element);
+	
+	newElement.Release();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ReplaceElementL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::ReplaceElementL( const TInt& aLineOffset, const TDesC8& aTargetElement, const TDesC8& aElementDescription )
+{
+	RDEBUG("PolicyEngineServer: CPolicyManager::ReplaceElementL");
+
+	//initialize policy parser...
+	CPolicyParser * parser = CPolicyParser::NewL( iPolicyStorage);
+	CleanupStack::PushL( parser);
+	parser->SetExternalIdChecked( KSameExternalIdAllowedForRoot);
+	parser->SetLineOffset( aLineOffset);
+
+	//Parse native model from XACML description
+	TInt err(KErrNone);	
+	TBuf8<KMaxReturnMessageLength> msg;
+	CElementBase * element = parser->ParseXACMLObjects( err, aElementDescription, msg);	
+	CleanupStack::PopAndDestroy( parser); //Parser
+
+	if ( err != KErrNone )
+	{
+		iMsg = msg;
+		User::Leave( KErrParser);	
+	}
+	
+
+	//Add element to policy storage (storage take responsibility to delete object)
+	RDEBUG_2("PolicyEngineServer: Element parsed and id created(id %d)", element->GetId());
+
+	element->CreateIdL();
+	element->CreateExternalId();
+	iPolicyStorage->AddNewElementL( element);
+	TElementReserver newElement( element);
+		
+	//Check is the policy valid and if so, add element to temporary storage
+	ReAssignElementL( aTargetElement, element);
+	
+	newElement.Release();
+	
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AssignPolicyL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::AssignElementL( const TDesC8& aTargetElement, CElementBase * aElement)
+{
+	RDEBUG("PolicyEngineServer: CPolicyManager::AssignElementL");
+
+	//get parent element and load it
+	CElementBase * parentElement = iPolicyStorage->GetEditableElementL( aTargetElement);
+
+	//if parent eleemnt is valid
+	if ( !parentElement)
+	{
+		RDEBUG("PolicyEngineServer: Target element not found");
+		iMsg = ManagementErrors::ElementNotFound;
+		User::Leave( KErrPolicyManager);
+	}
+	
+	TElementReserver assignReserver( parentElement);
+	iPolicyStorage->CheckElementL( parentElement);
+
+	//add parant id to components
+	aElement->AddParentIdL( parentElement->GetId());
+
+	//Check is assignment acceptable
+	IsAssigmentAcceptableL( parentElement, aElement, ETrue);
+	assignReserver.Release();
+	
+
+	//Add element to parent element, check is assigment valid
+	parentElement->AddIdElementL( aElement);
+	parentElement->iElementState = EEditedElement;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AssignPolicyL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::ReAssignElementL( const TDesC8& aTargetElement, CElementBase * aElement)
+{
+	RDEBUG("PolicyEngineServer: CPolicyManager::ReAssignElementL");
+
+	//get replaced element and load it
+	CElementBase * replacedElement = iPolicyStorage->GetEditableElementL( aTargetElement);
+
+	//check that element is valid
+	if ( !replacedElement)
+	{
+		RDEBUG("PolicyEngineServer: Target element not found");
+		iMsg = ManagementErrors::ElementNotFound;
+		User::Leave( KErrPolicyManager);
+	}
+	
+	//Check element
+	TElementReserver assignReserver( replacedElement);
+	iPolicyStorage->CheckElementL( replacedElement);
+
+	//copy parents to new element
+	aElement->AddParentIdL( replacedElement->iParentId);
+		
+	//Get parent elements
+	CElementBase * parentElement = iPolicyStorage->GetEditableElementL( replacedElement->iParentId);
+	
+	//check that element is valid
+	if ( !parentElement)
+	{
+		iMsg = ManagementErrors::ElementNotFound;
+		User::Leave( KErrPolicyManager);
+	}
+		
+	//Check element
+	TElementReserver parentReserver( parentElement);
+	iPolicyStorage->CheckElementL( parentElement);
+
+	//Check is reassignment acceptable
+	IsAssigmentAcceptableL( parentElement, aElement, EFalse);
+
+	//remove child from parent child list
+	parentElement->RemoveChild( replacedElement->GetId());
+	
+	//Add element to parent element and mark to modified
+	parentElement->AddIdElementL( aElement);
+	parentElement->iElementState = EEditedElement;
+	
+	//When edited element list is committed all "EDeletedEditableElement"s will be deleted...
+	replacedElement->DeleteMarkRecursiveL();
+
+	
+	
+	
+	parentReserver.Release();
+	assignReserver.Release();
+}
+// -----------------------------------------------------------------------------
+// CPolicyManager::RemoveElementL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::RemoveElementL( const TDesC8& aTargetElement)
+{
+	RDEBUG("CPolicyManager::RemoveElementL");
+
+
+	iMsg = ManagementErrors::OperationOk;
+
+	//get parent element and load it
+	CElementBase * element = iPolicyStorage->GetEditableElementL( aTargetElement);
+	
+	//error if element not found
+	if ( !element )
+	{
+		RDEBUG("PolicyEngineServer: Target element not found");
+		iMsg = ManagementErrors::ElementNotFound;
+		User::Leave( KErrPolicyManager);	
+	}
+
+
+	TElementReserver elementReserver( element);
+	iPolicyStorage->CheckElementL( element);
+
+
+	if ( element->iParentId)
+	{
+		//Remove element reference from parent element
+
+		CElementBase * parentElement = iPolicyStorage->GetEditableElementL( element->iParentId);
+		__ASSERT_ALWAYS ( parentElement, User::Panic( Panics::PolicyManagerPanic, KErrGeneral));
+			
+		//check element, use editable cache
+		TElementReserver elementReserver( parentElement);
+		iPolicyStorage->CheckElementL( parentElement);
+		
+		IsRemoveAcceptableL( parentElement, element );
+
+		TInt err = parentElement->RemoveChild( element->GetId());
+	
+		if ( err != KErrNone )
+		{
+			User::Leave( KErrPolicyManager);	
+		}
+		
+		parentElement->iElementState = EEditedElement;
+		
+		elementReserver.Release();
+	}
+	
+	//When edited element list is committed all "EDeletedEditableElement" will be deleted...
+	element->DeleteMarkRecursiveL();
+	
+	elementReserver.Release();
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::IsAssigmentAcceptable()
+// -----------------------------------------------------------------------------
+//
+
+
+void CPolicyManager::IsAssigmentAcceptableL( CElementBase * aParentElement, CElementBase * aElement, TBool aNewElement)
+{
+	RDEBUG("CPolicyManager::IsAssigmentAcceptableL");
+
+	using namespace PolicyLanguage::Constants;
+	using namespace AttributeContainerHelper;
+	using namespace PolicyLanguage::NativeLanguage::AttributeValues;
+	
+	//return if policy check is not needed
+	NO_POLICY_CHECK_RETURN;
+	RDEBUG_3("CPolicyManager: Parent element (%d) element (%d)", aParentElement->GetId(), aElement->GetId());
+
+	HBufC8* extId = aParentElement->ExternalId();
+	TInt match = extId->CompareF( PolicyLanguage::Constants::RolesMappingPolicy );
+	if( (match == 0) && aNewElement )
+	{
+		RDEBUG("CPolicyManager: Parent element is RolesMappingPolicy. Adding trust for server");
+		TInt rolesElements = aParentElement->GetChildElementCountL();
+				
+		RDEBUG_2("CPolicyManager: rolesElements count (%d)", rolesElements);
+		if( rolesElements >= 1 )
+		{ 
+			RDEBUG("CPolicyManager: Trust already exists");
+			iMsg = ManagementErrors::AccessDenied;
+			User::Leave( KErrPolicyManager);
+		}				
+		RDEBUG("CPolicyManager: No trust created yet");
+	}
+	//setup request context
+	iPolicyProcessor->ResetRequestContext();
+	iPolicyProcessor->SetTargetElement( aElement);
+	iPolicyProcessor->SetSessionTrust( iTrustedSession);
+	
+	//attribute list for request attributes
+	RAttributeContainer attributes;
+	CleanupClosePushL( attributes);
+	
+	//action attributes for meta_policy_Set	
+	if ( aNewElement)
+	{
+		attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, AddPolicy, StringDataType));
+	}
+	else
+	{
+		attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, ReplacePolicy, StringDataType));
+	}
+
+	//Trusted subject is either trustedsubject of session or trustedsubject used in element to be added.
+	//In a cases where new element contains trustedsubject, it is used. Other cases sessions trustedsubject
+	
+	//Get new element subjectmatch-elements
+	RElementArray subjectMatches;
+	CleanupClosePushL( subjectMatches);
+	aElement->FindAttributesL( ESubjectMatch, subjectMatches);
+	
+	//util variables
+	TPtrC8 trustedSubject( KNullDesC8);
+	TBool oneTrustedSubject = EFalse;
+		
+	//add trusted subject from target element
+	for ( TInt i(0); i < subjectMatches.Count(); i++)
+	{
+		CMatchObject* subjectMatch = (CMatchObject*) subjectMatches[i];
+		
+		//check attribute id (Certificate id is also trusted subject!)
+		TPtrC8 attributeId = subjectMatch->AttributeDesignator()->GetAttributeid();
+		if ( attributeId == PolicyEngineXACML::KTrustedSubject || attributeId == PolicyEngineXACML::KCertificate  )
+		{
+			//Only one target policy is valid
+			if ( oneTrustedSubject && trustedSubject.Compare( subjectMatch->AttributeValue()->Data()->Value()) != 0)
+			{
+				iMsg = ParserErrors::InvalidElement;
+				User::Leave( KErrPolicyManager);				
+			}
+		
+			oneTrustedSubject = ETrue;
+
+			//add trusted subject to attribute list
+			trustedSubject.Set( subjectMatch->AttributeValue()->Data()->Value());
+			
+			//certificates have to be transformed to CASN form
+			if ( attributeId == PolicyEngineXACML::KCertificate)
+			{
+				//create CSubject info
+				CCertificateMaps::CSubjectInfo* info = new (ELeave) CCertificateMaps::CSubjectInfo();
+				CleanupStack::PushL( info);
+				
+				//parse CASN info from certificate and add TargetTrustedSubject attribute with CASN value				
+				CCertificateMaps::CreateSubjectInfoL( info, trustedSubject);
+				attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, *info->iCASN, StringDataType));
+				CleanupStack::PopAndDestroy( info);
+			}
+			else
+			{
+				attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, trustedSubject, StringDataType));
+			}
+			
+		}
+	}
+	CleanupStack::PopAndDestroy( &subjectMatches);	//subjectMatches
+	
+	
+	
+	if ( iUseBearerCertificate )
+	{
+		if ( !iTrustedSession->CertificatedSession())
+		{
+			RDEBUG("PolicyEngineServer: Certificated session is required");
+			//when bearer certificate is used, session must be certificated
+			iMsg = ManagementErrors::SessionMustBeCertificated;
+			User::Leave( KErrPolicyManager);				
+		}
+	
+		//add certificate mapping for alias, certificate (TCertInfo) is available inside of trusted session
+		CElementBase * rule = iTrustedSession->CreateCertificateMappingL( trustedSubject);
+		CleanupStack::PushL( rule);
+		
+		if ( !rule)
+		{
+			RDEBUG("PolicyEngineServer: Invalid certificate!");
+			iMsg = ManagementErrors::InvalidCertificateMapping;
+			User::Leave( KErrPolicyManager);
+		}
+		else
+		{
+			rule->CreateIdL();
+			rule->CreateExternalId();
+			iPolicyStorage->AddNewElementL( rule);
+			
+			RDEBUG_2("PolicyEngineServer: Auto certifate created (id %d)", rule->GetId());
+			
+			//add parant id to cert policy
+			CElementBase* certMappingPolicy = iPolicyStorage->GetEditableElementL( CertMappingPolicy);
+			//if element is not valid
+			if (!certMappingPolicy)
+			{
+				return;
+			}
+			TElementReserver certReserver( certMappingPolicy);
+			iPolicyStorage->CheckElementL( certMappingPolicy);
+
+			rule->AddParentIdL( certMappingPolicy->GetId());
+
+			//Add element to parent element, check is assigment valid
+			certMappingPolicy->AddIdElementL( rule);
+			certMappingPolicy->iElementState = EEditedElement;
+			
+						
+			certReserver.Release();		
+						
+			CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+			iCertificateUpdates = ETrue;			
+		}
+		CleanupStack::Pop( rule);	
+	}
+	
+
+	//add session trusted subject
+	if ( iTrustedSession->CertificatedSession())
+	{
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KTrustedSubject, iTrustedSession->CASNForSessionL(), StringDataType));
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KRoleId, iTrustedSession->CASNForSessionL(), StringDataType));
+	}
+	else
+	{
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KSubjectId, iTrustedSession->SIDForSession(), StringDataType));
+	}
+
+	//certificate mapping must be checked first!! 
+	if ( *aParentElement->ExternalId() == CertMappingPolicy)
+	{
+		TBool validCertificate = EFalse;
+		TRAPD( err, validCertificate = iTrustedSession->IsCertificateMappingValidL( aElement))
+	
+		if ( !validCertificate || err != KErrNone)
+		{
+			RDEBUG("PolicyEngineServer: Invalid certificate mapping!");
+			iMsg = ManagementErrors::InvalidCertificateMapping;
+			User::Leave( KErrPolicyManager);
+		}
+		
+		iCertificateUpdates = ETrue;
+	}
+	
+	
+	//parent element for new policy
+	attributes.AppendL( EResourceAttributes, CAttribute::NewL( PolicyTargetAttr, *aParentElement->ExternalId(), StringDataType));
+
+	//make request
+	TMatchResponse response;
+
+	RDEBUG("CPolicyManager - Start request execution");
+	iPolicyProcessor->ExecuteRequestL( attributes, response);
+	RDEBUG("CPolicyManager - End request execution");
+		
+	CleanupStack::PopAndDestroy( &attributes);
+	RDEBUG("CPolicyManager - CleanupStack::PopAndDestroy( &attributes);");
+
+	if ( response != EPermit)
+	{
+		RDEBUG("CPolicyManager - Access denied");
+		iMsg = ManagementErrors::AccessDenied;
+		User::Leave( KErrPolicyManager);
+	}
+		
+	//add current DM session server id to list which defines server ids which DM operations are silent.
+	if ( iUseBearerCertificate)
+	{
+		AddSilentDMOperationServerIdL();
+	}
+		
+}
+	
+// -----------------------------------------------------------------------------
+// CPolicyManager::IdRemoveAcceptableL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::IsRemoveAcceptableL( CElementBase* aParentElement, CElementBase* aElement )
+	{
+	RDEBUG("CPolicyManager::IsRemoveAcceptableL");
+
+	using namespace PolicyLanguage::Constants;
+	using namespace AttributeContainerHelper;
+	using namespace PolicyLanguage::NativeLanguage::AttributeValues;
+
+	//return if policy check is not needed
+	NO_POLICY_CHECK_RETURN;
+	
+	//setup request context
+	iPolicyProcessor->ResetRequestContext();
+	iPolicyProcessor->SetTargetElement( aElement );
+	iPolicyProcessor->SetSessionTrust( iTrustedSession );
+	
+	//attribute list for request attributes
+	RAttributeContainer attributes;
+	CleanupClosePushL( attributes );
+	
+	//action attributes for meta_policy_Set	
+	attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, RemovePolicy, StringDataType));
+
+	//subject attributes for trusted sessions
+	if( iTrustedSession->CertificatedSession() )
+		{
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KRoleId, iTrustedSession->CASNForSessionL(), StringDataType));
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KTrustedSubject, iTrustedSession->CASNForSessionL(), StringDataType));
+		}
+	else
+		{
+		attributes.AppendL( ESubjectAttributes, 
+				CAttribute::NewL( PolicyEngineXACML::KSubjectId, iTrustedSession->SIDForSession(), StringDataType));
+		
+		}
+	
+	// ======= original certificate mapping ======================
+	//search trustedsubject from target element (element to be deleted)
+	HBufC8* targetTrustedSubject = iTrustedSession->GetTargetTrustedSubjectL( aElement, ETrue );	
+
+	//and target element trusted subject to request context....
+	if( targetTrustedSubject )
+		{
+		CleanupStack::PushL( targetTrustedSubject); 
+		attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, *targetTrustedSubject, StringDataType));
+		CleanupStack::PopAndDestroy( targetTrustedSubject);
+		}
+	// ===========================================================
+	
+	
+	// ======= mapped certificates ===============================
+	// all certificate mappings, including mapped certificates, are under "cert_mapping_policy"
+	CElementBase* certMappings = iPolicyStorage->GetEditableElementL( _L8("cert_mapping_policy") );
+	if( certMappings )
+		{
+		TElementReserver mappedElementReserver( certMappings );
+		iPolicyStorage->CheckElementL( certMappings );
+	
+		RPointerArray<HBufC8> mappedTargetTrustedSubjects;
+		iTrustedSession->GetMappedTargetTrustedSubjectL( mappedTargetTrustedSubjects, certMappings, ETrue );
+		TInt count = mappedTargetTrustedSubjects.Count();
+		if( count )
+			{
+			for( TInt i = 0; i < count; i++ )
+				{
+				HBufC8* mappedTargetTrustedSubject = mappedTargetTrustedSubjects[ i ];
+				CleanupStack::PushL( mappedTargetTrustedSubject);
+				attributes.AppendL( ESubjectAttributes, CAttribute::NewL( PolicyEngineXACML::KCertificateMapped, *mappedTargetTrustedSubject, StringDataType));
+				CleanupStack::PopAndDestroy( mappedTargetTrustedSubject ); 
+				}
+			}
+	
+		mappedTargetTrustedSubjects.Close();
+		mappedElementReserver.Release();
+		}
+	// ===========================================================
+	
+	//parent element for new policy
+	attributes.AppendL( EResourceAttributes, CAttribute::NewL( PolicyTargetAttr, *aParentElement->ExternalId(), StringDataType));
+
+	//make request
+	TMatchResponse response;
+	iPolicyProcessor->ExecuteRequestL( attributes, response );
+	CleanupStack::PopAndDestroy( &attributes );
+
+	if( response != EPermit )
+		{
+		iMsg = ManagementErrors::AccessDenied;
+		User::Leave( KErrPolicyManager );
+		}	
+	}
+	
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementListL()
+// -----------------------------------------------------------------------------
+//		
+void CPolicyManager::GetElementListL( const RMessage2& aMessage)
+{
+	
+	//element info is two phase operation...
+	if ( aMessage.Function() == EGetElementListLength)
+	{
+		//In first phase descriptor lengths are fetched
+
+		//Read element types
+		TElementType type;
+		TPckg<TElementType> typePack( type);
+		aMessage.ReadL(0, typePack, 0);
+		
+		//fetch element
+		CElementBase * element = iPolicyStorage->GetElementL( PolicyLanguage::Constants::RootElement);
+		
+		if ( element)
+		{
+			//reserve element and check it
+			TElementReserver elementReserver( element);
+			iPolicyStorage->CheckElementL( element);
+			
+			//get list length
+			TInt length = element->GetElementsListLengthL( type);
+	
+			delete iActiveElementList;
+			iActiveElementList = NULL;
+			
+			iActiveElementList = HBufC8::NewL( length);
+			TPtr8 ptr = iActiveElementList->Des();
+			element->GetElementsListL( type, ptr);
+	
+	
+			//write values to client side
+			TPckgC<TInt> intPack( length); 
+			aMessage.WriteL(1, intPack);	
+			
+			elementReserver.Release();
+		}
+		else
+		{
+			User::Leave( KErrNotFound);
+		}
+	}
+	else
+	{
+		// and in second phase descriptor are written to client side
+		if ( iActiveElementList )
+		{
+			aMessage.WriteL(0, *iActiveElementList);	
+		}
+		
+		//delete child list
+		delete iActiveElementList;
+		iActiveElementList = 0;
+	}
+	
+}
+	
+	
+	
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementInfoL()
+// -----------------------------------------------------------------------------
+//
+
+
+void CPolicyManager::GetElementInfoL( const RMessage2& aMessage)
+{
+
+
+	//element info is two phase operation...
+	if ( aMessage.Function() == EGetElementDescriptionAndChildListLength)
+	{
+		//In first phase descriptor lengths are fetched
+
+		//Read element id
+		TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des(); 
+		aMessage.ReadL(0, id, 0);
+		
+		//fetch element
+		CElementBase * element = iPolicyStorage->GetElementL( id);
+		
+		if ( element)
+		{
+			//reserve element and check it
+			TElementReserver elementReserver( element);
+			iPolicyStorage->CheckElementL( element);
+			
+			//Create helper pack, which is delivered to client side			
+			TElementInfoHelpPack helper;
+			helper.iDescriptionLength = 0;
+				
+			//get description and child list		
+			iActiveDescription = element->DescriptionL();
+			if ( iActiveDescription)
+			{
+				helper.iDescriptionLength = iActiveDescription->Length();
+			}
+	
+			helper.iChildListLength = element->GetChildListLengthL();
+	
+			//write values to client side
+			TPckgC<TElementInfoHelpPack> helperPack( helper); 
+			
+			delete iActiveChildList;
+			iActiveChildList = NULL;
+			iActiveChildList = HBufC8::NewL( helper.iChildListLength); 
+			TPtr8 ptr = iActiveChildList->Des();
+			element->GetChildListL( ptr);
+	
+			aMessage.WriteL(1, helperPack);	
+			
+			elementReserver.Release();
+		}
+		else
+		{
+			User::Leave( KErrNotFound);
+		}
+		
+		CleanupStack::PopAndDestroy();	//HBufC8
+	}
+	else
+	{
+		// and in second phase descriptor are written to client side
+		if ( iActiveDescription)
+		{
+			aMessage.WriteL(0, *iActiveDescription);	
+		}
+
+		if ( iActiveChildList)
+		{
+			aMessage.WriteL(1, *iActiveChildList);	
+		}
+
+		
+		//description is owned by descriptor element (do not delete)
+		iActiveDescription = 0;
+		//delete child list
+		delete iActiveChildList;
+		iActiveChildList = 0;
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementXACMLDescriptionL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::GetElementXACMLDescriptionL( const RMessage2& aMessage)
+{
+	
+
+	//get element XACML description is two phase operation...
+	if ( aMessage.Function() == EGetElementXACMLLength)
+	{
+		//Read element id
+		TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des(); 
+		aMessage.ReadL(0, id, 0);
+	
+		//In first phase descriptor length is fetched.
+		CElementBase * element = iPolicyStorage->GetElementL( id);
+
+		if ( element)
+		{
+			//reserve element and check it
+			TElementReserver elementReserver( element);
+			iPolicyStorage->CheckElementL( element);
+	
+			//Member pointer is used to save XACML description during two phase operation
+			delete iActiveXACMLContent;
+			iActiveXACMLContent = NULL;
+			iActiveXACMLContent = element->DecodeElementL( EXACML, EFullMode);
+		
+			TInt length = 0;
+			if ( iActiveXACMLContent)
+			{
+				length = iActiveXACMLContent->Length();
+			}
+	
+			//write values to client side
+			TPckg<TInt> descriptionLength( length); 
+			aMessage.WriteL(1, descriptionLength);	
+			
+			elementReserver.Release();
+		}
+		else
+		{
+			User::Leave( KErrNotFound);
+		}
+	
+		CleanupStack::PopAndDestroy();	//HBufC8
+	}
+	else
+	{
+		// and in second phase descriptor are written to client side
+		if ( iActiveXACMLContent )
+		{
+			aMessage.WriteL(0, *iActiveXACMLContent);	
+		}
+		
+		//delete XACML content
+		delete iActiveXACMLContent;
+		iActiveXACMLContent = NULL;
+		
+	}
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementXACMLDescriptionL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::IsServerIdValidL( const RMessage2& aMessage)
+{
+	RDEBUG("PolicyEngineServer: CPolicyManager: Is allowed server id");
+	
+	//Read server id
+	TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des(); 
+	aMessage.ReadL(0, id, 0);
+
+	//Create package for data
+	TBool response;
+	TPckg<TBool> respPck( response);
+
+	//check id
+	response = CPolicyStorage::PolicyStorage()->IsServerIdValid( id);
+
+	if ( response )
+		{
+		RDEBUG("CPolicyManager: Is allowed server id -> TRUE");
+		}
+	else
+		{
+		RDEBUG("CPolicyManager: Is allowed server id -> FALSE");
+		}
+	
+	//write response
+	aMessage.WriteL(1, respPck);	
+	
+	CleanupStack::PopAndDestroy();	
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetCertificateRoleL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::GetCertificateRoleL( const RMessage2& aMessage)
+	{
+	RDEBUG("PolicyEngineServer: CPolicyManager::GetCertificateRoleL");
+
+	//Create package for data
+	TCertInfo certInfo;
+	TPckg<TCertInfo> certInfoPck( certInfo);
+	aMessage.ReadL(0, certInfoPck, 0);
+
+	//TRole
+	TRole role;
+	TPckg<TRole> rolePck( role);
+	
+	//get certificate role...
+	role = CPolicyEngineServer::CertificateMaps()->CertificateRoleL( certInfo, EFalse );
+
+	//write response
+	aMessage.WriteL( 1, rolePck );	
+	}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AddSilentDMOperationServerIdL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::AddSilentDMOperationServerIdL()
+{
+	//connect to DM util client...
+	RDMUtil dmutil;
+	User::LeaveIfError( dmutil.Connect());
+	CleanupClosePushL( dmutil);
+	
+	//..and get server id
+	TBuf8<KMaxServerIdLength> serverid;
+	User::LeaveIfError( dmutil.GetDMSessionServerId( serverid));
+	
+	User::LeaveIfError( CPolicyStorage::PolicyStorage()->AddNewServerId( serverid));
+
+
+	CleanupStack::PopAndDestroy( &dmutil); 
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::IsCurrentServerIdTrustedL()
+// -----------------------------------------------------------------------------
+//
+TBool CPolicyManager::IsCurrentServerIdTrustedL()
+{
+	TBool trustedServer = EFalse;
+	
+	//connect to DM util client...
+	RDMUtil dmutil;
+	User::LeaveIfError( dmutil.Connect());
+	CleanupClosePushL( dmutil);
+	
+	//..and get server id
+	TBuf8<KMaxServerIdLength> serverid;
+	User::LeaveIfError( dmutil.GetDMSessionServerId( serverid));
+	TRAPD( err, trustedServer = CPolicyStorage::PolicyStorage()->IsServerIdValid( serverid) );
+	User::LeaveIfError( err );
+	CleanupStack::PopAndDestroy( &dmutil); 
+	
+	return trustedServer;
+}