os/persistentdata/persistentstorage/sql/SRC/Server/SqlSrvAuthorizer.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "SqlSrvAuthorizer.h"	//MSqlPolicyInspector
    17 #include "SqlSrvMain.h"			//CSqlServer
    18 #include "SqlSrvSecurityMap.h"	//RSqlSecurityMap
    19 #include "SqlSrvDatabase.h"		//CSqlSrvDatabase
    20 #include "SqlSecurityImpl.h"	//CSqlSecurityPolicy
    21 #include "SqlSrvDbSysSettings.h"//TSqlDbSysSettings
    22 #include "SqlSrvUtil.h"			//Global server functions
    23 #include "SqlSrvStatementUtil.h"//Global sql statement related functions
    24 #include "SqlSrvStrings.h"		//KTempDb
    25 #include "sqlite3.h"
    26 #include "SqliteSymbian.h"		//sqlite3SymbianLastOsError()
    27 
    28 //This macro is used to suppress "function argument not used" compiler warning.
    29 #define UNUSED_ARG(arg) arg = (arg)
    30 
    31 //Array of pragma commands 
    32 const TPtrC8 KPragmaCommands[] = 
    33 	{
    34 	KAutoVacuum(),	KCacheSize(), KCaseSensitiveLike(), KCountChanges(), KDefaultCacheSize(),
    35 	KEmptyResultCallbacks(), KEncoding(), KFullColumnNames(), KFullfsync(), KIncrementalVacuum(), 
    36 	KJournalMode(), KJournalSizeLimit(), KLegacyFileFormat(), KLockingMode(), KPageSize(),
    37 	KMaxPageCount(), KReadUncommitted(), KShortColumnNames(), KSynchronousFlag(), KTempStore(), 
    38 	KTempStoreDirectory(), KDatabaseList(), KForeignKeyList(), KFreelistCount(), KIndexInfo(), 
    39 	KIndexIist(), KPageCount(),KTableInfo(), KSchemaVersion(), KUserVersion(),
    40 	KIntegrityCheck(),KParserTrace(), KVdbeTrace(), KdbeListing()
    41 	};
    42 
    43 const TInt KMaxPragmaCommands = sizeof(KPragmaCommands) / sizeof(KPragmaCommands[0]);
    44 
    45 
    46 //Define the different ways of calling a pragam depending on the following
    47 // 1) If its a secure or non secure database
    48 // 2) If the pragma is called with a parameter (write) or without a parameter (read)
    49 struct TPragmaAccess
    50 	{
    51 	TInt iNonSecureRead; 
    52 	TInt iNonSecureWrite;
    53 	TInt iSecureRead;
    54 	TInt iSecureWrite;
    55 	};
    56 
    57 //Table specifying the permissions for each pragma command for secure (shared) and non-secure (public and private)
    58 //databases. For each database permissions for the following situations are specified
    59 //1) With Parameter - e.g "Pragma auto_vacuum = 0"
    60 //2) Without Parameter - e.g "Pragma auto_vacuum" 
    61 
    62 //Permissions "without parameters" usually apply to a pragma query (or read)
    63 //Permissions "with parameters" usually apply to pragama set (or write)
    64 //However please note that this is not always the case. e.g "index_info" requires a parameter but is used to query
    65 //(or read) the database and not a pragma set. 
    66 const TPragmaAccess KPermissionsTable[KMaxPragmaCommands] = 
    67 	{
    68 	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    69 	//				NON_SECURE					|				SECURE				|
    70 	//  W/Out Parameter		|With Parameter		|W/Out Parameter|With  Parameter	|Pragma Command 
    71 	/////////////////////////////////////////////////////////////////////////////////////////////////////////////
    72 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY, 	SQLITE_DENY}, 		//0. auto_vacuum
    73 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//1.cache_size
    74 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//2.case_sensitive_like
    75 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY}, 		//3.count_changes
    76 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//4.cache_size
    77 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//5.empty_result_callbacks
    78 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},  		//6.encoding
    79 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//7.full_column_names
    80 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//8.fullfsync
    81 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//9.incremental_vacuum
    82 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//10.journal_mode
    83 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//11.journal_size_limit
    84 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY}, 		//12.legacy_file_format
    85 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//13.locking_mode
    86 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//14.page_size
    87 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//15.max_page_count
    88 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//16.read_uncommitted
    89 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//17.short_column_names
    90 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//18.synchronous
    91 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//19.temp_store
    92 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//20.temp_store_directory
    93 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//21.database_list
    94 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//22.foreign_key_list
    95 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//23.freelist_count
    96 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//24.index_info
    97 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//25.index_list
    98 		{SQLITE_IGNORE,		SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//26.page_count
    99 		{SQLITE_OK,			SQLITE_OK,			SQLITE_DENY,	SQLITE_DENY},		//27.table_info
   100 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//28.schema_version
   101 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//29.user_version
   102 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//30.integrity_check
   103 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//31.parser_trace
   104 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//32.vdbe_trace
   105 		{SQLITE_OK,			SQLITE_IGNORE,		SQLITE_DENY,	SQLITE_DENY},		//33.vdbe_listing
   106 	};
   107 
   108 
   109 //This const array describes the relation between the database operation type and
   110 //the number of the authorizer argument where the table name is.
   111 //For example:
   112 //- SQLITE_CREATE_TEMP_TABLE operation. The table name is in aDbObjName1 argument, so the array element value is 1.
   113 //- SQLITE_PRAGMA operation. No table name for this operation, so the array element value is 0.
   114 //- SQLITE_CREATE_TEMP_TRIGGER operation. The table name is in aDbObjName2 argument, so the array element value is 2.
   115 const TUint8 KTableNameArgIndex[] =
   116 	{
   117 	/////////////////////////////////////////////////////////////////
   118 	//									  aDbObjName1	  aDbObjName2
   119 	/////////////////////////////////////////////////////////////////
   120 	1,	//SQLITE_COPY                     Table Name      Filename 
   121 	2,	//SQLITE_CREATE_INDEX             Index Name      Table Name      
   122 	1,	//SQLITE_CREATE_TABLE             Table Name      NULL            
   123 	2,	//SQLITE_CREATE_TEMP_INDEX        Index Name      Table Name      
   124 	1,	//SQLITE_CREATE_TEMP_TABLE        Table Name      NULL            
   125 	2,	//SQLITE_CREATE_TEMP_TRIGGER      Trigger Name    Table Name      
   126 	0,	//SQLITE_CREATE_TEMP_VIEW         View Name       NULL            
   127 	2,	//SQLITE_CREATE_TRIGGER           Trigger Name    Table Name      
   128 	0,	//SQLITE_CREATE_VIEW              View Name       NULL            
   129 	1,	//SQLITE_DELETE                   Table Name      NULL            
   130 	2,	//SQLITE_DROP_INDEX               Index Name      Table Name      
   131 	1,	//SQLITE_DROP_TABLE               Table Name      NULL            
   132 	2,	//SQLITE_DROP_TEMP_INDEX          Index Name      Table Name      
   133 	1,	//SQLITE_DROP_TEMP_TABLE          Table Name      NULL            
   134 	2,	//SQLITE_DROP_TEMP_TRIGGER        Trigger Name    Table Name      
   135 	0,	//SQLITE_DROP_TEMP_VIEW           View Name       NULL            
   136 	2,	//SQLITE_DROP_TRIGGER             Trigger Name    Table Name      
   137 	0,	//SQLITE_DROP_VIEW                View Name       NULL            
   138 	1,	//SQLITE_INSERT                   Table Name      NULL            
   139 	0,	//SQLITE_PRAGMA                   Pragma Name     1st arg or NULL 
   140 	1,	//SQLITE_READ                     Table Name      Column Name     
   141 	0,	//SQLITE_SELECT                   NULL            NULL            
   142 	0,	//SQLITE_TRANSACTION              NULL            NULL            
   143 	1,	//SQLITE_UPDATE                   Table Name      Column Name     
   144 	0,	//SQLITE_ATTACH                   Filename        NULL            
   145 	0,	//SQLITE_DETACH                   Database Name   NULL 
   146 	2,	//SQLITE_ALTER_TABLE          	  Database Name   Table Name
   147 	0,	//SQLITE_REINDEX              	  Index Name      NULL
   148 	1,	//SQLITE_ANALYZE              	  Table Name      NULL
   149 	1,	//SQLITE_CREATE_VTABLE			  Table Name	  Module Name	
   150 	1,	//SQLITE_DROP_VTABLE          	  Table Name      Module Name
   151 	0	//SQLITE_FUNCTION				  Function Name   NULL
   152 	};
   153 
   154 //The function returns the argument number where the table name is.
   155 inline TInt DbOp2TableNameArgIndex(TInt aDbOpType)
   156 	{
   157 	__ASSERT_DEBUG(aDbOpType > 0 && aDbOpType <= SQLITE_FUNCTION, __SQLPANIC2(ESqlPanicInternalError));
   158 	return KTableNameArgIndex[aDbOpType];
   159 	}
   160 
   161 //The function returns the table name, which may be in aDbObjName1 or aDbObjName2, depending on aDbOpType value.
   162 //The return value is "const char" pointer to a zero terminated string.
   163 inline const char* DbOp2TableName(TInt aDbOpType, const char* aDbObjName1, const char* aDbObjName2)
   164 	{
   165 	TInt pos = DbOp2TableNameArgIndex(aDbOpType);
   166 	if(pos == 2)
   167 		{
   168 		__ASSERT_DEBUG(aDbObjName2 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   169 		return aDbObjName2;
   170 		}
   171 	else if(pos == 1)
   172 		{
   173 		__ASSERT_DEBUG(aDbObjName1 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   174 		return aDbObjName1;
   175 		}
   176 	return NULL;//Some database operations do not use table name
   177 	}
   178 
   179 //This function returns the database name which may be in aDbObjName1 or aDbName depending on aDbOpType value.
   180 //The return value is "const char" pointer to a zero terminated string.
   181 inline const char* DbOp2DbName(TInt aDbOpType, const char* aDbObjName1, const char* aDbName)
   182 	{
   183 	if(aDbOpType == SQLITE_DETACH || aDbOpType == SQLITE_ALTER_TABLE)
   184 		{
   185 		__ASSERT_DEBUG(aDbObjName1 != NULL, __SQLPANIC2(ESqlPanicInternalError));
   186 		return aDbObjName1;
   187 		}
   188 	return aDbName;//It may be NULL for some database operations
   189 	}
   190 
   191 /**
   192 This function performs pragma permission checks for non-secure and secure databases
   193 
   194 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   195 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   196 @param aParamUsed ETrue if the pragma command has been executed with a parameter, EFalse otherwise
   197 @param aSecure ETrue if the pragam check if for secure database, EFalse otherwise
   198 
   199 @return SQLITE_OK		Access is allowed
   200 @return SQLITE_DENY 	The entire SQL statement should be aborted
   201 @return SQLITE_IGNORE	The column should be treated as it has NULL value
   202 
   203 @internalComponent
   204  */ 
   205 static TInt PragmaCheck(const char* aDbObjName1, TBool aParamUsed, TBool aSecure)
   206 	{
   207 	//Retreive the pragma name
   208 	TPtrC8 DbObjName1(KNullDesC8);
   209 	DbObjName1.Set(reinterpret_cast <const TUint8*> (aDbObjName1));
   210 	
   211 	//Access the pragma permissions table depending if its :-
   212 	// 1) Secure or non-secure database.
   213 	// 2) Parameter was used or not.
   214 	for (TInt index=0; index<KMaxPragmaCommands; index++)
   215 		{
   216 		if (CompareNoCase8(DbObjName1,KPragmaCommands[index])== 0)
   217 			{
   218 			if (aSecure)
   219 				{
   220 				if(aParamUsed)
   221 					return KPermissionsTable[index].iSecureWrite;
   222 				else
   223 					return KPermissionsTable[index].iSecureRead;
   224 				}
   225 			else
   226 				{
   227 				if(aParamUsed)
   228 					return KPermissionsTable[index].iNonSecureWrite;
   229 				else
   230 					return KPermissionsTable[index].iNonSecureRead;
   231 				}
   232 			}
   233 		}
   234 	//If the pragma is not on the list then deny access
   235 	return SQLITE_DENY;
   236 	}
   237 
   238 
   239 /**
   240 This function performs additional permission checks for non-secure (private and public) databases
   241 
   242 @param aDbOpType Database operation type, which needs to be authorized.
   243 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   244 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   245 @param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   246 
   247 @return SQLITE_OK		Access is allowed
   248 @return SQLITE_DENY 	The entire SQL statement should be aborted
   249 @return SQLITE_IGNORE	The column should be treated as it has NULL value
   250 
   251 @panic SqlDb 7 In _DEBUG mode. Unknown/invalid aDbOpType argument.
   252 
   253 @internalComponent
   254  */ 
   255 static TInt NonSecureChecks(TInt aDbOpType,const char* aDbObjName1, const char* aDbObjName2)
   256 	{
   257 	//=================================================================
   258 	//	aDbOpType							aDbObjName1		aDbObjName2
   259 	//=================================================================
   260 	TInt res = SQLITE_OK;
   261 	switch(aDbOpType)
   262 		{
   263 		case SQLITE_CREATE_INDEX://          Index Name      Table Name      
   264 		case SQLITE_CREATE_TABLE://          Table Name      NULL            
   265 		case SQLITE_CREATE_TRIGGER://        Trigger Name    Table Name      
   266 		case SQLITE_CREATE_VIEW://           View Name       NULL            
   267 		case SQLITE_DROP_INDEX://            Index Name      Table Name            
   268 		case SQLITE_DROP_TABLE://            Table Name      NULL 
   269 		case SQLITE_DROP_TRIGGER://          Trigger Name    Table Name      
   270 		case SQLITE_DROP_VIEW://             View Name       NULL            
   271 		case SQLITE_ALTER_TABLE://			 Database Name   Table Name
   272 		case SQLITE_SELECT://                NULL            NULL            
   273 		case SQLITE_TRANSACTION://           NULL            NULL          
   274 		case SQLITE_DELETE://                Table Name      NULL
   275 		case SQLITE_INSERT://                Table Name      NULL   
   276 		case SQLITE_UPDATE://                Table Name      Column Name		
   277 		case SQLITE_READ://                  Table Name      Column Name     
   278 		case SQLITE_ATTACH://                Filename        NULL            
   279 		case SQLITE_DETACH://                Database Name   NULL
   280 		case SQLITE_REINDEX://				 Index Name      NULL
   281 		case SQLITE_ANALYZE://				 Table Name      NULL
   282 		case SQLITE_FUNCTION:
   283 			break;
   284 		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
   285 			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), EFalse);
   286 			break;
   287 //All "temp" operations are handled earlier, in CSqlSrvDatabase::AuthorizeCallback(), where a check for "temp"
   288 //database name is performed.
   289 //      case SQLITE_CREATE_TEMP_INDEX://     Index Name      Table Name      
   290 //      case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
   291 //      case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
   292 //      case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
   293 //      case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
   294 //      case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
   295 //      case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
   296 //      case SQLITE_DROP_TEMP_VIEW://        View Name       NULL
   297 //"CREATE VIRTUAL TABLE" and "DROP VIRTUAL TABLE" sql statements are not supported
   298 //		case SQLITE_CREATE_VTABLE:
   299 //		case SQLITE_DROP_VTABLE:
   300 		default:
   301 			__ASSERT_DEBUG(EFalse, __SQLPANIC2(ESqlPanicInternalError));
   302 			break;
   303 			}
   304 	return res;
   305 	}
   306 
   307 /**
   308 This function performs additional permission checks for secure databases
   309 
   310 @param aSecurityPolicy Security policy corresponding to this database
   311 @param aDbOpType Database operation type, which needs to be authorized.
   312 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   313 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   314 @param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   315 
   316 @return SQLITE_OK		Access is allowed
   317 @return SQLITE_DENY 	The entire SQL statement should be aborted
   318 @return SQLITE_IGNORE	The column should be treated as it has NULL value
   319 
   320 @panic SqlDb 7 In _DEBUG mode. Unknown/invalid aDbOpType argument.
   321 
   322 @internalComponent
   323  */ 
   324 static TInt SecureChecks(const CSqlSecurityPolicy* aSecurityPolicy,TInt aDbOpType,const char* aDbObjName1, const char* aDbObjName2)
   325 	{
   326 	TPtrC8 tblName(KNullDesC8);
   327 	const char* tblNamePtr = DbOp2TableName(aDbOpType, aDbObjName1, aDbObjName2);
   328 	if(tblNamePtr)
   329 		{
   330 		tblName.Set(reinterpret_cast <const TUint8*> (tblNamePtr));
   331 		}
   332 	
   333 	//Under no circumstances is allowed to do any operation with the system tables.
   334 	//(Even SQLITE_READ operation, because the system tables data is read at the moment when the database
   335 	// is created/opened)
   336 	if(::IsSystemTableName(tblName))
   337 		{
   338 		return SQLITE_DENY;
   339 		}
   340 	//=================================================================
   341 	//	aDbOpType							aDbObjName1		aDbObjName2
   342 	//=================================================================
   343 	MSqlPolicyInspector& inspector = ::SqlServer().SecurityInspector();
   344 	TSecurityPolicy schemaPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::ESchemaPolicy);
   345 	TSecurityPolicy writePolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EWritePolicy);
   346 	TSecurityPolicy readPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EReadPolicy);
   347 	TInt res = SQLITE_OK;
   348 	switch(aDbOpType)
   349 		{
   350 		//"Database schema policy" check
   351 		case SQLITE_CREATE_INDEX://          Index Name      Table Name      
   352 		case SQLITE_CREATE_TABLE://          Table Name      NULL            
   353 		case SQLITE_CREATE_TRIGGER://        Trigger Name    Table Name      
   354 		case SQLITE_CREATE_VIEW://           View Name       NULL            
   355 		case SQLITE_DROP_INDEX://            Index Name      Table Name      
   356 		case SQLITE_DROP_TABLE://            Table Name      NULL            
   357 		case SQLITE_DROP_TRIGGER://          Trigger Name    Table Name      
   358 		case SQLITE_DROP_VIEW://             View Name       NULL            
   359 		case SQLITE_ALTER_TABLE://			 Database Name   Table Name
   360 			if(!inspector.Check(schemaPolicy))
   361 				{
   362 				res = SQLITE_DENY;	
   363 				}
   364 			break;
   365 		//No policy check
   366 		case SQLITE_SELECT://                NULL            NULL            
   367 		case SQLITE_TRANSACTION://           NULL            NULL            
   368 			break;
   369 		//"Database schema policy" for sqlite tables
   370 		//"Database schema policy" || "Database write policy" for user tables
   371 		case SQLITE_DELETE://                Table Name      NULL            
   372 		case SQLITE_INSERT://                Table Name      NULL            
   373 		case SQLITE_UPDATE://                Table Name      Column Name
   374 			if(!inspector.Check(schemaPolicy))
   375 				{
   376 				res = SQLITE_DENY;	
   377 				if(!::IsSqliteTableName(tblName))
   378 					{
   379 					if(inspector.Check(writePolicy))
   380 						{
   381 						res = SQLITE_OK;
   382 						}
   383 					}
   384 				}
   385 			break;
   386 		//"Database schema policy" || "Database read policy" || "Database write policy" for sqlite tables
   387 		//"Database schema policy" || "Database read policy"  for user tables
   388 		case SQLITE_READ://                  Table Name      Column Name     
   389 			if(!(inspector.Check(schemaPolicy) || inspector.Check(readPolicy)))
   390 				{
   391 				res = SQLITE_DENY;	
   392 				if(::IsSqliteTableName(tblName))
   393 					{
   394 					if(inspector.Check(writePolicy))
   395 						{
   396 						res = SQLITE_OK;
   397 						}
   398 					}
   399 				}
   400 			break;
   401 		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
   402 			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), ETrue);	
   403 			break;
   404 		case SQLITE_ATTACH://                Filename        NULL
   405 		case SQLITE_DETACH://                Database Name   NULL
   406 		//If the operation is SQLITE_ATTACH or SQLITE_DETACH, return SQLITE_DENY.
   407 		//"ATTACH DATABASE"/"DETACH DATABASE" operations are performed by separate "attach/detach db" methods.
   408 			res = SQLITE_DENY;	
   409 			break;
   410 		//No policy check
   411 		case SQLITE_REINDEX://				Index Name      NULL
   412 		case SQLITE_ANALYZE://				Table Name      NULL
   413 			break;
   414 		//No policy check
   415 		case SQLITE_FUNCTION:
   416 			break;
   417 //All "temp" operations are handled earlier, in CSqlSrvDatabase::AuthorizeCallback(), where a check for "temp"
   418 //database name is performed.
   419 //      case SQLITE_CREATE_TEMP_INDEX://     Index Name      Table Name      
   420 //      case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
   421 //      case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
   422 //      case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
   423 //      case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
   424 //      case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
   425 //      case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
   426 //      case SQLITE_DROP_TEMP_VIEW://        View Name       NULL            
   427 //"CREATE VIRTUAL TABLE" and "DROP VIRTUAL TABLE" sql statements are not supported
   428 //		case SQLITE_CREATE_VTABLE:
   429 //		case SQLITE_DROP_VTABLE:
   430 		default:
   431 			__ASSERT_DEBUG(EFalse, __SQLPANIC2(ESqlPanicInternalError));
   432 			break;
   433 		}
   434 	return res;
   435 	}
   436 
   437 /**
   438 This callback function is invoked by the SQLITE engine at SQL statement compile time 
   439 for each attempt to access a column of a table in the database.
   440 
   441 The callback returns SQLITE_OK if access is allowed, 
   442 SQLITE_DENY if the entire SQL statement should be aborted with an error and 
   443 SQLITE_IGNORE if the column should be treated as a NULL value.
   444 
   445 @param aDb "This" pointer (to the rellated CSqlSrvDatabase object).
   446 @param aDbOpType Database operation type, which needs to be authorized. It could be one of these:
   447 
   448 @code
   449 =================================================================
   450 aDbOpType						aDbObjName1		aDbObjName2
   451 =================================================================
   452 SQLITE_CREATE_INDEX             Index Name      Table Name      
   453 SQLITE_CREATE_TABLE             Table Name      NULL            
   454 SQLITE_CREATE_TEMP_INDEX        Index Name      Table Name      
   455 SQLITE_CREATE_TEMP_TABLE        Table Name      NULL            
   456 SQLITE_CREATE_TEMP_TRIGGER      Trigger Name    Table Name      
   457 SQLITE_CREATE_TEMP_VIEW         View Name       NULL            
   458 SQLITE_CREATE_TRIGGER           Trigger Name    Table Name      
   459 SQLITE_CREATE_VIEW              View Name       NULL            
   460 SQLITE_DELETE                   Table Name      NULL            
   461 SQLITE_DROP_INDEX               Index Name      Table Name      
   462 SQLITE_DROP_TABLE               Table Name      NULL            
   463 SQLITE_DROP_TEMP_INDEX          Index Name      Table Name      
   464 SQLITE_DROP_TEMP_TABLE          Table Name      NULL            
   465 SQLITE_DROP_TEMP_TRIGGER        Trigger Name    Table Name      
   466 SQLITE_DROP_TEMP_VIEW           View Name       NULL            
   467 SQLITE_DROP_TRIGGER             Trigger Name    Table Name      
   468 SQLITE_DROP_VIEW                View Name       NULL            
   469 SQLITE_INSERT                   Table Name      NULL            
   470 SQLITE_PRAGMA                   Pragma Name     1st arg or NULL 
   471 SQLITE_READ                     Table Name      Column Name     
   472 SQLITE_SELECT                   NULL            NULL            
   473 SQLITE_TRANSACTION              NULL            NULL            
   474 SQLITE_UPDATE                   Table Name      Column Name     
   475 SQLITE_ATTACH                   Filename        NULL            
   476 SQLITE_DETACH                   Database Name   NULL 
   477 SQLITE_ALTER_TABLE          	Database Name   Table Name
   478 SQLITE_REINDEX              	Index Name      NULL
   479 SQLITE_ANALYZE              	Table Name      NULL
   480 SQLITE_CREATE_VTABLE			Table Name	  	Module Name	
   481 SQLITE_DROP_VTABLE          	Table Name      Module Name
   482 SQLITE_FUNCTION				    Function Name   NULL
   483 =================================================================
   484 @endcode
   485 
   486 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
   487 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
   488 @param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
   489 @param aDbName Database name - "main", "temp", etc. UTF8 encoded, zero-terminated.
   490 @param aTrgOrViewName The name of the inner-most trigger or view that is responsible for the access
   491 			attempt or NULL if this access attempt is directly from input SQL code. UTF8 encoded, zero-terminated.
   492 
   493 @return SQLITE_OK		Access is allowed
   494 @return SQLITE_DENY 	The entire SQL statement should be aborted
   495 @return SQLITE_IGNORE	The column should be treated as it has NULL value
   496 
   497 @panic SqlDb 4 In _DEBUG mode. The authorizer was called with NULL aDb argument.
   498 
   499 @internalComponent
   500 */
   501 TInt CSqlSrvDatabase::AuthorizeCallback(void* aDb, TInt aDbOpType, 
   502 										const char* aDbObjName1, const char* aDbObjName2, 
   503 										const char* aDbName, const char* aTrgOrViewName)
   504 	{
   505 	UNUSED_ARG(aTrgOrViewName);
   506  	__ASSERT_DEBUG(aDb != NULL, __SQLPANIC2(ESqlPanicBadArgument));
   507 	
   508 #ifdef _SQL_AUTHORIZER_TRACE_ENABLED
   509     enum TDbOpType {EOpCreateIndex = 1, EOpCreateTable, EOpCreateTempIndex, EOpCreateTempTable, 
   510         EOpCreateTempTrigger, EOpCreateTempView, EOpCreateTrigger, EOpCreateView, EOpDelete, EOpDropIndex, 
   511         EOpDropTable, EOpDropTempIndex, EOpDropTempTable, EOpDropTempTrigger, EOpDropTempView, EOpDropTrigger,
   512 		EOpDropView, EOpInsert, EOpPragma, EOpRead, EOpSelect, EOpTransaction, EOpUpdate, EOpAttach, EOpDettach,
   513 		EOpAlterTable, EOpReindex, EOpAnalyze, EOpCreateVTable, EOpDropVTable, EOpFunctionCall};
   514 	TDbOpType dbOpType = static_cast <TDbOpType> (aDbOpType);//can be seen now in the debugger
   515 	::PrintAuthorizerArguments(dbOpType, aDbObjName1, aDbObjName2, aDbName, aTrgOrViewName);
   516 #endif
   517 
   518 	CSqlSrvDatabase& db = *static_cast <CSqlSrvDatabase*> (aDb);
   519 
   520 	//1. If the authorizer is currently disabled - return SQLITE_OK.
   521 	//   (This happens when a database is attached/detached)
   522 	if(db.iAuthorizerDisabled)
   523 		{
   524 		return SQLITE_OK;	
   525 		}
   526 
   527 	TPtrC8 dbName(KNullDesC8);
   528 	const char* dbNamePtr = DbOp2DbName(aDbOpType, aDbObjName1, aDbName);//dbNamePtr is zero terminated
   529 	if(dbNamePtr)
   530 		{
   531 		dbName.Set(reinterpret_cast <const TUint8*> (dbNamePtr));
   532 		}
   533 	aDbName = NULL;//No more use of aDbName argument inside the function.
   534 	
   535 	//2. If the database name is KTempDb, then allow the access. It is a local database 
   536 	//   (for the client), deleted when closed.
   537 	if(dbName.Compare(KTempDb8) == 0) 	//dbName is guaranteed to be in lower case if it is "temp",
   538 		{								//so it is possible to use binary string comparison
   539 		return SQLITE_OK;	
   540 		}
   541 
   542 	//3. Find the security policies. For DefaultAccess initialized with NULL.
   543 	const CSqlSecurityPolicy* securityPolicy = NULL;
   544 	if(dbName.Compare(KMainDb8) == 0||dbName.Length() == 0)	//dbName is guaranteed to be in lower case if it is "main",
   545 		{								//so it is possible to use binary string comparison
   546 		//4. This is the main database.
   547 		securityPolicy = db.iSecurityPolicy;
   548 		}
   549 	else
   550 		{
   551 		//5. This is an attached database. Find the attached database security policies.
   552 	    //dbNamePtr is used here because it is zero terminated
   553 		TSqlAttachDbPair* attachDbPair = db.iAttachDbMap.Entry(reinterpret_cast <const TUint8*> (dbNamePtr));
   554 		if(attachDbPair)
   555 			{//secure database, find the security policies
   556 			const TUint8* securityMapKey = attachDbPair->iData;
   557 			RSqlSecurityMap& map = ::SqlServer().SecurityMap();
   558 			TSqlSecurityPair* pair = map.Entry(securityMapKey);
   559 			if(pair)
   560 				{
   561 				securityPolicy = pair->iData;
   562 				}
   563 			}
   564 		}
   565 		
   566 	//Here we have: 
   567 	// - valid database name (not NULL);
   568 	
   569 	//6. Default or Security Policy Checks
   570 	return !securityPolicy ? NonSecureChecks(aDbOpType,aDbObjName1,aDbObjName2): SecureChecks(securityPolicy,aDbOpType,aDbObjName1,aDbObjName2);
   571 	}