diff options
author | drh <drh@noemail.net> | 2003-04-25 17:52:11 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2003-04-25 17:52:11 +0000 |
commit | 85e2096fb60de90ff32830cf7b9a4689370d723e (patch) | |
tree | b92674526394998c76d05def3f9188c2c5aab8ef /src | |
parent | 2e6d11bc07ca73239a49d25fd8313713f6eeb75e (diff) | |
download | sqlite-85e2096fb60de90ff32830cf7b9a4689370d723e.tar.gz sqlite-85e2096fb60de90ff32830cf7b9a4689370d723e.zip |
Report the correct authorization context in the authorization callback
when coding an INSTEAD OF trigger on an update or delete. (CVS 936)
FossilOrigin-Name: 67746833fc8de3afff80db413bd63a362bb28218
Diffstat (limited to 'src')
-rw-r--r-- | src/auth.c | 30 | ||||
-rw-r--r-- | src/delete.c | 11 | ||||
-rw-r--r-- | src/sqliteInt.h | 16 | ||||
-rw-r--r-- | src/trigger.c | 7 | ||||
-rw-r--r-- | src/update.c | 44 |
5 files changed, 87 insertions, 21 deletions
diff --git a/src/auth.c b/src/auth.c index 4703ba013..2a5a8f564 100644 --- a/src/auth.c +++ b/src/auth.c @@ -14,7 +14,7 @@ ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.7 2003/04/24 01:45:04 drh Exp $ +** $Id: auth.c,v 1.8 2003/04/25 17:52:11 drh Exp $ */ #include "sqliteInt.h" @@ -173,4 +173,32 @@ int sqliteAuthCheck( return rc; } +/* +** Push an authorization context. After this routine is called, the +** zArg3 argument to authorization callbacks will be zContext until +** popped. Or if pParse==0, this routine is a no-op. +*/ +void sqliteAuthContextPush( + Parse *pParse, + AuthContext *pContext, + const char *zContext +){ + pContext->pParse = pParse; + if( pParse ){ + pContext->zAuthContext = pParse->zAuthContext; + pParse->zAuthContext = zContext; + } +} + +/* +** Pop an authorization context that was previously pushed +** by sqliteAuthContextPush +*/ +void sqliteAuthContextPop(AuthContext *pContext){ + if( pContext->pParse ){ + pContext->pParse->zAuthContext = pContext->zAuthContext; + pContext->pParse = 0; + } +} + #endif /* SQLITE_OMIT_AUTHORIZATION */ diff --git a/src/delete.c b/src/delete.c index 7d0003578..14c7a20e1 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.54 2003/04/24 01:45:04 drh Exp $ +** $Id: delete.c,v 1.55 2003/04/25 17:52:11 drh Exp $ */ #include "sqliteInt.h" @@ -68,12 +68,14 @@ void sqliteDeleteFrom( int base; /* Index of the first available table cursor */ sqlite *db; /* Main database structure */ int isView; /* True if attempting to delete from a view */ + AuthContext sContext; /* Authorization context */ int row_triggers_exist = 0; /* True if any triggers exist */ int before_triggers; /* True if there are BEFORE triggers */ int after_triggers; /* True if there are AFTER triggers */ int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ + sContext.pParse = 0; if( pParse->nErr || sqlite_malloc_failed ){ pTabList = 0; goto delete_from_cleanup; @@ -127,6 +129,12 @@ void sqliteDeleteFrom( } } + /* Start the view context + */ + if( isView ){ + sqliteAuthContextPush(pParse, &sContext, pTab->zName); + } + /* Begin generating code. */ v = sqliteGetVdbe(pParse); @@ -303,6 +311,7 @@ void sqliteDeleteFrom( } delete_from_cleanup: + sqliteAuthContextPop(&sContext); sqliteSrcListDelete(pTabList); sqliteExprDelete(pWhere); return; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7027b30a9..c68ccd94c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.180 2003/04/24 01:45:04 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.181 2003/04/25 17:52:11 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -219,6 +219,7 @@ typedef struct TriggerStep TriggerStep; typedef struct TriggerStack TriggerStack; typedef struct FKey FKey; typedef struct Db Db; +typedef struct AuthContext AuthContext; /* ** Each database file to be accessed by the system is an instance @@ -835,6 +836,15 @@ struct Parse { }; /* +** An instance of the following structure can be declared on a stack and used +** to save the Parse.zAuthContext value so that it can be restored later. +*/ +struct AuthContext { + const char *zAuthContext; /* Put saved Parse.zAuthContext here */ + Parse *pParse; /* The Parse structure */ +}; + +/* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * @@ -1111,9 +1121,13 @@ void sqliteDeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION void sqliteAuthRead(Parse*,Expr*,SrcList*,int); int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*); + void sqliteAuthContextPush(Parse*, AuthContext*, const char*); + void sqliteAuthContextPop(AuthContext*); #else # define sqliteAuthRead(a,b,c,d) # define sqliteAuthCheck(a,b,c,d) SQLITE_OK +# define sqliteAuthContextPush(a,b,c) +# define sqliteAuthContextPop(a) #endif void sqliteAttach(Parse*, Token*, Token*); void sqliteDetach(Parse*, Token*); diff --git a/src/trigger.c b/src/trigger.c index 0abe7ee0d..b07b8c5a8 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -661,7 +661,7 @@ int sqliteCodeRowTrigger( int endTrigger; SrcList dummyTablist; Expr * whenExpr; - const char *zSavedAuthContext; + AuthContext sContext; dummyTablist.nSrc = 0; @@ -673,8 +673,7 @@ int sqliteCodeRowTrigger( pTriggerStack->pNext = pParse->trigStack; pTriggerStack->ignoreJump = ignoreJump; pParse->trigStack = pTriggerStack; - zSavedAuthContext = pParse->zAuthContext; - pParse->zAuthContext = pTrigger->name; + sqliteAuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe); @@ -692,7 +691,7 @@ int sqliteCodeRowTrigger( /* Pop the entry off the trigger stack */ pParse->trigStack = pParse->trigStack->pNext; - pParse->zAuthContext = zSavedAuthContext; + sqliteAuthContextPop(&sContext); sqliteFree(pTriggerStack); sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger); diff --git a/src/update.c b/src/update.c index c1961426c..cd98c82c0 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.63 2003/04/24 01:45:05 drh Exp $ +** $Id: update.c,v 1.64 2003/04/25 17:52:11 drh Exp $ */ #include "sqliteInt.h" @@ -49,6 +49,7 @@ void sqliteUpdate( Expr *pRecnoExpr; /* Expression defining the new record number */ int openAll; /* True if all indices need to be opened */ int isView; /* Trying to update a view */ + AuthContext sContext; /* The authorization context */ int before_triggers; /* True if there are any BEFORE triggers */ int after_triggers; /* True if there are any AFTER triggers */ @@ -57,6 +58,7 @@ void sqliteUpdate( int newIdx = -1; /* index of trigger "new" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */ + sContext.pParse = 0; if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup; db = pParse->db; assert( pTabList->nSrc==1 ); @@ -74,8 +76,10 @@ void sqliteUpdate( if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){ goto update_cleanup; } - if( isView && sqliteViewGetColumnNames(pParse, pTab) ){ - goto update_cleanup; + if( isView ){ + if( sqliteViewGetColumnNames(pParse, pTab) ){ + goto update_cleanup; + } } aXRef = sqliteMalloc( sizeof(int) * pTab->nCol ); if( aXRef==0 ) goto update_cleanup; @@ -99,20 +103,12 @@ void sqliteUpdate( pParse->nTab++; } - /* Resolve the column names in all the expressions in both the - ** WHERE clause and in the new values. Also find the column index + /* Resolve the column names in all the expressions of the + ** of the UPDATE statement. Also find the column index ** for each column to be updated in the pChanges array. For each ** column to be updated, make sure we have authorization to change ** that column. */ - if( pWhere ){ - if( sqliteExprResolveIds(pParse, base, pTabList, 0, pWhere) ){ - goto update_cleanup; - } - if( sqliteExprCheck(pParse, pWhere, 0, 0) ){ - goto update_cleanup; - } - } chngRecno = 0; for(i=0; i<pChanges->nExpr; i++){ if( sqliteExprResolveIds(pParse, base, pTabList, 0, pChanges->a[i].pExpr) ){ @@ -185,6 +181,24 @@ void sqliteUpdate( } } + /* Resolve the column names in all the expressions in the + ** WHERE clause. + */ + if( pWhere ){ + if( sqliteExprResolveIds(pParse, base, pTabList, 0, pWhere) ){ + goto update_cleanup; + } + if( sqliteExprCheck(pParse, pWhere, 0, 0) ){ + goto update_cleanup; + } + } + + /* Start the view context + */ + if( isView ){ + sqliteAuthContextPush(pParse, &sContext, pTab->zName); + } + /* Begin generating code. */ v = sqliteGetVdbe(pParse); @@ -195,7 +209,8 @@ void sqliteUpdate( ** a temporary table. */ if( isView ){ - Select *pView = sqliteSelectDup(pTab->pSelect); + Select *pView; + pView = sqliteSelectDup(pTab->pSelect); sqliteSelect(pParse, pView, SRT_TempTable, base, 0, 0, 0); sqliteSelectDelete(pView); } @@ -422,6 +437,7 @@ void sqliteUpdate( } update_cleanup: + sqliteAuthContextPop(&sContext); sqliteFree(apIdx); sqliteFree(aXRef); sqliteSrcListDelete(pTabList); |