aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2003-04-25 17:52:11 +0000
committerdrh <drh@noemail.net>2003-04-25 17:52:11 +0000
commit85e2096fb60de90ff32830cf7b9a4689370d723e (patch)
treeb92674526394998c76d05def3f9188c2c5aab8ef /src
parent2e6d11bc07ca73239a49d25fd8313713f6eeb75e (diff)
downloadsqlite-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.c30
-rw-r--r--src/delete.c11
-rw-r--r--src/sqliteInt.h16
-rw-r--r--src/trigger.c7
-rw-r--r--src/update.c44
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);