os/persistentdata/persistentstorage/sql/SRC/Server/SqlSrvAuthorizer.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Server/SqlSrvAuthorizer.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,571 @@
     1.4 +// Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "SqlSrvAuthorizer.h"	//MSqlPolicyInspector
    1.20 +#include "SqlSrvMain.h"			//CSqlServer
    1.21 +#include "SqlSrvSecurityMap.h"	//RSqlSecurityMap
    1.22 +#include "SqlSrvDatabase.h"		//CSqlSrvDatabase
    1.23 +#include "SqlSecurityImpl.h"	//CSqlSecurityPolicy
    1.24 +#include "SqlSrvDbSysSettings.h"//TSqlDbSysSettings
    1.25 +#include "SqlSrvUtil.h"			//Global server functions
    1.26 +#include "SqlSrvStatementUtil.h"//Global sql statement related functions
    1.27 +#include "SqlSrvStrings.h"		//KTempDb
    1.28 +#include "sqlite3.h"
    1.29 +#include "SqliteSymbian.h"		//sqlite3SymbianLastOsError()
    1.30 +
    1.31 +//This macro is used to suppress "function argument not used" compiler warning.
    1.32 +#define UNUSED_ARG(arg) arg = (arg)
    1.33 +
    1.34 +//Array of pragma commands 
    1.35 +const TPtrC8 KPragmaCommands[] = 
    1.36 +	{
    1.37 +	KAutoVacuum(),	KCacheSize(), KCaseSensitiveLike(), KCountChanges(), KDefaultCacheSize(),
    1.38 +	KEmptyResultCallbacks(), KEncoding(), KFullColumnNames(), KFullfsync(), KIncrementalVacuum(), 
    1.39 +	KJournalMode(), KJournalSizeLimit(), KLegacyFileFormat(), KLockingMode(), KPageSize(),
    1.40 +	KMaxPageCount(), KReadUncommitted(), KShortColumnNames(), KSynchronousFlag(), KTempStore(), 
    1.41 +	KTempStoreDirectory(), KDatabaseList(), KForeignKeyList(), KFreelistCount(), KIndexInfo(), 
    1.42 +	KIndexIist(), KPageCount(),KTableInfo(), KSchemaVersion(), KUserVersion(),
    1.43 +	KIntegrityCheck(),KParserTrace(), KVdbeTrace(), KdbeListing()
    1.44 +	};
    1.45 +
    1.46 +const TInt KMaxPragmaCommands = sizeof(KPragmaCommands) / sizeof(KPragmaCommands[0]);
    1.47 +
    1.48 +
    1.49 +//Define the different ways of calling a pragam depending on the following
    1.50 +// 1) If its a secure or non secure database
    1.51 +// 2) If the pragma is called with a parameter (write) or without a parameter (read)
    1.52 +struct TPragmaAccess
    1.53 +	{
    1.54 +	TInt iNonSecureRead; 
    1.55 +	TInt iNonSecureWrite;
    1.56 +	TInt iSecureRead;
    1.57 +	TInt iSecureWrite;
    1.58 +	};
    1.59 +
    1.60 +//Table specifying the permissions for each pragma command for secure (shared) and non-secure (public and private)
    1.61 +//databases. For each database permissions for the following situations are specified
    1.62 +//1) With Parameter - e.g "Pragma auto_vacuum = 0"
    1.63 +//2) Without Parameter - e.g "Pragma auto_vacuum" 
    1.64 +
    1.65 +//Permissions "without parameters" usually apply to a pragma query (or read)
    1.66 +//Permissions "with parameters" usually apply to pragama set (or write)
    1.67 +//However please note that this is not always the case. e.g "index_info" requires a parameter but is used to query
    1.68 +//(or read) the database and not a pragma set. 
    1.69 +const TPragmaAccess KPermissionsTable[KMaxPragmaCommands] = 
    1.70 +	{
    1.71 +	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.72 +	//				NON_SECURE					|				SECURE				|
    1.73 +	//  W/Out Parameter		|With Parameter		|W/Out Parameter|With  Parameter	|Pragma Command 
    1.74 +	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.75 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY, 	SQLITE_DENY}, 		//0. auto_vacuum
    1.76 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//1.cache_size
    1.77 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//2.case_sensitive_like
    1.78 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY}, 		//3.count_changes
    1.79 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//4.cache_size
    1.80 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//5.empty_result_callbacks
    1.81 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},  		//6.encoding
    1.82 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//7.full_column_names
    1.83 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//8.fullfsync
    1.84 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//9.incremental_vacuum
    1.85 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//10.journal_mode
    1.86 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//11.journal_size_limit
    1.87 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//12.legacy_file_format
    1.88 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//13.locking_mode
    1.89 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//14.page_size
    1.90 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//15.max_page_count
    1.91 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//16.read_uncommitted
    1.92 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//17.short_column_names
    1.93 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//18.synchronous
    1.94 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//19.temp_store
    1.95 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//20.temp_store_directory
    1.96 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//21.database_list
    1.97 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//22.foreign_key_list
    1.98 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//23.freelist_count
    1.99 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//24.index_info
   1.100 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//25.index_list
   1.101 +		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//26.page_count
   1.102 +		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//27.table_info
   1.103 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//28.schema_version
   1.104 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//29.user_version
   1.105 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//30.integrity_check
   1.106 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//31.parser_trace
   1.107 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//32.vdbe_trace
   1.108 +		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//33.vdbe_listing
   1.109 +	};
   1.110 +
   1.111 +
   1.112 +//This const array describes the relation between the database operation type and
   1.113 +//the number of the authorizer argument where the table name is.
   1.114 +//For example:
   1.115 +//- SQLITE_CREATE_TEMP_TABLE operation. The table name is in aDbObjName1 argument, so the array element value is 1.
   1.116 +//- SQLITE_PRAGMA operation. No table name for this operation, so the array element value is 0.
   1.117 +//- SQLITE_CREATE_TEMP_TRIGGER operation. The table name is in aDbObjName2 argument, so the array element value is 2.
   1.118 +const TUint8 KTableNameArgIndex[] =
   1.119 +	{
   1.120 +	/////////////////////////////////////////////////////////////////
   1.121 +	//									  aDbObjName1	  aDbObjName2
   1.122 +	/////////////////////////////////////////////////////////////////
   1.123 +	1,	//SQLITE_COPY                     Table Name      Filename 
   1.124 +	2,	//SQLITE_CREATE_INDEX             Index Name      Table Name      
   1.125 +	1,	//SQLITE_CREATE_TABLE             Table Name      NULL            
   1.126 +	2,	//SQLITE_CREATE_TEMP_INDEX        Index Name      Table Name      
   1.127 +	1,	//SQLITE_CREATE_TEMP_TABLE        Table Name      NULL            
   1.128 +	2,	//SQLITE_CREATE_TEMP_TRIGGER      Trigger Name    Table Name      
   1.129 +	0,	//SQLITE_CREATE_TEMP_VIEW         View Name       NULL            
   1.130 +	2,	//SQLITE_CREATE_TRIGGER           Trigger Name    Table Name      
   1.131 +	0,	//SQLITE_CREATE_VIEW              View Name       NULL            
   1.132 +	1,	//SQLITE_DELETE                   Table Name      NULL            
   1.133 +	2,	//SQLITE_DROP_INDEX               Index Name      Table Name      
   1.134 +	1,	//SQLITE_DROP_TABLE               Table Name      NULL            
   1.135 +	2,	//SQLITE_DROP_TEMP_INDEX          Index Name      Table Name      
   1.136 +	1,	//SQLITE_DROP_TEMP_TABLE          Table Name      NULL            
   1.137 +	2,	//SQLITE_DROP_TEMP_TRIGGER        Trigger Name    Table Name      
   1.138 +	0,	//SQLITE_DROP_TEMP_VIEW           View Name       NULL            
   1.139 +	2,	//SQLITE_DROP_TRIGGER             Trigger Name    Table Name      
   1.140 +	0,	//SQLITE_DROP_VIEW                View Name       NULL            
   1.141 +	1,	//SQLITE_INSERT                   Table Name      NULL            
   1.142 +	0,	//SQLITE_PRAGMA                   Pragma Name     1st arg or NULL 
   1.143 +	1,	//SQLITE_READ                     Table Name      Column Name     
   1.144 +	0,	//SQLITE_SELECT                   NULL            NULL            
   1.145 +	0,	//SQLITE_TRANSACTION              NULL            NULL            
   1.146 +	1,	//SQLITE_UPDATE                   Table Name      Column Name     
   1.147 +	0,	//SQLITE_ATTACH                   Filename        NULL            
   1.148 +	0,	//SQLITE_DETACH                   Database Name   NULL 
   1.149 +	2,	//SQLITE_ALTER_TABLE          	  Database Name   Table Name
   1.150 +	0,	//SQLITE_REINDEX              	  Index Name      NULL
   1.151 +	1,	//SQLITE_ANALYZE              	  Table Name      NULL
   1.152 +	1,	//SQLITE_CREATE_VTABLE			  Table Name	  Module Name	
   1.153 +	1,	//SQLITE_DROP_VTABLE          	  Table Name      Module Name
   1.154 +	0	//SQLITE_FUNCTION				  Function Name   NULL
   1.155 +	};
   1.156 +
   1.157 +//The function returns the argument number where the table name is.
   1.158 +inline TInt DbOp2TableNameArgIndex(TInt aDbOpType)
   1.159 +	{
   1.160 +	__ASSERT_DEBUG(aDbOpType > 0 && aDbOpType <= SQLITE_FUNCTION, __SQLPANIC2(ESqlPanicInternalError));
   1.161 +	return KTableNameArgIndex[aDbOpType];
   1.162 +	}
   1.163 +
   1.164 +//The function returns the table name, which may be in aDbObjName1 or aDbObjName2, depending on aDbOpType value.
   1.165 +//The return value is "const char" pointer to a zero terminated string.
   1.166 +inline const char* DbOp2TableName(TInt aDbOpType, const char* aDbObjName1, const char* aDbObjName2)
   1.167 +	{
   1.168 +	TInt pos = DbOp2TableNameArgIndex(aDbOpType);
   1.169 +	if(pos == 2)
   1.170 +		{
   1.171 +		__ASSERT_DEBUG(aDbObjName2 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.172 +		return aDbObjName2;
   1.173 +		}
   1.174 +	else if(pos == 1)
   1.175 +		{
   1.176 +		__ASSERT_DEBUG(aDbObjName1 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.177 +		return aDbObjName1;
   1.178 +		}
   1.179 +	return NULL;//Some database operations do not use table name
   1.180 +	}
   1.181 +
   1.182 +//This function returns the database name which may be in aDbObjName1 or aDbName depending on aDbOpType value.
   1.183 +//The return value is "const char" pointer to a zero terminated string.
   1.184 +inline const char* DbOp2DbName(TInt aDbOpType, const char* aDbObjName1, const char* aDbName)
   1.185 +	{
   1.186 +	if(aDbOpType == SQLITE_DETACH || aDbOpType == SQLITE_ALTER_TABLE)
   1.187 +		{
   1.188 +		__ASSERT_DEBUG(aDbObjName1 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.189 +		return aDbObjName1;
   1.190 +		}
   1.191 +	return aDbName;//It may be NULL for some database operations
   1.192 +	}
   1.193 +
   1.194 +/**
   1.195 +This function performs pragma permission checks for non-secure and secure databases
   1.196 +
   1.197 +@param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   1.198 +			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.199 +@param aParamUsed ETrue if the pragma command has been executed with a parameter, EFalse otherwise
   1.200 +@param aSecure ETrue if the pragam check if for secure database, EFalse otherwise
   1.201 +
   1.202 +@return SQLITE_OK		Access is allowed
   1.203 +@return SQLITE_DENY 	The entire SQL statement should be aborted
   1.204 +@return SQLITE_IGNORE	The column should be treated as it has NULL value
   1.205 +
   1.206 +@internalComponent
   1.207 + */ 
   1.208 +static TInt PragmaCheck(const char* aDbObjName1, TBool aParamUsed, TBool aSecure)
   1.209 +	{
   1.210 +	//Retreive the pragma name
   1.211 +	TPtrC8 DbObjName1(KNullDesC8);
   1.212 +	DbObjName1.Set(reinterpret_cast <const TUint8*> (aDbObjName1));
   1.213 +	
   1.214 +	//Access the pragma permissions table depending if its :-
   1.215 +	// 1) Secure or non-secure database.
   1.216 +	// 2) Parameter was used or not.
   1.217 +	for (TInt index=0; index<KMaxPragmaCommands; index++)
   1.218 +		{
   1.219 +		if (CompareNoCase8(DbObjName1,KPragmaCommands[index])== 0)
   1.220 +			{
   1.221 +			if (aSecure)
   1.222 +				{
   1.223 +				if(aParamUsed)
   1.224 +					return KPermissionsTable[index].iSecureWrite;
   1.225 +				else
   1.226 +					return KPermissionsTable[index].iSecureRead;
   1.227 +				}
   1.228 +			else
   1.229 +				{
   1.230 +				if(aParamUsed)
   1.231 +					return KPermissionsTable[index].iNonSecureWrite;
   1.232 +				else
   1.233 +					return KPermissionsTable[index].iNonSecureRead;
   1.234 +				}
   1.235 +			}
   1.236 +		}
   1.237 +	//If the pragma is not on the list then deny access
   1.238 +	return SQLITE_DENY;
   1.239 +	}
   1.240 +
   1.241 +
   1.242 +/**
   1.243 +This function performs additional permission checks for non-secure (private and public) databases
   1.244 +
   1.245 +@param aDbOpType Database operation type, which needs to be authorized.
   1.246 +@param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   1.247 +			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.248 +@param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.249 +
   1.250 +@return SQLITE_OK		Access is allowed
   1.251 +@return SQLITE_DENY 	The entire SQL statement should be aborted
   1.252 +@return SQLITE_IGNORE	The column should be treated as it has NULL value
   1.253 +
   1.254 +@panic SqlDb 7 In _DEBUG mode. Unknown/invalid aDbOpType argument.
   1.255 +
   1.256 +@internalComponent
   1.257 + */ 
   1.258 +static TInt NonSecureChecks(TInt aDbOpType,const char* aDbObjName1, const char* aDbObjName2)
   1.259 +	{
   1.260 +	//=================================================================
   1.261 +	//	aDbOpType							aDbObjName1		aDbObjName2
   1.262 +	//=================================================================
   1.263 +	TInt res = SQLITE_OK;
   1.264 +	switch(aDbOpType)
   1.265 +		{
   1.266 +		case SQLITE_CREATE_INDEX://          Index Name      Table Name      
   1.267 +		case SQLITE_CREATE_TABLE://          Table Name      NULL            
   1.268 +		case SQLITE_CREATE_TRIGGER://        Trigger Name    Table Name      
   1.269 +		case SQLITE_CREATE_VIEW://           View Name       NULL            
   1.270 +		case SQLITE_DROP_INDEX://            Index Name      Table Name            
   1.271 +		case SQLITE_DROP_TABLE://            Table Name      NULL 
   1.272 +		case SQLITE_DROP_TRIGGER://          Trigger Name    Table Name      
   1.273 +		case SQLITE_DROP_VIEW://             View Name       NULL            
   1.274 +		case SQLITE_ALTER_TABLE://			 Database Name   Table Name
   1.275 +		case SQLITE_SELECT://                NULL            NULL            
   1.276 +		case SQLITE_TRANSACTION://           NULL            NULL          
   1.277 +		case SQLITE_DELETE://                Table Name      NULL
   1.278 +		case SQLITE_INSERT://                Table Name      NULL   
   1.279 +		case SQLITE_UPDATE://                Table Name      Column Name		
   1.280 +		case SQLITE_READ://                  Table Name      Column Name     
   1.281 +		case SQLITE_ATTACH://                Filename        NULL            
   1.282 +		case SQLITE_DETACH://                Database Name   NULL
   1.283 +		case SQLITE_REINDEX://				 Index Name      NULL
   1.284 +		case SQLITE_ANALYZE://				 Table Name      NULL
   1.285 +		case SQLITE_FUNCTION:
   1.286 +			break;
   1.287 +		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
   1.288 +			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), EFalse);
   1.289 +			break;
   1.290 +//All "temp" operations are handled earlier, in CSqlSrvDatabase::AuthorizeCallback(), where a check for "temp"
   1.291 +//database name is performed.
   1.292 +//      case SQLITE_CREATE_TEMP_INDEX://     Index Name      Table Name      
   1.293 +//      case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
   1.294 +//      case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
   1.295 +//      case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
   1.296 +//      case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
   1.297 +//      case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
   1.298 +//      case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
   1.299 +//      case SQLITE_DROP_TEMP_VIEW://        View Name       NULL
   1.300 +//"CREATE VIRTUAL TABLE" and "DROP VIRTUAL TABLE" sql statements are not supported
   1.301 +//		case SQLITE_CREATE_VTABLE:
   1.302 +//		case SQLITE_DROP_VTABLE:
   1.303 +		default:
   1.304 +			__ASSERT_DEBUG(EFalse, __SQLPANIC2(ESqlPanicInternalError));
   1.305 +			break;
   1.306 +			}
   1.307 +	return res;
   1.308 +	}
   1.309 +
   1.310 +/**
   1.311 +This function performs additional permission checks for secure databases
   1.312 +
   1.313 +@param aSecurityPolicy Security policy corresponding to this database
   1.314 +@param aDbOpType Database operation type, which needs to be authorized.
   1.315 +@param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   1.316 +			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.317 +@param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.318 +
   1.319 +@return SQLITE_OK		Access is allowed
   1.320 +@return SQLITE_DENY 	The entire SQL statement should be aborted
   1.321 +@return SQLITE_IGNORE	The column should be treated as it has NULL value
   1.322 +
   1.323 +@panic SqlDb 7 In _DEBUG mode. Unknown/invalid aDbOpType argument.
   1.324 +
   1.325 +@internalComponent
   1.326 + */ 
   1.327 +static TInt SecureChecks(const CSqlSecurityPolicy* aSecurityPolicy,TInt aDbOpType,const char* aDbObjName1, const char* aDbObjName2)
   1.328 +	{
   1.329 +	TPtrC8 tblName(KNullDesC8);
   1.330 +	const char* tblNamePtr = DbOp2TableName(aDbOpType, aDbObjName1, aDbObjName2);
   1.331 +	if(tblNamePtr)
   1.332 +		{
   1.333 +		tblName.Set(reinterpret_cast <const TUint8*> (tblNamePtr));
   1.334 +		}
   1.335 +	
   1.336 +	//Under no circumstances is allowed to do any operation with the system tables.
   1.337 +	//(Even SQLITE_READ operation, because the system tables data is read at the moment when the database
   1.338 +	// is created/opened)
   1.339 +	if(::IsSystemTableName(tblName))
   1.340 +		{
   1.341 +		return SQLITE_DENY;
   1.342 +		}
   1.343 +	//=================================================================
   1.344 +	//	aDbOpType							aDbObjName1		aDbObjName2
   1.345 +	//=================================================================
   1.346 +	MSqlPolicyInspector& inspector = ::SqlServer().SecurityInspector();
   1.347 +	TSecurityPolicy schemaPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::ESchemaPolicy);
   1.348 +	TSecurityPolicy writePolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EWritePolicy);
   1.349 +	TSecurityPolicy readPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EReadPolicy);
   1.350 +	TInt res = SQLITE_OK;
   1.351 +	switch(aDbOpType)
   1.352 +		{
   1.353 +		//"Database schema policy" check
   1.354 +		case SQLITE_CREATE_INDEX://          Index Name      Table Name      
   1.355 +		case SQLITE_CREATE_TABLE://          Table Name      NULL            
   1.356 +		case SQLITE_CREATE_TRIGGER://        Trigger Name    Table Name      
   1.357 +		case SQLITE_CREATE_VIEW://           View Name       NULL            
   1.358 +		case SQLITE_DROP_INDEX://            Index Name      Table Name      
   1.359 +		case SQLITE_DROP_TABLE://            Table Name      NULL            
   1.360 +		case SQLITE_DROP_TRIGGER://          Trigger Name    Table Name      
   1.361 +		case SQLITE_DROP_VIEW://             View Name       NULL            
   1.362 +		case SQLITE_ALTER_TABLE://			 Database Name   Table Name
   1.363 +			if(!inspector.Check(schemaPolicy))
   1.364 +				{
   1.365 +				res = SQLITE_DENY;	
   1.366 +				}
   1.367 +			break;
   1.368 +		//No policy check
   1.369 +		case SQLITE_SELECT://                NULL            NULL            
   1.370 +		case SQLITE_TRANSACTION://           NULL            NULL            
   1.371 +			break;
   1.372 +		//"Database schema policy" for sqlite tables
   1.373 +		//"Database schema policy" || "Database write policy" for user tables
   1.374 +		case SQLITE_DELETE://                Table Name      NULL            
   1.375 +		case SQLITE_INSERT://                Table Name      NULL            
   1.376 +		case SQLITE_UPDATE://                Table Name      Column Name
   1.377 +			if(!inspector.Check(schemaPolicy))
   1.378 +				{
   1.379 +				res = SQLITE_DENY;	
   1.380 +				if(!::IsSqliteTableName(tblName))
   1.381 +					{
   1.382 +					if(inspector.Check(writePolicy))
   1.383 +						{
   1.384 +						res = SQLITE_OK;
   1.385 +						}
   1.386 +					}
   1.387 +				}
   1.388 +			break;
   1.389 +		//"Database schema policy" || "Database read policy" || "Database write policy" for sqlite tables
   1.390 +		//"Database schema policy" || "Database read policy"  for user tables
   1.391 +		case SQLITE_READ://                  Table Name      Column Name     
   1.392 +			if(!(inspector.Check(schemaPolicy) || inspector.Check(readPolicy)))
   1.393 +				{
   1.394 +				res = SQLITE_DENY;	
   1.395 +				if(::IsSqliteTableName(tblName))
   1.396 +					{
   1.397 +					if(inspector.Check(writePolicy))
   1.398 +						{
   1.399 +						res = SQLITE_OK;
   1.400 +						}
   1.401 +					}
   1.402 +				}
   1.403 +			break;
   1.404 +		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
   1.405 +			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), ETrue);	
   1.406 +			break;
   1.407 +		case SQLITE_ATTACH://                Filename        NULL
   1.408 +		case SQLITE_DETACH://                Database Name   NULL
   1.409 +		//If the operation is SQLITE_ATTACH or SQLITE_DETACH, return SQLITE_DENY.
   1.410 +		//"ATTACH DATABASE"/"DETACH DATABASE" operations are performed by separate "attach/detach db" methods.
   1.411 +			res = SQLITE_DENY;	
   1.412 +			break;
   1.413 +		//No policy check
   1.414 +		case SQLITE_REINDEX://				Index Name      NULL
   1.415 +		case SQLITE_ANALYZE://				Table Name      NULL
   1.416 +			break;
   1.417 +		//No policy check
   1.418 +		case SQLITE_FUNCTION:
   1.419 +			break;
   1.420 +//All "temp" operations are handled earlier, in CSqlSrvDatabase::AuthorizeCallback(), where a check for "temp"
   1.421 +//database name is performed.
   1.422 +//      case SQLITE_CREATE_TEMP_INDEX://     Index Name      Table Name      
   1.423 +//      case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
   1.424 +//      case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
   1.425 +//      case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
   1.426 +//      case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
   1.427 +//      case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
   1.428 +//      case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
   1.429 +//      case SQLITE_DROP_TEMP_VIEW://        View Name       NULL            
   1.430 +//"CREATE VIRTUAL TABLE" and "DROP VIRTUAL TABLE" sql statements are not supported
   1.431 +//		case SQLITE_CREATE_VTABLE:
   1.432 +//		case SQLITE_DROP_VTABLE:
   1.433 +		default:
   1.434 +			__ASSERT_DEBUG(EFalse, __SQLPANIC2(ESqlPanicInternalError));
   1.435 +			break;
   1.436 +		}
   1.437 +	return res;
   1.438 +	}
   1.439 +
   1.440 +/**
   1.441 +This callback function is invoked by the SQLITE engine at SQL statement compile time 
   1.442 +for each attempt to access a column of a table in the database.
   1.443 +
   1.444 +The callback returns SQLITE_OK if access is allowed, 
   1.445 +SQLITE_DENY if the entire SQL statement should be aborted with an error and 
   1.446 +SQLITE_IGNORE if the column should be treated as a NULL value.
   1.447 +
   1.448 +@param aDb "This" pointer (to the rellated CSqlSrvDatabase object).
   1.449 +@param aDbOpType Database operation type, which needs to be authorized. It could be one of these:
   1.450 +
   1.451 +@code
   1.452 +=================================================================
   1.453 +aDbOpType						aDbObjName1		aDbObjName2
   1.454 +=================================================================
   1.455 +SQLITE_CREATE_INDEX             Index Name      Table Name      
   1.456 +SQLITE_CREATE_TABLE             Table Name      NULL            
   1.457 +SQLITE_CREATE_TEMP_INDEX        Index Name      Table Name      
   1.458 +SQLITE_CREATE_TEMP_TABLE        Table Name      NULL            
   1.459 +SQLITE_CREATE_TEMP_TRIGGER      Trigger Name    Table Name      
   1.460 +SQLITE_CREATE_TEMP_VIEW         View Name       NULL            
   1.461 +SQLITE_CREATE_TRIGGER           Trigger Name    Table Name      
   1.462 +SQLITE_CREATE_VIEW              View Name       NULL            
   1.463 +SQLITE_DELETE                   Table Name      NULL            
   1.464 +SQLITE_DROP_INDEX               Index Name      Table Name      
   1.465 +SQLITE_DROP_TABLE               Table Name      NULL            
   1.466 +SQLITE_DROP_TEMP_INDEX          Index Name      Table Name      
   1.467 +SQLITE_DROP_TEMP_TABLE          Table Name      NULL            
   1.468 +SQLITE_DROP_TEMP_TRIGGER        Trigger Name    Table Name      
   1.469 +SQLITE_DROP_TEMP_VIEW           View Name       NULL            
   1.470 +SQLITE_DROP_TRIGGER             Trigger Name    Table Name      
   1.471 +SQLITE_DROP_VIEW                View Name       NULL            
   1.472 +SQLITE_INSERT                   Table Name      NULL            
   1.473 +SQLITE_PRAGMA                   Pragma Name     1st arg or NULL 
   1.474 +SQLITE_READ                     Table Name      Column Name     
   1.475 +SQLITE_SELECT                   NULL            NULL            
   1.476 +SQLITE_TRANSACTION              NULL            NULL            
   1.477 +SQLITE_UPDATE                   Table Name      Column Name     
   1.478 +SQLITE_ATTACH                   Filename        NULL            
   1.479 +SQLITE_DETACH                   Database Name   NULL 
   1.480 +SQLITE_ALTER_TABLE          	Database Name   Table Name
   1.481 +SQLITE_REINDEX              	Index Name      NULL
   1.482 +SQLITE_ANALYZE              	Table Name      NULL
   1.483 +SQLITE_CREATE_VTABLE			Table Name	  	Module Name	
   1.484 +SQLITE_DROP_VTABLE          	Table Name      Module Name
   1.485 +SQLITE_FUNCTION				    Function Name   NULL
   1.486 +=================================================================
   1.487 +@endcode
   1.488 +
   1.489 +@param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   1.490 +			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.491 +@param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   1.492 +@param aDbName Database name - "main", "temp", etc. UTF8 encoded, zero-terminated.
   1.493 +@param aTrgOrViewName The name of the inner-most trigger or view that is responsible for the access
   1.494 +			attempt or NULL if this access attempt is directly from input SQL code. UTF8 encoded, zero-terminated.
   1.495 +
   1.496 +@return SQLITE_OK		Access is allowed
   1.497 +@return SQLITE_DENY 	The entire SQL statement should be aborted
   1.498 +@return SQLITE_IGNORE	The column should be treated as it has NULL value
   1.499 +
   1.500 +@panic SqlDb 4 In _DEBUG mode. The authorizer was called with NULL aDb argument.
   1.501 +
   1.502 +@internalComponent
   1.503 +*/
   1.504 +TInt CSqlSrvDatabase::AuthorizeCallback(void* aDb, TInt aDbOpType, 
   1.505 +										const char* aDbObjName1, const char* aDbObjName2, 
   1.506 +										const char* aDbName, const char* aTrgOrViewName)
   1.507 +	{
   1.508 +	UNUSED_ARG(aTrgOrViewName);
   1.509 + 	__ASSERT_DEBUG(aDb != NULL, __SQLPANIC2(ESqlPanicBadArgument));
   1.510 +	
   1.511 +#ifdef _SQL_AUTHORIZER_TRACE_ENABLED
   1.512 +    enum TDbOpType {EOpCreateIndex = 1, EOpCreateTable, EOpCreateTempIndex, EOpCreateTempTable, 
   1.513 +        EOpCreateTempTrigger, EOpCreateTempView, EOpCreateTrigger, EOpCreateView, EOpDelete, EOpDropIndex, 
   1.514 +        EOpDropTable, EOpDropTempIndex, EOpDropTempTable, EOpDropTempTrigger, EOpDropTempView, EOpDropTrigger,
   1.515 +		EOpDropView, EOpInsert, EOpPragma, EOpRead, EOpSelect, EOpTransaction, EOpUpdate, EOpAttach, EOpDettach,
   1.516 +		EOpAlterTable, EOpReindex, EOpAnalyze, EOpCreateVTable, EOpDropVTable, EOpFunctionCall};
   1.517 +	TDbOpType dbOpType = static_cast <TDbOpType> (aDbOpType);//can be seen now in the debugger
   1.518 +	::PrintAuthorizerArguments(dbOpType, aDbObjName1, aDbObjName2, aDbName, aTrgOrViewName);
   1.519 +#endif
   1.520 +
   1.521 +	CSqlSrvDatabase& db = *static_cast <CSqlSrvDatabase*> (aDb);
   1.522 +
   1.523 +	//1. If the authorizer is currently disabled - return SQLITE_OK.
   1.524 +	//   (This happens when a database is attached/detached)
   1.525 +	if(db.iAuthorizerDisabled)
   1.526 +		{
   1.527 +		return SQLITE_OK;	
   1.528 +		}
   1.529 +
   1.530 +	TPtrC8 dbName(KNullDesC8);
   1.531 +	const char* dbNamePtr = DbOp2DbName(aDbOpType, aDbObjName1, aDbName);//dbNamePtr is zero terminated
   1.532 +	if(dbNamePtr)
   1.533 +		{
   1.534 +		dbName.Set(reinterpret_cast <const TUint8*> (dbNamePtr));
   1.535 +		}
   1.536 +	aDbName = NULL;//No more use of aDbName argument inside the function.
   1.537 +	
   1.538 +	//2. If the database name is KTempDb, then allow the access. It is a local database 
   1.539 +	//   (for the client), deleted when closed.
   1.540 +	if(dbName.Compare(KTempDb8) == 0) 	//dbName is guaranteed to be in lower case if it is "temp",
   1.541 +		{								//so it is possible to use binary string comparison
   1.542 +		return SQLITE_OK;	
   1.543 +		}
   1.544 +
   1.545 +	//3. Find the security policies. For DefaultAccess initialized with NULL.
   1.546 +	const CSqlSecurityPolicy* securityPolicy = NULL;
   1.547 +	if(dbName.Compare(KMainDb8) == 0||dbName.Length() == 0)	//dbName is guaranteed to be in lower case if it is "main",
   1.548 +		{								//so it is possible to use binary string comparison
   1.549 +		//4. This is the main database.
   1.550 +		securityPolicy = db.iSecurityPolicy;
   1.551 +		}
   1.552 +	else
   1.553 +		{
   1.554 +		//5. This is an attached database. Find the attached database security policies.
   1.555 +	    //dbNamePtr is used here because it is zero terminated
   1.556 +		TSqlAttachDbPair* attachDbPair = db.iAttachDbMap.Entry(reinterpret_cast <const TUint8*> (dbNamePtr));
   1.557 +		if(attachDbPair)
   1.558 +			{//secure database, find the security policies
   1.559 +			const TUint8* securityMapKey = attachDbPair->iData;
   1.560 +			RSqlSecurityMap& map = ::SqlServer().SecurityMap();
   1.561 +			TSqlSecurityPair* pair = map.Entry(securityMapKey);
   1.562 +			if(pair)
   1.563 +				{
   1.564 +				securityPolicy = pair->iData;
   1.565 +				}
   1.566 +			}
   1.567 +		}
   1.568 +		
   1.569 +	//Here we have: 
   1.570 +	// - valid database name (not NULL);
   1.571 +	
   1.572 +	//6. Default or Security Policy Checks
   1.573 +	return !securityPolicy ? NonSecureChecks(aDbOpType,aDbObjName1,aDbObjName2): SecureChecks(securityPolicy,aDbOpType,aDbObjName1,aDbObjName2);
   1.574 +	}