policymanagement/policyengine/policyengineserver/src/CommsDatEnforcement.cpp
changeset 0 b497e44ab2fc
child 76 3cdbd92ee07b
equal deleted inserted replaced
-1:000000000000 0:b497e44ab2fc
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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 "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: Implementation of policymanagement components
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 
       
    22 #include <commdb.h>
       
    23 
       
    24 #include "CommsDatEnforcement.h"
       
    25 #include "XACMLconstants.h"
       
    26 #include "debug.h"
       
    27 #include "PolicyEngineServer.h"
       
    28 #include "PolicyStorage.h"
       
    29 
       
    30 #include <protectdb.h>
       
    31 
       
    32 #include <commsdattypesv1_1.h>
       
    33 #include <WlanCdbCols.h>
       
    34 #include <d32dbms.h>
       
    35 #include <metadatabase.h>
       
    36 
       
    37 // EXTERNAL DATA STRUCTURES
       
    38 // EXTERNAL FUNCTION PROTOTYPES
       
    39 // CONSTANTS
       
    40 
       
    41 _LIT( KCommsDatEnformentPanic, "CommsDat enforcement panic");
       
    42 
       
    43 
       
    44 //Repository UIDs
       
    45 
       
    46 const TUid TCommsDatRepository = { 0xCCCCCC00 };
       
    47 const TUint32 KCDMaskRecordType = 0x7f800000;
       
    48 
       
    49 const TUint32 KWLANServiceExtRecord			  = 0x05000000; 
       
    50 
       
    51 const TPtrC KWLANServiceExtTable( _S("WLANServiceExtensionTable"));
       
    52 const TPtrC KWLANServiceTable( _S("WLANServiceTable"));
       
    53 const TPtrC KWLANDeviceTable( _S("WLANDeviceTable"));
       
    54 const TPtrC KWLANSecondarySSID( _S("SecondarySSID"));
       
    55 const TPtrC KDestinationNetwork( _S("DestinationNetwork"));
       
    56 
       
    57 
       
    58 _LIT8( KAPURI, "AP");
       
    59 
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CCommsDatEnforcement::CCommsDatEnforcement()
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 CCommsDatEnforcement::CCommsDatEnforcement()
       
    66 	{
       
    67 	RDEBUG("CCommsDatEnforcement::CCommsDatEnforcement()");
       
    68 	}
       
    69 
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CCommsDatEnforcement::~CCommsDatEnforcement()
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 CCommsDatEnforcement::~CCommsDatEnforcement()
       
    76 	{
       
    77 	RDEBUG("CCommsDatEnforcement::~CCommsDatEnforcement()");
       
    78 	
       
    79 	if( iSession )
       
    80         {
       
    81         iSession->Close();
       
    82         delete iSession; 
       
    83         }
       
    84 	
       
    85 	iMaskList.Close();	
       
    86 	iTableList.Close();	
       
    87 	iCommsDatEnforcement.Close();
       
    88 	iCentRepServer.Close();	
       
    89 	iDMUtil.Close();
       
    90 	}
       
    91 
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CCommsDatEnforcement::ConstructL()
       
    95 // -----------------------------------------------------------------------------
       
    96 //		
       
    97 void CCommsDatEnforcement::ConstructL()
       
    98 	{
       
    99 	RDEBUG("CCommsDatEnforcement::ConstructL()");	
       
   100 	//no implementation needed
       
   101     iSession = CMDBSession::NewL( CMDBSession::LatestVersion() );
       
   102 	}
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CCommsDatEnforcement::NewL()
       
   106 // -----------------------------------------------------------------------------
       
   107 //		
       
   108 CCommsDatEnforcement* CCommsDatEnforcement::NewL( const TDesC8& aEnforcementId )
       
   109 	{
       
   110 	RDEBUG("CCommsDatEnforcement::NewL()");
       
   111 	CCommsDatEnforcement* self = 0;
       
   112 
       
   113 	if( aEnforcementId == PolicyLanguage::Constants::EAPEnforcementPolicy )
       
   114 		{
       
   115 		RDEBUG("	-> EAPEnforcementPolicy");
       
   116 		self = new ( ELeave ) CCommsDatEnforcement();	
       
   117 		self->ConstructL();
       
   118 		CleanupStack::PushL( self );
       
   119 		self->iMaskList.AppendL( KCDTIdWAPAccessPointRecord );
       
   120 		self->iTableList.AppendL( TPtrC(KCDTypeNameWAPAccessPoint ));
       
   121 		self->iMaskList.AppendL( KCDTIdWAPSMSBearerRecord );
       
   122 		self->iTableList.AppendL( TPtrC(KCDTypeNameWAPSMSBearer) );
       
   123 		self->iMaskList.AppendL( KCDTIdWAPIPBearerRecord );
       
   124 		self->iTableList.AppendL( TPtrC(KCDTypeNameWAPIPBearer) );
       
   125 		self->iMaskList.AppendL( KCDTIdIAPRecord );
       
   126 		self->iTableList.AppendL( TPtrC(KCDTypeNameIAP) );
       
   127 		self->iSettingType = EAPEnforcement;
       
   128 		CleanupStack::Pop( self );
       
   129 		}
       
   130 	else if( aEnforcementId == PolicyLanguage::Constants::EWLANEnforcementPolicy )
       
   131 		{
       
   132 		RDEBUG("	-> EWLANEnforcementPolicy");
       
   133 		self = new ( ELeave ) CCommsDatEnforcement();	
       
   134 		self->ConstructL();	
       
   135 		CleanupStack::PushL( self );
       
   136 		self->iMaskList.AppendL( KWLANServiceExtRecord );
       
   137 		self->iTableList.AppendL( KWLANServiceExtTable );
       
   138 
       
   139 		TUint32 wlanServiceTableId = self->GetRecordIdL( KWLANServiceTable );
       
   140 		self->iMaskList.AppendL( wlanServiceTableId );
       
   141 		self->iTableList.AppendL( KWLANServiceTable );
       
   142 		
       
   143 		TUint32 wlanDeviceTableId = self->GetRecordIdL( KWLANDeviceTable );
       
   144 		self->iMaskList.AppendL( wlanDeviceTableId );
       
   145 		self->iTableList.AppendL( KWLANDeviceTable );
       
   146 		
       
   147 		TUint32 wlanSSIDTableId = self->GetRecordIdL( KWLANSecondarySSID );
       
   148 		self->iMaskList.AppendL( wlanSSIDTableId );
       
   149 		self->iTableList.AppendL( KWLANSecondarySSID );
       
   150 		
       
   151 		TUint32 wlanDestinationNetworkTableId = self->GetRecordIdL( KDestinationNetwork );
       
   152 		self->iMaskList.AppendL( wlanDestinationNetworkTableId );
       
   153 		self->iTableList.AppendL( KDestinationNetwork );	
       
   154 
       
   155 		self->iSettingType = EWLANEnforcement;
       
   156 		CleanupStack::Pop( self );
       
   157 		}
       
   158 
       
   159 	return self;
       
   160 	}
       
   161 
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CCommsDatEnforcement::ValidEnforcementElement()
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 TBool CCommsDatEnforcement::ValidEnforcementElement( const TDesC8& aEnforcementId )
       
   168 	{
       
   169 	RDEBUG("CCommsDatEnforcement::ValidEnforcementElement()");
       
   170 	if ( aEnforcementId == PolicyLanguage::Constants::EAPEnforcementPolicy )
       
   171 		{
       
   172 		RDEBUG("	-> valid EAPEnforcementPolicy");
       
   173 		return ETrue;
       
   174 		} 
       
   175 	else if ( aEnforcementId == PolicyLanguage::Constants::EWLANEnforcementPolicy )
       
   176 		{
       
   177 		RDEBUG("	-> valid EWLANEnforcementPolicy");
       
   178 		return ETrue;	
       
   179 		}
       
   180 	
       
   181 	return EFalse;
       
   182 	}
       
   183 
       
   184 	
       
   185 // -----------------------------------------------------------------------------
       
   186 // CCommsDatEnforcement::InitEnforcement()
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CCommsDatEnforcement::InitEnforcementL( TRequestStatus& aRequestStatus )
       
   190 	{
       
   191 	RDEBUG("CCommsDatEnforcement::InitEnforcementL()");
       
   192 	//set restore flag
       
   193 	if ( iAccessControlList->Count() )
       
   194 		{
       
   195 		iRestore = EFalse;
       
   196 		}
       
   197 	else
       
   198 		{
       
   199 		iRestore = ETrue;
       
   200 		iInitState++;
       
   201 		}
       
   202 
       
   203 	//in first phase open connections to centreptool
       
   204 	if ( iInitState == 0 || iRestore )
       
   205 		{
       
   206 		RDEBUG("	-> Opening connections ... ");
       
   207 		User::LeaveIfError( iCentRepServer.Connect() );
       
   208 		User::LeaveIfError( iCommsDatEnforcement.Open( TCommsDatRepository , iCentRepServer ) );
       
   209 		User::LeaveIfError( iDMUtil.Connect());
       
   210 		RDEBUG("	-> Opening connections ... DONE!");
       
   211 		}
       
   212 	
       
   213 	//init each session in own cycle....
       
   214 	switch ( iInitState )
       
   215 		{
       
   216 		case 0:
       
   217 			{
       
   218 			RDEBUG("CCommsDatEnforcement: Protect AP tables ... ");
       
   219 			CCommsDatabaseProtect* dbprotect = CCommsDatabaseProtect::NewL();
       
   220 			
       
   221 			//add protection for GS
       
   222 			for ( TInt i( 0 ); i < iTableList.Count(); i++ )
       
   223 				{
       
   224 				TInt err = dbprotect->ProtectTable( iTableList[ i ] );
       
   225 				RDEBUG_2("CCommsDatEnforcement: Protection status %d", err );
       
   226 				}			
       
   227 			
       
   228 			delete dbprotect;
       
   229 			dbprotect = NULL;	
       
   230 			
       
   231 			// enable all WLAN AP locks
       
   232 		    if(iSettingType == EWLANEnforcement)
       
   233 		    {
       
   234 				LockWLANAccessPointsL( ETrue );
       
   235 		    }
       
   236 				
       
   237 			//compelete request
       
   238 			TRequestStatus * status = &aRequestStatus;
       
   239 			User::RequestComplete( status, KErrNone );
       
   240 			}
       
   241 		break;
       
   242 		case 1:
       
   243 			{
       
   244 			RDEBUG("CCommsDatEnforcement: Init commsDat enforcement session");
       
   245 			iCommsDatEnforcement.InitSession( aRequestStatus );
       
   246 			}
       
   247 		break;
       
   248 		default:
       
   249 			{
       
   250 			RDEBUG("**** CCommsDatEnforcement PANIC, invalid switch-case!");
       
   251 			User::Panic( KCommsDatEnformentPanic, KErrAbort );
       
   252 			}
       
   253 		break;
       
   254 		}
       
   255 	
       
   256 	iInitState++;
       
   257 	}
       
   258 
       
   259 
       
   260 // -----------------------------------------------------------------------------
       
   261 // CCommsDatEnforcement::InitReady()
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 TBool CCommsDatEnforcement::InitReady()
       
   265 	{
       
   266 	RDEBUG("CCommsDatEnforcement::InitReady()");
       
   267 	return ( iInitState > 1 );
       
   268 	}
       
   269 
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // CCommsDatEnforcement::InitReady()
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 void CCommsDatEnforcement::DoEnforcementL( TRequestStatus& aRequestStatus )
       
   276 	{
       
   277 	RDEBUG("CCommsDatEnforcement::DoEnforcementL()");
       
   278 	if( !iRestore )
       
   279 		{
       
   280 		//if there any number subject which have exclusively right for setting, give access only for DM client
       
   281 		for ( TInt i( 0 ); i < iMaskList.Count(); i++ )
       
   282 			{
       
   283 			RDEBUG_3("	making enforcement: %d/%d", i, iMaskList.Count() );
       
   284 			User::LeaveIfError( iCommsDatEnforcement.SetSIDWRForMask( iMaskList[ i ], KCDMaskRecordType, KDMClientUiD));
       
   285 			User::LeaveIfError( iCommsDatEnforcement.RemoveBackupFlagForMask( iMaskList[ i ], KCDMaskRecordType));
       
   286 			CPolicyStorage::PolicyStorage()->ActivateEnforcementFlagL( iSettingType );	
       
   287 			}
       
   288 		
       
   289 		//ACL...
       
   290 		RDEBUG("	making ACL modifications for enforcement ... ");
       
   291 		User::LeaveIfError( iDMUtil.SetMngSessionCertificate( SessionCertificate() ) );
       
   292 		User::LeaveIfError( iDMUtil.AddACLForNode( KAPURI, EForChildrens, EACLDelete ) );
       
   293 		User::LeaveIfError( iDMUtil.AddACLForNode( KAPURI, EForNode, EACLGet ) );
       
   294 		User::LeaveIfError( iDMUtil.SetACLForNode( KAPURI, EForNode, EACLAdd ) );
       
   295 		RDEBUG("	making ACL modifications for enforcement ... DONE!");
       
   296 		}
       
   297 	else
       
   298 		{
       
   299 		//Clear default settings
       
   300 		for ( TInt i( 0 ); i < iMaskList.Count(); i++ )
       
   301 			{
       
   302 			RDEBUG_3("	clearing default settings: %d/%d", i, iMaskList.Count() );
       
   303 			User::LeaveIfError( iCommsDatEnforcement.RestoreMask( iMaskList[ i ], KCDMaskRecordType ));
       
   304 			User::LeaveIfError( iCommsDatEnforcement.RestoreBackupFlagForMask( iMaskList[ i ], KCDMaskRecordType));
       
   305 			CPolicyStorage::PolicyStorage()->DeactivateEnforcementFlagL( iSettingType );
       
   306 			}
       
   307 
       
   308 		//ACL...
       
   309 		RDEBUG("	removing ACL modifications for enforcement ... ");
       
   310 		User::LeaveIfError( iDMUtil.RemoveACL( KAPURI, ETrue ) );
       
   311 		RDEBUG("	removing ACL modifications for enforcement ... DONE!");
       
   312 
       
   313 		}
       
   314 	
       
   315 	iEnforcementState++;
       
   316 	TRequestStatus * status = &aRequestStatus;
       
   317 	User::RequestComplete( status, KErrNone );
       
   318 	}
       
   319 
       
   320 // -----------------------------------------------------------------------------
       
   321 // CCommsDatEnforcement::EnforcementReady()
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 TBool CCommsDatEnforcement::EnforcementReady()
       
   325 	{
       
   326 	RDEBUG("CCommsDatEnforcement::EnforcementReady()");
       
   327 	return iEnforcementState > 0;
       
   328 	}
       
   329 	
       
   330 // -----------------------------------------------------------------------------
       
   331 // CCommsDatEnforcement::FinishEnforcementL()
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 void CCommsDatEnforcement::FinishEnforcementL( TBool aFlushSettings)
       
   335 	{
       
   336 	RDEBUG("CCommsDatEnforcement::FinishEnforcementL()");
       
   337 	//Close sessions
       
   338 	if( aFlushSettings )
       
   339 		{
       
   340 		iCommsDatEnforcement.Flush();
       
   341 		iDMUtil.Flush();
       
   342 		}
       
   343 	
       
   344 	iCommsDatEnforcement.Close();
       
   345 
       
   346 	//Close centrep server...
       
   347 	iCentRepServer.Close();
       
   348 	
       
   349 	iDMUtil.Close();
       
   350 
       
   351 		
       
   352 	if( iRestore && aFlushSettings )
       
   353 		{
       
   354 		RDEBUG("PolicyEngineServer: Remove AP table Protection");
       
   355 	
       
   356 		CCommsDatabaseProtect* dbprotect = CCommsDatabaseProtect::NewL();
       
   357 		CleanupStack::PushL( dbprotect );
       
   358 		
       
   359 		TRAP_IGNORE( LockWLANAccessPointsL( EFalse ) );
       
   360 		//remove protection for GS
       
   361 		for ( TInt i( 0 ); i < iTableList.Count(); i++ )
       
   362 			{
       
   363 			TInt err = dbprotect->UnProtectTable( iTableList[ i ] );
       
   364 			RDEBUG_2("PolicyEngineServer: Protection status %d", err );
       
   365 			}			
       
   366 	//Condition when AP + WLAN are enforced and AP is being removed
       
   367 	//GS should still show lock icons for WLANs
       
   368 	      RDbRowSet::TAccess checkAccessType = RDbRowSet::EReadOnly ;
       
   369 		   	TRAP_IGNORE( checkAccessType =  dbprotect->GetTableAccessL(TPtrC(WLAN_SERVICE)));
       
   370     		switch(checkAccessType)
       
   371     		{
       
   372     			case RDbRowSet::EReadOnly :
       
   373 				 	TRAP_IGNORE(LockWLANAccessPointsL( ETrue ));
       
   374 				default :	break;
       
   375     		}
       
   376 		CleanupStack::PopAndDestroy( dbprotect );
       
   377 		}
       
   378 	}
       
   379 				
       
   380 // -----------------------------------------------------------------------------
       
   381 // CCommsDatEnforcement::AccessRightList()
       
   382 // -----------------------------------------------------------------------------
       
   383 //
       
   384 void CCommsDatEnforcement::AccessRightList( RAccessControlList& aAccessControlList)
       
   385 	{
       
   386 	RDEBUG("CCommsDatEnforcement::AccessRightList()");
       
   387 	iAccessControlList = &aAccessControlList;
       
   388 	}
       
   389 
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // CCommsDatEnforcement::ResetEnforcementL()
       
   393 // -----------------------------------------------------------------------------
       
   394 //
       
   395 void CCommsDatEnforcement::ResetEnforcementL()
       
   396 	{
       
   397 	RDEBUG("CCommsDatEnforcement::ResetEnforcementL()");
       
   398 	
       
   399 	User::LeaveIfError( iCentRepServer.Connect() );
       
   400 	User::LeaveIfError( iCommsDatEnforcement.Open( TCommsDatRepository , iCentRepServer ) );
       
   401 	User::LeaveIfError( iDMUtil.Connect());
       
   402 
       
   403 	TRequestStatus request;
       
   404 	iCommsDatEnforcement.InitSession( request );
       
   405 	User::WaitForRequest( request);
       
   406 	
       
   407 		for ( TInt i( 0 ); i < iMaskList.Count(); i++ )
       
   408 			{
       
   409 			User::LeaveIfError( iCommsDatEnforcement.RestoreMask( iMaskList[ i ], KCDMaskRecordType ));
       
   410 			User::LeaveIfError( iCommsDatEnforcement.RestoreBackupFlagForMask( iMaskList[ i ], KCDMaskRecordType));
       
   411 			}
       
   412 
       
   413 	//ACL...
       
   414 	User::LeaveIfError( iDMUtil.RemoveACL( KAPURI, ETrue ) );
       
   415 
       
   416 
       
   417 	iCommsDatEnforcement.Flush();
       
   418 	iCommsDatEnforcement.Close();
       
   419 	iCentRepServer.Close();	
       
   420 	iDMUtil.Close();
       
   421 	}
       
   422 
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // CCommsDatEnforcement::LockWLANAccessPointsL()
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 void CCommsDatEnforcement::LockWLANAccessPointsL( TBool aLockValue )
       
   429 	{
       
   430 	RDEBUG_2("CCommsDatEnforcement::LockAccessPoint( %d )", aLockValue );
       
   431 	
       
   432 	//Get WLAN service table and get ServiceID--> which is nothing but IAP ID and lock that record
       
   433 
       
   434 	//TBool ret = EFalse;
       
   435 	TUint32 apIAPID = 0;
       
   436 		
       
   437     CCommsDbTableView*  checkView;
       
   438 	CCommsDatabase* commsDataBase = CCommsDatabase::NewL();
       
   439 	CleanupStack::PushL( commsDataBase );
       
   440     checkView = commsDataBase->OpenTableLC(TPtrC(IAP));
       
   441    	RDEBUG("		-> After opening IAP table ");
       
   442    	TBuf<KCommsDbSvrMaxFieldLength> serviceType;
       
   443     TInt error = checkView->GotoFirstRecord();
       
   444     RDEBUG("		-> After going to first record ");
       
   445     while (error == KErrNone)
       
   446         {
       
   447         RDEBUG("		-> KERRNONE ");
       
   448        		// Get the ID and check for service type
       
   449        	checkView->ReadTextL(TPtrC(IAP_SERVICE_TYPE), serviceType);
       
   450         if(serviceType == TPtrC(LAN_SERVICE))
       
   451             {
       
   452                	checkView->ReadUintL(TPtrC(COMMDB_ID), apIAPID);
       
   453                		RDEBUG_2("	->found %d WLAN AP. being protected or unprotected", apIAPID );
       
   454                	if(aLockValue)
       
   455                	{
       
   456                	((CCommsDbProtectTableView*)checkView)->ProtectRecord();
       
   457                	RDEBUG("		-> WLAN AP protected successfully!");	
       
   458                	}
       
   459                	else
       
   460                	{
       
   461                		((CCommsDbProtectTableView*)checkView)->UnprotectRecord();
       
   462                		RDEBUG("		-> WLAN AP UN protected successfully!");
       
   463                	}
       
   464                	
       
   465             }
       
   466             error = checkView->GotoNextRecord();
       
   467             
       
   468         }
       
   469     CleanupStack::PopAndDestroy(); // checkView
       
   470 
       
   471     CleanupStack::PopAndDestroy( commsDataBase );	
       
   472 
       
   473 
       
   474 	}	
       
   475 
       
   476 
       
   477 // -----------------------------------------------------------------------------
       
   478 // CCommsDatEnforcement::GetRecordId()
       
   479 // -----------------------------------------------------------------------------
       
   480 //	
       
   481 TUint32 CCommsDatEnforcement::GetRecordIdL( const TDesC& aTableName )
       
   482 	{
       
   483 	RDEBUG_2("looking rentrep record id for table: %S", &aTableName );
       
   484 	TMDBElementId tableRecordId = 0;
       
   485 	CMDBGenericRecord* tempUserDefinedRecord = static_cast<CMDBGenericRecord*>(CCDRecordBase::RecordFactoryL(0));
       
   486     CleanupStack::PushL(tempUserDefinedRecord);
       
   487     
       
   488     tempUserDefinedRecord->InitializeL(aTableName, NULL);
       
   489 	tempUserDefinedRecord->LoadL(*iSession);
       
   490 	
       
   491     // Get the Id that we're interested in...
       
   492     tableRecordId = tempUserDefinedRecord->TableId();
       
   493 	RDEBUG_2("	found tableRecordId: %08x", tableRecordId );
       
   494 	CleanupStack::PopAndDestroy(tempUserDefinedRecord);
       
   495 
       
   496     // ..and validate it.
       
   497     if ((tableRecordId & KCDMaskShowRecordType) < KCDInitialUDefRecordType)
       
   498     	{
       
   499 	   	RDEBUG("Error validating tableRecordId");
       
   500         User::Leave(KErrNotFound);
       
   501         }
       
   502 
       
   503 	return tableRecordId;
       
   504 	}
       
   505