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
This commit is contained in:
parent
2e6d11bc07
commit
85e2096fb6
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
||||
C Add\stests\sto\sinsure\sVACUUM\sworks\sin\sthe\spresence\sof\sI/O\serrors.\s\sFix\ssome\nproblems\sthat\scame\sto\slight\sby\sthese\stests.\s(CVS\s935)
|
||||
D 2003-04-25T15:37:58
|
||||
C Report\sthe\scorrect\sauthorization\scontext\sin\sthe\sauthorization\scallback\nwhen\scoding\san\sINSTEAD\sOF\strigger\son\san\supdate\sor\sdelete.\s(CVS\s936)
|
||||
D 2003-04-25T17:52:11
|
||||
F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@ -20,13 +20,13 @@ F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
|
||||
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||
F src/attach.c 7ebc7487de43e357a64226f8abef81f2669f2183
|
||||
F src/auth.c a4afd27964fb9f661147115790c8ae2ee230ebcc
|
||||
F src/auth.c 3be3c7434592117f049703966b940e0b07088ae2
|
||||
F src/btree.c 077d75aee4ed63f3628698611ba43c87097d458d
|
||||
F src/btree.h 23c50e00709de16a5dce1fcea9c0429cc955ff0e
|
||||
F src/btree_rb.c 8e00e40be264716e1929987878672e55d9e0e76d
|
||||
F src/build.c d5a26baeffa5bc49b4b7009a7723c6ab7e1b02d9
|
||||
F src/copy.c 44b13fd4d2444fb53bff8a5ecee1c5f6f86a8263
|
||||
F src/delete.c 23d33fd8967c6cc492943bbecea93be6491edc6a
|
||||
F src/delete.c 0f7c26aaebc417ad66a2a1099e59cc4056512c31
|
||||
F src/encode.c faf03741efe921755ec371cf4a6984536de00042
|
||||
F src/expr.c 46e2bb93abd6c70e67c8cdc5d92fdcd0b95498f3
|
||||
F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
|
||||
@ -47,7 +47,7 @@ F src/select.c dfc13cb62ba658c4463179713c40ee25a062b2ba
|
||||
F src/shell.c e0b3da1f44a2cc72daf41a4559b1c5f0545944a5
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e
|
||||
F src/sqliteInt.h 5d15d1dea3f0c497a78c6a123eec5b4b92811c1c
|
||||
F src/sqliteInt.h 0c7474068c37a5aad715810c8190266edcbd4f4c
|
||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||
F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d
|
||||
F src/test1.c 4484806861a3099670188a09e12f858ec65aa56c
|
||||
@ -55,8 +55,8 @@ F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
|
||||
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
|
||||
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
||||
F src/tokenize.c 067d1a477a94af7712ca74e09aaa6bd0f7299527
|
||||
F src/trigger.c e763f4015c96e06b694184ead5754985c1dfdae0
|
||||
F src/update.c b7fa7c427b74aee6db56ecfa09e5e151e6f9fa6a
|
||||
F src/trigger.c 62d1e1b837a98f1fa7511c77977d51c8516ddb65
|
||||
F src/update.c f40376ed2e092a7040c6fc6fa0add59fad5c5e76
|
||||
F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c
|
||||
F src/vacuum.c 14ac3073203fa021e01ffe33db56968ad79a8344
|
||||
F src/vdbe.c 48098080d2b5d35d4cc28ac2a4855c7730f6ee7b
|
||||
@ -64,7 +64,7 @@ F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
|
||||
F src/where.c f632cd30f013163484a4d60c249d36fe31f5be12
|
||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||
F test/attach.test b311c83e370e6b22b79a8279317039440ce64862
|
||||
F test/auth.test d25a76f21494b61483787caa7b28c713bc7c7c7f
|
||||
F test/auth.test dee78be1f4f920bd6b15c4c947ce4d01bfe2826d
|
||||
F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
|
||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||
F test/btree.test 1e3463c7838e7e71bbf37c9c6e45beee9c8975ba
|
||||
@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
|
||||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P c3b1f84dfce13b2523c9923e4270577862ca0595
|
||||
R 40330553c4eb619fb11602a7f62ead1c
|
||||
P 8d3e879349fc9523c72cb46111e0058b57ce9341
|
||||
R fbd9cacc0c39e890456b02e579584ea3
|
||||
U drh
|
||||
Z 09a1f9c6aa9e8c12d787618e6052f340
|
||||
Z d170dde2366e1aeda159869f0f0e19bb
|
||||
|
@ -1 +1 @@
|
||||
8d3e879349fc9523c72cb46111e0058b57ce9341
|
||||
67746833fc8de3afff80db413bd63a362bb28218
|
30
src/auth.c
30
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 */
|
||||
|
11
src/delete.c
11
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;
|
||||
|
@ -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
|
||||
@ -834,6 +835,15 @@ struct Parse {
|
||||
TriggerStack *trigStack; /* Trigger actions being coded */
|
||||
};
|
||||
|
||||
/*
|
||||
** 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*);
|
||||
|
@ -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);
|
||||
|
44
src/update.c
44
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);
|
||||
|
@ -12,7 +12,7 @@
|
||||
# focus of this script is testing the ATTACH and DETACH commands
|
||||
# and related functionality.
|
||||
#
|
||||
# $Id: auth.test,v 1.8 2003/04/22 20:30:40 drh Exp $
|
||||
# $Id: auth.test,v 1.9 2003/04/25 17:52:11 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -1714,5 +1714,74 @@ do_test auth-3.2 {
|
||||
}
|
||||
} {12 112 2 2 {} {} 8 108 8 8 {} {}}
|
||||
|
||||
# Make sure the names of views and triggers are passed on on arg4.
|
||||
#
|
||||
do_test auth-4.1 {
|
||||
proc auth {code arg1 arg2 arg3 arg4} {
|
||||
lappend ::authargs $code $arg1 $arg2 $arg3 $arg4
|
||||
return SQLITE_OK
|
||||
}
|
||||
set authargs {}
|
||||
execsql {
|
||||
UPDATE t2 SET a=a+1;
|
||||
}
|
||||
set authargs
|
||||
} [list \
|
||||
SQLITE_READ t2 a main {} \
|
||||
SQLITE_UPDATE t2 a main {} \
|
||||
SQLITE_INSERT tx {} main r1 \
|
||||
SQLITE_READ t2 a main r1 \
|
||||
SQLITE_READ t2 a main r1 \
|
||||
SQLITE_READ t2 b main r1 \
|
||||
SQLITE_READ t2 b main r1 \
|
||||
SQLITE_READ t2 c main r1 \
|
||||
SQLITE_READ t2 c main r1]
|
||||
do_test auth-4.2 {
|
||||
execsql {
|
||||
CREATE VIEW v1 AS SELECT a+b AS x FROM t2;
|
||||
CREATE TABLE v1chng(x1,x2);
|
||||
CREATE TRIGGER r2 INSTEAD OF UPDATE ON v1 BEGIN
|
||||
INSERT INTO v1chng VALUES(OLD.x,NEW.x);
|
||||
END;
|
||||
SELECT * FROM v1;
|
||||
}
|
||||
} {115 117}
|
||||
do_test auth-4.3 {
|
||||
set authargs {}
|
||||
execsql {
|
||||
UPDATE v1 SET x=1 WHERE x=117
|
||||
}
|
||||
set authargs
|
||||
} [list \
|
||||
SQLITE_UPDATE v1 x main {} \
|
||||
SQLITE_READ v1 x main {} \
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ t2 a main v1 \
|
||||
SQLITE_READ t2 b main v1 \
|
||||
SQLITE_INSERT v1chng {} main r2 \
|
||||
SQLITE_READ v1 x main r2 \
|
||||
SQLITE_READ v1 x main r2]
|
||||
do_test auth-4.4 {
|
||||
execsql {
|
||||
CREATE TRIGGER r3 INSTEAD OF DELETE ON v1 BEGIN
|
||||
INSERT INTO v1chng VALUES(OLD.x,NULL);
|
||||
END;
|
||||
SELECT * FROM v1;
|
||||
}
|
||||
} {115 117}
|
||||
do_test auth-4.5 {
|
||||
set authargs {}
|
||||
execsql {
|
||||
DELETE FROM v1 WHERE x=117
|
||||
}
|
||||
set authargs
|
||||
} [list \
|
||||
SQLITE_DELETE v1 {} main {} \
|
||||
SQLITE_READ v1 x main {} \
|
||||
SQLITE_SELECT {} {} {} v1 \
|
||||
SQLITE_READ t2 a main v1 \
|
||||
SQLITE_READ t2 b main v1 \
|
||||
SQLITE_INSERT v1chng {} main r3 \
|
||||
SQLITE_READ v1 x main r3]
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user