persistentstorage/sql/SRC/Server/SqlSrvAuthorizer.cpp
changeset 0 08ec8eefde2f
child 8 fa9941cf3867
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2005-2009 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 	__SQLASSERT(aDbOpType > 0 && aDbOpType <= SQLITE_FUNCTION, 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 		__SQLASSERT(aDbObjName2 != NULL, ESqlPanicInternalError);
       
   169 		return aDbObjName2;
       
   170 		}
       
   171 	else if(pos == 1)
       
   172 		{
       
   173 		__SQLASSERT(aDbObjName1 != NULL, 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 		__SQLASSERT(aDbObjName1 != NULL, 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_CREATE_TEMP_INDEX://     Index Name      Table Name      
       
   273 		case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
       
   274 		case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
       
   275 		case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
       
   276 		case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
       
   277 		case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
       
   278 		case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
       
   279 		case SQLITE_DROP_TEMP_VIEW://        View Name       NULL            
       
   280 		case SQLITE_SELECT://                NULL            NULL            
       
   281 		case SQLITE_TRANSACTION://           NULL            NULL          
       
   282 		case SQLITE_DELETE://                Table Name      NULL
       
   283 		case SQLITE_INSERT://                Table Name      NULL   
       
   284 		case SQLITE_UPDATE://                Table Name      Column Name		
       
   285 		case SQLITE_READ://                  Table Name      Column Name     
       
   286 		case SQLITE_ATTACH://                Filename        NULL            
       
   287 		case SQLITE_DETACH://                Database Name   NULL
       
   288 		case SQLITE_REINDEX://				 Index Name      NULL
       
   289 		case SQLITE_ANALYZE://				 Table Name      NULL
       
   290 		case SQLITE_CREATE_VTABLE:
       
   291 		case SQLITE_DROP_VTABLE:
       
   292 		case SQLITE_FUNCTION:
       
   293 			break;
       
   294 		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
       
   295 			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), EFalse);
       
   296 			break;
       
   297 		default:
       
   298 			__SQLASSERT(EFalse, ESqlPanicInternalError);
       
   299 			break;
       
   300 			}
       
   301 	return res;
       
   302 	}
       
   303 
       
   304 /**
       
   305 This function performs additional permission checks for secure databases
       
   306 
       
   307 @param aSecurityPolicy Security policy corresponding to this database
       
   308 @param aDbOpType Database operation type, which needs to be authorized.
       
   309 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
       
   310 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
       
   311 @param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
       
   312 
       
   313 @return SQLITE_OK		Access is allowed
       
   314 @return SQLITE_DENY 	The entire SQL statement should be aborted
       
   315 @return SQLITE_IGNORE	The column should be treated as it has NULL value
       
   316 
       
   317 @panic SqlDb 7 In _DEBUG mode. Unknown/invalid aDbOpType argument.
       
   318 
       
   319 @internalComponent
       
   320  */ 
       
   321 static TInt SecureChecks(const CSqlSecurityPolicy* aSecurityPolicy,TInt aDbOpType,const char* aDbObjName1, const char* aDbObjName2)
       
   322 	{
       
   323 	TPtrC8 tblName(KNullDesC8);
       
   324 	const char* tblNamePtr = DbOp2TableName(aDbOpType, aDbObjName1, aDbObjName2);
       
   325 	if(tblNamePtr)
       
   326 		{
       
   327 		tblName.Set(reinterpret_cast <const TUint8*> (tblNamePtr));
       
   328 		}
       
   329 	
       
   330 	//Under no circumstances is allowed to do any operation with the system tables.
       
   331 	//(Even SQLITE_READ operation, because the system tables data is read at the moment when the database
       
   332 	// is created/opened)
       
   333 	if(::IsSystemTableName(tblName))
       
   334 		{
       
   335 		return SQLITE_DENY;
       
   336 		}
       
   337 	//=================================================================
       
   338 	//	aDbOpType							aDbObjName1		aDbObjName2
       
   339 	//=================================================================
       
   340 	MSqlPolicyInspector& inspector = ::SqlServer().SecurityInspector();
       
   341 	TSecurityPolicy schemaPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::ESchemaPolicy);
       
   342 	TSecurityPolicy writePolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EWritePolicy);
       
   343 	TSecurityPolicy readPolicy = aSecurityPolicy->DbPolicy(RSqlSecurityPolicy::EReadPolicy);
       
   344 	TInt res = SQLITE_OK;
       
   345 	switch(aDbOpType)
       
   346 		{
       
   347 		//"Database schema policy" check
       
   348 		case SQLITE_CREATE_INDEX://          Index Name      Table Name      
       
   349 		case SQLITE_CREATE_TABLE://          Table Name      NULL            
       
   350 		case SQLITE_CREATE_TRIGGER://        Trigger Name    Table Name      
       
   351 		case SQLITE_CREATE_VIEW://           View Name       NULL            
       
   352 		case SQLITE_DROP_INDEX://            Index Name      Table Name      
       
   353 		case SQLITE_DROP_TABLE://            Table Name      NULL            
       
   354 		case SQLITE_DROP_TRIGGER://          Trigger Name    Table Name      
       
   355 		case SQLITE_DROP_VIEW://             View Name       NULL            
       
   356 		case SQLITE_ALTER_TABLE://			 Database Name   Table Name
       
   357 			if(!inspector.Check(schemaPolicy))
       
   358 				{
       
   359 				res = SQLITE_DENY;	
       
   360 				}
       
   361 			break;
       
   362 		//No policy check
       
   363 		case SQLITE_CREATE_TEMP_INDEX://     Index Name      Table Name      
       
   364 		case SQLITE_CREATE_TEMP_TABLE://     Table Name      NULL            
       
   365 		case SQLITE_CREATE_TEMP_TRIGGER://   Trigger Name    Table Name      
       
   366 		case SQLITE_CREATE_TEMP_VIEW://      View Name       NULL            
       
   367 		case SQLITE_DROP_TEMP_INDEX://       Index Name      Table Name      
       
   368 		case SQLITE_DROP_TEMP_TABLE://       Table Name      NULL            
       
   369 		case SQLITE_DROP_TEMP_TRIGGER://     Trigger Name    Table Name      
       
   370 		case SQLITE_DROP_TEMP_VIEW://        View Name       NULL            
       
   371 		case SQLITE_SELECT://                NULL            NULL            
       
   372 		case SQLITE_TRANSACTION://           NULL            NULL            
       
   373 			break;
       
   374 		//"Database schema policy" for sqlite tables
       
   375 		//"Database schema policy" || "Database write policy" for user tables
       
   376 		case SQLITE_DELETE://                Table Name      NULL            
       
   377 		case SQLITE_INSERT://                Table Name      NULL            
       
   378 		case SQLITE_UPDATE://                Table Name      Column Name
       
   379 			if(!inspector.Check(schemaPolicy))
       
   380 				{
       
   381 				res = SQLITE_DENY;	
       
   382 				if(!::IsSqliteTableName(tblName))
       
   383 					{
       
   384 					if(inspector.Check(writePolicy))
       
   385 						{
       
   386 						res = SQLITE_OK;
       
   387 						}
       
   388 					}
       
   389 				}
       
   390 			break;
       
   391 		//"Database schema policy" || "Database read policy" || "Database write policy" for sqlite tables
       
   392 		//"Database schema policy" || "Database read policy"  for user tables
       
   393 		case SQLITE_READ://                  Table Name      Column Name     
       
   394 			if(!(inspector.Check(schemaPolicy) || inspector.Check(readPolicy)))
       
   395 				{
       
   396 				res = SQLITE_DENY;	
       
   397 				if(::IsSqliteTableName(tblName))
       
   398 					{
       
   399 					if(inspector.Check(writePolicy))
       
   400 						{
       
   401 						res = SQLITE_OK;
       
   402 						}
       
   403 					}
       
   404 				}
       
   405 			break;
       
   406 		case SQLITE_PRAGMA://                Pragma Name     1st arg or NULL 
       
   407 			res = PragmaCheck(aDbObjName1, (aDbObjName2 != NULL), ETrue);	
       
   408 			break;
       
   409 		case SQLITE_ATTACH://                Filename        NULL
       
   410 		case SQLITE_DETACH://                Database Name   NULL
       
   411 		//If the operation is SQLITE_ATTACH or SQLITE_DETACH, return SQLITE_DENY.
       
   412 		//"ATTACH DATABASE"/"DETACH DATABASE" operations are performed by separate "attach/detach db" methods.
       
   413 			res = SQLITE_DENY;	
       
   414 			break;
       
   415 		//No policy check
       
   416 		case SQLITE_REINDEX://				Index Name      NULL
       
   417 		case SQLITE_ANALYZE://				Table Name      NULL
       
   418 			break;
       
   419 		case SQLITE_CREATE_VTABLE:
       
   420 		case SQLITE_DROP_VTABLE:
       
   421 			__SQLASSERT(EFalse, ESqlPanicInternalError);
       
   422 			res = SQLITE_DENY;	
       
   423 		//No policy check
       
   424 		case SQLITE_FUNCTION:
       
   425 			break;
       
   426 		default:
       
   427 			__SQLASSERT(EFalse, ESqlPanicInternalError);
       
   428 			break;
       
   429 		}
       
   430 	return res;
       
   431 	}
       
   432 
       
   433 /**
       
   434 This callback function is invoked by the SQLITE engine at SQL statement compile time 
       
   435 for each attempt to access a column of a table in the database.
       
   436 
       
   437 The callback returns SQLITE_OK if access is allowed, 
       
   438 SQLITE_DENY if the entire SQL statement should be aborted with an error and 
       
   439 SQLITE_IGNORE if the column should be treated as a NULL value.
       
   440 
       
   441 @param aDb "This" pointer (to the rellated CSqlSrvDatabase object).
       
   442 @param aDbOpType Database operation type, which needs to be authorized. It could be one of these:
       
   443 
       
   444 @code
       
   445 =================================================================
       
   446 aDbOpType						aDbObjName1		aDbObjName2
       
   447 =================================================================
       
   448 SQLITE_CREATE_INDEX             Index Name      Table Name      
       
   449 SQLITE_CREATE_TABLE             Table Name      NULL            
       
   450 SQLITE_CREATE_TEMP_INDEX        Index Name      Table Name      
       
   451 SQLITE_CREATE_TEMP_TABLE        Table Name      NULL            
       
   452 SQLITE_CREATE_TEMP_TRIGGER      Trigger Name    Table Name      
       
   453 SQLITE_CREATE_TEMP_VIEW         View Name       NULL            
       
   454 SQLITE_CREATE_TRIGGER           Trigger Name    Table Name      
       
   455 SQLITE_CREATE_VIEW              View Name       NULL            
       
   456 SQLITE_DELETE                   Table Name      NULL            
       
   457 SQLITE_DROP_INDEX               Index Name      Table Name      
       
   458 SQLITE_DROP_TABLE               Table Name      NULL            
       
   459 SQLITE_DROP_TEMP_INDEX          Index Name      Table Name      
       
   460 SQLITE_DROP_TEMP_TABLE          Table Name      NULL            
       
   461 SQLITE_DROP_TEMP_TRIGGER        Trigger Name    Table Name      
       
   462 SQLITE_DROP_TEMP_VIEW           View Name       NULL            
       
   463 SQLITE_DROP_TRIGGER             Trigger Name    Table Name      
       
   464 SQLITE_DROP_VIEW                View Name       NULL            
       
   465 SQLITE_INSERT                   Table Name      NULL            
       
   466 SQLITE_PRAGMA                   Pragma Name     1st arg or NULL 
       
   467 SQLITE_READ                     Table Name      Column Name     
       
   468 SQLITE_SELECT                   NULL            NULL            
       
   469 SQLITE_TRANSACTION              NULL            NULL            
       
   470 SQLITE_UPDATE                   Table Name      Column Name     
       
   471 SQLITE_ATTACH                   Filename        NULL            
       
   472 SQLITE_DETACH                   Database Name   NULL 
       
   473 SQLITE_ALTER_TABLE          	Database Name   Table Name
       
   474 SQLITE_REINDEX              	Index Name      NULL
       
   475 SQLITE_ANALYZE              	Table Name      NULL
       
   476 SQLITE_CREATE_VTABLE			Table Name	  	Module Name	
       
   477 SQLITE_DROP_VTABLE          	Table Name      Module Name
       
   478 SQLITE_FUNCTION				    Function Name   NULL
       
   479 =================================================================
       
   480 @endcode
       
   481 
       
   482 @param aDbObjName1 Database, Table, View, Trigger, Index, Pragma or File name. It depends on the 
       
   483 			values of aDbOpType argument. UTF8 encoded, zero-terminated.
       
   484 @param aDbObjName2 Table or Column name. It depends on the values of aDbOpType argument. UTF8 encoded, zero-terminated.
       
   485 @param aDbName Database name - "main", "temp", etc. UTF8 encoded, zero-terminated.
       
   486 @param aTrgOrViewName The name of the inner-most trigger or view that is responsible for the access
       
   487 			attempt or NULL if this access attempt is directly from input SQL code. UTF8 encoded, zero-terminated.
       
   488 
       
   489 @return SQLITE_OK		Access is allowed
       
   490 @return SQLITE_DENY 	The entire SQL statement should be aborted
       
   491 @return SQLITE_IGNORE	The column should be treated as it has NULL value
       
   492 
       
   493 @panic SqlDb 4 In _DEBUG mode. The authorizer was called with NULL aDb argument.
       
   494 
       
   495 @internalComponent
       
   496 */
       
   497 TInt CSqlSrvDatabase::AuthorizeCallback(void* aDb, TInt aDbOpType, 
       
   498 										const char* aDbObjName1, const char* aDbObjName2, 
       
   499 										const char* aDbName, const char* aTrgOrViewName)
       
   500 	{
       
   501 	UNUSED_ARG(aTrgOrViewName);
       
   502  	__SQLASSERT(aDb != NULL, ESqlPanicBadArgument);
       
   503 	
       
   504 #ifdef _NOTIFY
       
   505     enum TDbOpType {EOpCreateIndex = 1, EOpCreateTable, EOpCreateTempIndex, EOpCreateTempTable, 
       
   506         EOpCreateTempTrigger, EOpCreateTempView, EOpCreateTrigger, EOpCreateView, EOpDelete, EOpDropIndex, 
       
   507         EOpDropTable, EOpDropTempIndex, EOpDropTempTable, EOpDropTempTrigger, EOpDropTempView, EOpDropTrigger,
       
   508 		EOpDropView, EOpInsert, EOpPragma, EOpRead, EOpSelect, EOpTransaction, EOpUpdate, EOpAttach, EOpDettach,
       
   509 		EOpAlterTable, EOpReindex, EOpAnalyze, EOpCreateVTable, EOpDropVTable, EOpFunctionCall};
       
   510 	TDbOpType dbOpType = static_cast <TDbOpType> (aDbOpType);//can be seen now in the debugger
       
   511 	::PrintAuthorizerArguments(dbOpType, aDbObjName1, aDbObjName2, aDbName, aTrgOrViewName);
       
   512 #endif//_NOTIFY
       
   513 
       
   514 	CSqlSrvDatabase& db = *static_cast <CSqlSrvDatabase*> (aDb);
       
   515 
       
   516 	//1. If the authorizer is currently disabled - return SQLITE_OK.
       
   517 	//   (This happens when a database is attached/detached)
       
   518 	if(db.iAuthorizerDisabled)
       
   519 		{
       
   520 		return SQLITE_OK;	
       
   521 		}
       
   522 
       
   523 	TPtrC8 dbName(KNullDesC8);
       
   524 	const char* dbNamePtr = DbOp2DbName(aDbOpType, aDbObjName1, aDbName);//dbNamePtr is zero terminated
       
   525 	if(dbNamePtr)
       
   526 		{
       
   527 		dbName.Set(reinterpret_cast <const TUint8*> (dbNamePtr));
       
   528 		}
       
   529 	aDbName = NULL;//No more use of aDbName argument inside the function.
       
   530 	
       
   531 	//2. If the database name is KTempDb, then allow the access. It is a local database 
       
   532 	//   (for the client), deleted when closed.
       
   533 	if(dbName.Compare(KTempDb8) == 0) 	//dbName is guaranteed to be in lower case if it is "temp",
       
   534 		{								//so it is possible to use binary string comparison
       
   535 		return SQLITE_OK;	
       
   536 		}
       
   537 
       
   538 	//3. Find the security policies. For DefaultAccess initialized with NULL.
       
   539 	const CSqlSecurityPolicy* securityPolicy = NULL;
       
   540 	if(dbName.Compare(KMainDb8) == 0||dbName.Length() == 0)	//dbName is guaranteed to be in lower case if it is "main",
       
   541 		{								//so it is possible to use binary string comparison
       
   542 		//4. This is the main database.
       
   543 		securityPolicy = db.iSecurityPolicy;
       
   544 		}
       
   545 	else
       
   546 		{
       
   547 		//5. This is an attached database. Find the attached database security policies.
       
   548 	    //dbNamePtr is used here because it is zero terminated
       
   549 		TSqlAttachDbPair* attachDbPair = db.iAttachDbMap.Entry(reinterpret_cast <const TUint8*> (dbNamePtr));
       
   550 		if(attachDbPair)
       
   551 			{//secure database, find the security policies
       
   552 			const TUint8* securityMapKey = attachDbPair->iData;
       
   553 			RSqlSecurityMap& map = ::SqlServer().SecurityMap();
       
   554 			TSqlSecurityPair* pair = map.Entry(securityMapKey);
       
   555 			if(pair)
       
   556 				{
       
   557 				securityPolicy = pair->iData;
       
   558 				}
       
   559 			}
       
   560 		}
       
   561 		
       
   562 	//Here we have: 
       
   563 	// - valid database name (not NULL);
       
   564 	
       
   565 	//6. Default or Security Policy Checks
       
   566 	return !securityPolicy ? NonSecureChecks(aDbOpType,aDbObjName1,aDbObjName2): SecureChecks(securityPolicy,aDbOpType,aDbObjName1,aDbObjName2);
       
   567 	}