mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Update the authorizer API so that it reports the database that table and
indices belong to and so that it reports when actions are taken in response to a trigger. (CVS 928) FossilOrigin-Name: c675a5504138f34cae6def782b5d3add2c67d2bc
This commit is contained in:
44
manifest
44
manifest
@ -1,5 +1,5 @@
|
|||||||
C Check\sfor\sreadline\slibs\snow\sadds\sappropriate\scurses\sor\stermcap\slib\swhen\sneeded\s(CVS\s927)
|
C Update\sthe\sauthorizer\sAPI\sso\sthat\sit\sreports\sthe\sdatabase\sthat\stable\sand\nindices\sbelong\sto\sand\sso\sthat\sit\sreports\swhen\sactions\sare\staken\sin\sresponse\nto\sa\strigger.\s(CVS\s928)
|
||||||
D 2003-04-22T08:04:49
|
D 2003-04-22T20:30:38
|
||||||
F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f
|
F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -20,19 +20,19 @@ F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
|
|||||||
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||||
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||||
F src/attach.c 7ebc7487de43e357a64226f8abef81f2669f2183
|
F src/attach.c 7ebc7487de43e357a64226f8abef81f2669f2183
|
||||||
F src/auth.c 2dd558dba4d8ffbed25fe1644e9af242f389f3e9
|
F src/auth.c 7b0a72a649989461d36eced6ff1214f32af436c5
|
||||||
F src/btree.c b9487cceb9ea78af9cbae9def34114902f511736
|
F src/btree.c b9487cceb9ea78af9cbae9def34114902f511736
|
||||||
F src/btree.h 529c98cb0715c62214544fbbe50b946f99a85540
|
F src/btree.h 529c98cb0715c62214544fbbe50b946f99a85540
|
||||||
F src/btree_rb.c 97375d44bc2cf93b6312acd0f3276177c20e77bb
|
F src/btree_rb.c 97375d44bc2cf93b6312acd0f3276177c20e77bb
|
||||||
F src/build.c 90fc1b15d5e69316ffb979a11052ba6743e9b556
|
F src/build.c d5a26baeffa5bc49b4b7009a7723c6ab7e1b02d9
|
||||||
F src/copy.c 8699e571994934c78f70761a1458d7b9e9e75073
|
F src/copy.c 6bafc19598daef79d80d16214260611d758a53a1
|
||||||
F src/delete.c af65b26d9d13abbf63fdc4e97b88d26c700b04bb
|
F src/delete.c c5c26039cfdf1eadabff698eb329e3880189795e
|
||||||
F src/encode.c faf03741efe921755ec371cf4a6984536de00042
|
F src/encode.c faf03741efe921755ec371cf4a6984536de00042
|
||||||
F src/expr.c 3c0ff6b7b34d483ea03fb86c66f28b929542c782
|
F src/expr.c 46e2bb93abd6c70e67c8cdc5d92fdcd0b95498f3
|
||||||
F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
|
F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
|
||||||
F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
|
F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
|
||||||
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
||||||
F src/insert.c ae9ffb52b0c4218e3f00f611acfc600fd082dac4
|
F src/insert.c 350167db53b779a8d402d00ec5153410a8003931
|
||||||
F src/main.c d6a7f78ec5269c7ced3380908a7ff04508aa2f8e
|
F src/main.c d6a7f78ec5269c7ced3380908a7ff04508aa2f8e
|
||||||
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
||||||
F src/os.c 7274951ed6894f383cb889342267ded07caf339b
|
F src/os.c 7274951ed6894f383cb889342267ded07caf339b
|
||||||
@ -40,23 +40,23 @@ F src/os.h aa52f0c9da321ff6134d19f2ca959e18e33615d0
|
|||||||
F src/pager.c df4c81350cbd80c1ab48341ae0768ba78d99ad49
|
F src/pager.c df4c81350cbd80c1ab48341ae0768ba78d99ad49
|
||||||
F src/pager.h e3702f7d384921f6cd5ce0b3ed589185433e9f6c
|
F src/pager.h e3702f7d384921f6cd5ce0b3ed589185433e9f6c
|
||||||
F src/parse.y 15ae47e7dd84304c1c6ae9205558405127977541
|
F src/parse.y 15ae47e7dd84304c1c6ae9205558405127977541
|
||||||
F src/pragma.c aef327bd597e15f0d31f45b042bd2797cca65039
|
F src/pragma.c 3b1e8da84304d5efa1db5802c67261335b663327
|
||||||
F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
|
F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
|
||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||||
F src/select.c 07140aaf5f2e209dd7bf8a681401a412ce16dc04
|
F src/select.c 92a66f0122f321688569e108feceaf74f5f4e63a
|
||||||
F src/shell.c a0b7043713713ff45f666ce6b3c03a64109a8bb5
|
F src/shell.c a0b7043713713ff45f666ce6b3c03a64109a8bb5
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in f49c2cdec7d24cb03e496a1ca519e16306495ee1
|
F src/sqlite.h.in 058574a5c0cc4cdd4826b2452f8088c9fb04ed85
|
||||||
F src/sqliteInt.h 331d92aa826c5230247d97818b291f38aba21a11
|
F src/sqliteInt.h b9bbf9d8ec7d5b3fd5a0a4173a3a41f54f1dff6e
|
||||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||||
F src/tclsqlite.c 7a072c3c8ba9796edc25e5ffa62b68558134e192
|
F src/tclsqlite.c 1ca3b70aaa8564f89900909c28b991b95bf3fc70
|
||||||
F src/test1.c 7ad4e6308dde0bf5a0f0775ce20cb2ec37a328f8
|
F src/test1.c 4484806861a3099670188a09e12f858ec65aa56c
|
||||||
F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
|
F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
|
||||||
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
|
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
|
||||||
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
||||||
F src/tokenize.c 067d1a477a94af7712ca74e09aaa6bd0f7299527
|
F src/tokenize.c 067d1a477a94af7712ca74e09aaa6bd0f7299527
|
||||||
F src/trigger.c c461789fb90df04b4c43b0d07a7aede8f453d9bc
|
F src/trigger.c 21ad1677bb0f0625348a01e92d1e0c6d794185a1
|
||||||
F src/update.c 803c13ad967850fb18443394e0a5c2b0f0d7ce6f
|
F src/update.c 3301448786205a7ec2d035c7cb7bd8ae5128c2b0
|
||||||
F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c
|
F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c
|
||||||
F src/vacuum.c e24781e38db36d1c9f578b6b3613bf0989ebd63c
|
F src/vacuum.c e24781e38db36d1c9f578b6b3613bf0989ebd63c
|
||||||
F src/vdbe.c d453e8c95c9fac5a5e067c5c58243b3ae75699fc
|
F src/vdbe.c d453e8c95c9fac5a5e067c5c58243b3ae75699fc
|
||||||
@ -64,7 +64,7 @@ F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
|
|||||||
F src/where.c c0709e5cf402f30026b597dce9dc3e74f1d07f8e
|
F src/where.c c0709e5cf402f30026b597dce9dc3e74f1d07f8e
|
||||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||||
F test/attach.test b311c83e370e6b22b79a8279317039440ce64862
|
F test/attach.test b311c83e370e6b22b79a8279317039440ce64862
|
||||||
F test/auth.test 8128cd750830cba01b7fd0fba8ddfa1722ea6291
|
F test/auth.test d25a76f21494b61483787caa7b28c713bc7c7c7f
|
||||||
F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
|
F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
|
||||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||||
F test/btree.test 1e3463c7838e7e71bbf37c9c6e45beee9c8975ba
|
F test/btree.test 1e3463c7838e7e71bbf37c9c6e45beee9c8975ba
|
||||||
@ -116,7 +116,7 @@ F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba
|
|||||||
F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
|
F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
|
||||||
F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
|
F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
|
||||||
F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
|
F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
|
||||||
F test/tclsqlite.test 62773bcb94f7d7b69f1ab05c0ae07a22c737440f
|
F test/tclsqlite.test 42b8f01461a73e9921a3dfaa6d34e28e54441dcc
|
||||||
F test/temptable.test 6feff1960c707e924d5462356c5303943dac4a8e
|
F test/temptable.test 6feff1960c707e924d5462356c5303943dac4a8e
|
||||||
F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488
|
F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488
|
||||||
F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
|
F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
|
||||||
@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
|
|||||||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P 58ddd587b0f5d565ae3b0ba3a1fa5c20d459f3fc
|
P 393dd91c252531bb5abfe424b86a5f7eb20edcfc
|
||||||
R 56bc5369df13f5ed3e79edd9e52598e8
|
R 6eac04a1271ebdc92908dc18c218ec20
|
||||||
U paul
|
U drh
|
||||||
Z 46984dea9f9baae2ea78dc3185931bfa
|
Z 926b6500299b68262d64ec3146410e0c
|
||||||
|
@ -1 +1 @@
|
|||||||
393dd91c252531bb5abfe424b86a5f7eb20edcfc
|
c675a5504138f34cae6def782b5d3add2c67d2bc
|
29
src/auth.c
29
src/auth.c
@ -14,7 +14,7 @@
|
|||||||
** systems that do not need this facility may omit it by recompiling
|
** systems that do not need this facility may omit it by recompiling
|
||||||
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
|
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
|
||||||
**
|
**
|
||||||
** $Id: auth.c,v 1.5 2003/04/16 20:24:52 drh Exp $
|
** $Id: auth.c,v 1.6 2003/04/22 20:30:38 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -52,7 +52,7 @@
|
|||||||
*/
|
*/
|
||||||
int sqlite_set_authorizer(
|
int sqlite_set_authorizer(
|
||||||
sqlite *db,
|
sqlite *db,
|
||||||
int (*xAuth)(void*,int,const char*,const char*),
|
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
|
||||||
void *pArg
|
void *pArg
|
||||||
){
|
){
|
||||||
db->xAuth = xAuth;
|
db->xAuth = xAuth;
|
||||||
@ -94,7 +94,12 @@ void sqliteAuthRead(
|
|||||||
Table *pTab; /* The table being read */
|
Table *pTab; /* The table being read */
|
||||||
const char *zCol; /* Name of the column of the table */
|
const char *zCol; /* Name of the column of the table */
|
||||||
int iSrc; /* Index in pTabList->a[] of table being read */
|
int iSrc; /* Index in pTabList->a[] of table being read */
|
||||||
|
const char *zDBase; /* Name of database being accessed */
|
||||||
|
const char *zTrig; /* Name of the trigger doing the accessing */
|
||||||
|
TriggerStack *pStack; /* The stack of current triggers */
|
||||||
|
|
||||||
|
pStack = pParse->trigStack;
|
||||||
|
zTrig = pStack ? pStack->pTrigger->name : 0;
|
||||||
if( db->xAuth==0 ) return;
|
if( db->xAuth==0 ) return;
|
||||||
assert( pExpr->op==TK_COLUMN );
|
assert( pExpr->op==TK_COLUMN );
|
||||||
iSrc = pExpr->iTable - base;
|
iSrc = pExpr->iTable - base;
|
||||||
@ -104,7 +109,6 @@ void sqliteAuthRead(
|
|||||||
/* This must be an attempt to read the NEW or OLD pseudo-tables
|
/* This must be an attempt to read the NEW or OLD pseudo-tables
|
||||||
** of a trigger.
|
** of a trigger.
|
||||||
*/
|
*/
|
||||||
TriggerStack *pStack = pParse->trigStack;
|
|
||||||
assert( pStack!=0 );
|
assert( pStack!=0 );
|
||||||
assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
|
assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
|
||||||
pTab = pStack->pTab;
|
pTab = pStack->pTab;
|
||||||
@ -119,12 +123,19 @@ void sqliteAuthRead(
|
|||||||
}else{
|
}else{
|
||||||
zCol = "ROWID";
|
zCol = "ROWID";
|
||||||
}
|
}
|
||||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol);
|
assert( pExpr->iDb>=0 && pExpr->iDb<db->nDb );
|
||||||
|
zDBase = db->aDb[pExpr->iDb].zName;
|
||||||
|
rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, zTrig);
|
||||||
if( rc==SQLITE_IGNORE ){
|
if( rc==SQLITE_IGNORE ){
|
||||||
pExpr->op = TK_NULL;
|
pExpr->op = TK_NULL;
|
||||||
}else if( rc==SQLITE_DENY ){
|
}else if( rc==SQLITE_DENY ){
|
||||||
sqliteSetString(&pParse->zErrMsg,"access to ",
|
if( db->nDb>2 || pExpr->iDb!=0 ){
|
||||||
|
sqliteSetString(&pParse->zErrMsg,"access to ", zDBase, ".",
|
||||||
pTab->zName, ".", zCol, " is prohibited", 0);
|
pTab->zName, ".", zCol, " is prohibited", 0);
|
||||||
|
}else{
|
||||||
|
sqliteSetString(&pParse->zErrMsg,"access to ", pTab->zName, ".",
|
||||||
|
zCol, " is prohibited", 0);
|
||||||
|
}
|
||||||
pParse->nErr++;
|
pParse->nErr++;
|
||||||
pParse->rc = SQLITE_AUTH;
|
pParse->rc = SQLITE_AUTH;
|
||||||
}else if( rc!=SQLITE_OK ){
|
}else if( rc!=SQLITE_OK ){
|
||||||
@ -142,14 +153,18 @@ int sqliteAuthCheck(
|
|||||||
Parse *pParse,
|
Parse *pParse,
|
||||||
int code,
|
int code,
|
||||||
const char *zArg1,
|
const char *zArg1,
|
||||||
const char *zArg2
|
const char *zArg2,
|
||||||
|
const char *zArg3
|
||||||
){
|
){
|
||||||
sqlite *db = pParse->db;
|
sqlite *db = pParse->db;
|
||||||
int rc;
|
int rc;
|
||||||
|
const char *zTrigName;
|
||||||
|
|
||||||
if( db->xAuth==0 ){
|
if( db->xAuth==0 ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2);
|
zTrigName = pParse->trigStack ? pParse->trigStack->pTrigger->name : 0;
|
||||||
|
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, zTrigName);
|
||||||
if( rc==SQLITE_DENY ){
|
if( rc==SQLITE_DENY ){
|
||||||
sqliteSetString(&pParse->zErrMsg, "not authorized", 0);
|
sqliteSetString(&pParse->zErrMsg, "not authorized", 0);
|
||||||
pParse->rc = SQLITE_AUTH;
|
pParse->rc = SQLITE_AUTH;
|
||||||
|
44
src/build.c
44
src/build.c
@ -23,7 +23,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.148 2003/04/21 18:48:46 drh Exp $
|
** $Id: build.c,v 1.149 2003/04/22 20:30:38 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -453,12 +453,13 @@ void sqliteStartTable(
|
|||||||
if( pParse->iDb==1 ) isTemp = 1;
|
if( pParse->iDb==1 ) isTemp = 1;
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
assert( (isTemp & 1)==isTemp );
|
assert( (isTemp & 1)==isTemp );
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0) ){
|
{
|
||||||
|
int code;
|
||||||
|
char *zDb = isTemp ? "temp" : "main";
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
|
||||||
sqliteFree(zName);
|
sqliteFree(zName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
int code;
|
|
||||||
if( isView ){
|
if( isView ){
|
||||||
if( isTemp ){
|
if( isTemp ){
|
||||||
code = SQLITE_CREATE_TEMP_VIEW;
|
code = SQLITE_CREATE_TEMP_VIEW;
|
||||||
@ -472,7 +473,7 @@ void sqliteStartTable(
|
|||||||
code = SQLITE_CREATE_TABLE;
|
code = SQLITE_CREATE_TABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, code, zName, 0) ){
|
if( sqliteAuthCheck(pParse, code, zName, 0, zDb) ){
|
||||||
sqliteFree(zName);
|
sqliteFree(zName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1218,12 +1219,15 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
|
|||||||
pTable = sqliteTableFromToken(pParse, pName);
|
pTable = sqliteTableFromToken(pParse, pName);
|
||||||
if( pTable==0 ) return;
|
if( pTable==0 ) return;
|
||||||
iDb = pTable->iDb;
|
iDb = pTable->iDb;
|
||||||
|
assert( iDb>=0 && iDb<db->nDb );
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->iDb),0)){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
|
const char *zTab = SCHEMA_TABLE(pTable->iDb);
|
||||||
|
const char *zDb = db->aDb[pTable->iDb].zName;
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if( isView ){
|
if( isView ){
|
||||||
if( iDb==1 ){
|
if( iDb==1 ){
|
||||||
code = SQLITE_DROP_TEMP_VIEW;
|
code = SQLITE_DROP_TEMP_VIEW;
|
||||||
@ -1237,10 +1241,10 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
|
|||||||
code = SQLITE_DROP_TABLE;
|
code = SQLITE_DROP_TABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, code, pTable->zName, 0) ){
|
if( sqliteAuthCheck(pParse, code, pTable->zName, 0, zDb) ){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTable->zName, 0) ){
|
if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTable->zName, 0, zDb) ){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1600,16 +1604,20 @@ void sqliteCreateIndex(
|
|||||||
/* Check for authorization to create an index.
|
/* Check for authorization to create an index.
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
|
{
|
||||||
|
const char *zDb = db->aDb[pTab->iDb].zName;
|
||||||
|
|
||||||
assert( isTemp==0 || isTemp==1 );
|
assert( isTemp==0 || isTemp==1 );
|
||||||
assert( pTab->iDb==pParse->iDb || isTemp==1 );
|
assert( pTab->iDb==pParse->iDb || isTemp==1 );
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0) ){
|
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
i = SQLITE_CREATE_INDEX;
|
i = SQLITE_CREATE_INDEX;
|
||||||
if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
|
if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
|
||||||
if( sqliteAuthCheck(pParse, i, zName, pTab->zName) ){
|
if( sqliteAuthCheck(pParse, i, zName, pTab->zName, zDb) ){
|
||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If pList==0, it means this routine was called to make a primary
|
/* If pList==0, it means this routine was called to make a primary
|
||||||
@ -1813,11 +1821,13 @@ void sqliteDropIndex(Parse *pParse, SrcList *pName){
|
|||||||
{
|
{
|
||||||
int code = SQLITE_DROP_INDEX;
|
int code = SQLITE_DROP_INDEX;
|
||||||
Table *pTab = pIndex->pTable;
|
Table *pTab = pIndex->pTable;
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pIndex->iDb), 0) ){
|
const char *zDb = db->aDb[pIndex->iDb].zName;
|
||||||
|
const char *zTab = SCHEMA_TABLE(pIndex->iDb);
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
|
||||||
goto exit_drop_index;
|
goto exit_drop_index;
|
||||||
}
|
}
|
||||||
if( pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
|
if( pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
|
||||||
if( sqliteAuthCheck(pParse, code, pIndex->zName, pTab->zName) ){
|
if( sqliteAuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
|
||||||
goto exit_drop_index;
|
goto exit_drop_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2035,7 +2045,7 @@ void sqliteBeginTransaction(Parse *pParse, int onError){
|
|||||||
|
|
||||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||||
if( pParse->nErr || sqlite_malloc_failed ) return;
|
if( pParse->nErr || sqlite_malloc_failed ) return;
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0) ) return;
|
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
|
||||||
if( db->flags & SQLITE_InTrans ){
|
if( db->flags & SQLITE_InTrans ){
|
||||||
sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");
|
sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");
|
||||||
return;
|
return;
|
||||||
@ -2053,7 +2063,7 @@ void sqliteCommitTransaction(Parse *pParse){
|
|||||||
|
|
||||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||||
if( pParse->nErr || sqlite_malloc_failed ) return;
|
if( pParse->nErr || sqlite_malloc_failed ) return;
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0) ) return;
|
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
|
sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
|
||||||
return;
|
return;
|
||||||
@ -2072,7 +2082,7 @@ void sqliteRollbackTransaction(Parse *pParse){
|
|||||||
|
|
||||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||||
if( pParse->nErr || sqlite_malloc_failed ) return;
|
if( pParse->nErr || sqlite_malloc_failed ) return;
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0) ) return;
|
if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
|
sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
|
||||||
return;
|
return;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the COPY command.
|
** This file contains code used to implement the COPY command.
|
||||||
**
|
**
|
||||||
** $Id: copy.c,v 1.2 2003/04/15 19:22:23 drh Exp $
|
** $Id: copy.c,v 1.3 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -39,6 +39,7 @@ void sqliteCopy(
|
|||||||
int addr, end;
|
int addr, end;
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
char *zFile = 0;
|
char *zFile = 0;
|
||||||
|
const char *zDb;
|
||||||
sqlite *db = pParse->db;
|
sqlite *db = pParse->db;
|
||||||
|
|
||||||
|
|
||||||
@ -48,8 +49,10 @@ void sqliteCopy(
|
|||||||
if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto copy_cleanup;
|
if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto copy_cleanup;
|
||||||
zFile = sqliteStrNDup(pFilename->z, pFilename->n);
|
zFile = sqliteStrNDup(pFilename->z, pFilename->n);
|
||||||
sqliteDequote(zFile);
|
sqliteDequote(zFile);
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, zFile)
|
assert( pTab->iDb>=0 && pTab->iDb<db->nDb );
|
||||||
|| sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile) ){
|
zDb = db->aDb[pTab->iDb].zName;
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb)
|
||||||
|
|| sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){
|
||||||
goto copy_cleanup;
|
goto copy_cleanup;
|
||||||
}
|
}
|
||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle DELETE FROM statements.
|
** to handle DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.52 2003/04/17 22:57:53 drh Exp $
|
** $Id: delete.c,v 1.53 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ void sqliteDeleteFrom(
|
|||||||
){
|
){
|
||||||
Vdbe *v; /* The virtual database engine */
|
Vdbe *v; /* The virtual database engine */
|
||||||
Table *pTab; /* The table from which records will be deleted */
|
Table *pTab; /* The table from which records will be deleted */
|
||||||
|
const char *zDb; /* Name of database holding pTab */
|
||||||
int end, addr; /* A couple addresses of generated code */
|
int end, addr; /* A couple addresses of generated code */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
WhereInfo *pWInfo; /* Information about the WHERE clause */
|
WhereInfo *pWInfo; /* Information about the WHERE clause */
|
||||||
@ -97,7 +98,9 @@ void sqliteDeleteFrom(
|
|||||||
}
|
}
|
||||||
if( sqliteIsReadOnly(pParse, pTab) ) goto delete_from_cleanup;
|
if( sqliteIsReadOnly(pParse, pTab) ) goto delete_from_cleanup;
|
||||||
assert( pTab->pSelect==0 ); /* This table is not a view */
|
assert( pTab->pSelect==0 ); /* This table is not a view */
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0) ){
|
assert( pTab->iDb<db->nDb );
|
||||||
|
zDb = db->aDb[pTab->iDb].zName;
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
|
||||||
goto delete_from_cleanup;
|
goto delete_from_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
src/expr.c
19
src/expr.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.93 2003/04/19 17:27:25 drh Exp $
|
** $Id: expr.c,v 1.94 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -432,6 +432,8 @@ int sqliteExprResolveIds(
|
|||||||
int cnt = 0; /* Number of matches */
|
int cnt = 0; /* Number of matches */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
char *z;
|
char *z;
|
||||||
|
int iDb = -1;
|
||||||
|
|
||||||
assert( pExpr->token.z );
|
assert( pExpr->token.z );
|
||||||
z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
|
z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
|
||||||
sqliteDequote(z);
|
sqliteDequote(z);
|
||||||
@ -440,11 +442,13 @@ int sqliteExprResolveIds(
|
|||||||
int j;
|
int j;
|
||||||
Table *pTab = pTabList->a[i].pTab;
|
Table *pTab = pTabList->a[i].pTab;
|
||||||
if( pTab==0 ) continue;
|
if( pTab==0 ) continue;
|
||||||
|
iDb = pTab->iDb;
|
||||||
assert( pTab->nCol>0 );
|
assert( pTab->nCol>0 );
|
||||||
for(j=0; j<pTab->nCol; j++){
|
for(j=0; j<pTab->nCol; j++){
|
||||||
if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
|
if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
|
||||||
cnt++;
|
cnt++;
|
||||||
pExpr->iTable = i + base;
|
pExpr->iTable = i + base;
|
||||||
|
pExpr->iDb = pTab->iDb;
|
||||||
if( j==pTab->iPKey ){
|
if( j==pTab->iPKey ){
|
||||||
/* Substitute the record number for the INTEGER PRIMARY KEY */
|
/* Substitute the record number for the INTEGER PRIMARY KEY */
|
||||||
pExpr->iColumn = -1;
|
pExpr->iColumn = -1;
|
||||||
@ -470,9 +474,10 @@ int sqliteExprResolveIds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( cnt==0 && sqliteIsRowid(z) ){
|
if( cnt==0 && iDb>=0 && sqliteIsRowid(z) ){
|
||||||
pExpr->iColumn = -1;
|
pExpr->iColumn = -1;
|
||||||
pExpr->iTable = base;
|
pExpr->iTable = base;
|
||||||
|
pExpr->iDb = iDb;
|
||||||
cnt = 1 + (pTabList->nSrc>1);
|
cnt = 1 + (pTabList->nSrc>1);
|
||||||
pExpr->op = TK_COLUMN;
|
pExpr->op = TK_COLUMN;
|
||||||
pExpr->dataType = SQLITE_SO_NUM;
|
pExpr->dataType = SQLITE_SO_NUM;
|
||||||
@ -544,11 +549,15 @@ int sqliteExprResolveIds(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( 0==(cntTab++) ) pExpr->iTable = i + base;
|
if( 0==(cntTab++) ){
|
||||||
|
pExpr->iTable = i + base;
|
||||||
|
pExpr->iDb = pTab->iDb;
|
||||||
|
}
|
||||||
for(j=0; j<pTab->nCol; j++){
|
for(j=0; j<pTab->nCol; j++){
|
||||||
if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
|
if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
|
||||||
cnt++;
|
cnt++;
|
||||||
pExpr->iTable = i + base;
|
pExpr->iTable = i + base;
|
||||||
|
pExpr->iDb = pTab->iDb;
|
||||||
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
|
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
|
||||||
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
|
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
|
||||||
pExpr->dataType = pTab->aCol[j].sortOrder & SQLITE_SO_TYPEMASK;
|
pExpr->dataType = pTab->aCol[j].sortOrder & SQLITE_SO_TYPEMASK;
|
||||||
@ -563,11 +572,15 @@ int sqliteExprResolveIds(
|
|||||||
int t = 0;
|
int t = 0;
|
||||||
if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zLeft) == 0 ){
|
if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zLeft) == 0 ){
|
||||||
pExpr->iTable = pTriggerStack->newIdx;
|
pExpr->iTable = pTriggerStack->newIdx;
|
||||||
|
assert( pTriggerStack->pTab );
|
||||||
|
pExpr->iDb = pTriggerStack->pTab->iDb;
|
||||||
cntTab++;
|
cntTab++;
|
||||||
t = 1;
|
t = 1;
|
||||||
}
|
}
|
||||||
if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zLeft) == 0 ){
|
if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zLeft) == 0 ){
|
||||||
pExpr->iTable = pTriggerStack->oldIdx;
|
pExpr->iTable = pTriggerStack->oldIdx;
|
||||||
|
assert( pTriggerStack->pTab );
|
||||||
|
pExpr->iDb = pTriggerStack->pTab->iDb;
|
||||||
cntTab++;
|
cntTab++;
|
||||||
t = 1;
|
t = 1;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.80 2003/04/20 17:29:24 drh Exp $
|
** $Id: insert.c,v 1.81 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -93,6 +93,7 @@ void sqliteInsert(
|
|||||||
){
|
){
|
||||||
Table *pTab; /* The table to insert into */
|
Table *pTab; /* The table to insert into */
|
||||||
char *zTab; /* Name of the table into which we are inserting */
|
char *zTab; /* Name of the table into which we are inserting */
|
||||||
|
const char *zDb; /* Name of the database holding this table */
|
||||||
int i, j, idx; /* Loop counters */
|
int i, j, idx; /* Loop counters */
|
||||||
Vdbe *v; /* Generate code into this virtual machine */
|
Vdbe *v; /* Generate code into this virtual machine */
|
||||||
Index *pIdx; /* For looping over indices of the table */
|
Index *pIdx; /* For looping over indices of the table */
|
||||||
@ -126,7 +127,9 @@ void sqliteInsert(
|
|||||||
if( pTab==0 ){
|
if( pTab==0 ){
|
||||||
goto insert_cleanup;
|
goto insert_cleanup;
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){
|
assert( pTab->iDb<db->nDb );
|
||||||
|
zDb = db->aDb[pTab->iDb].zName;
|
||||||
|
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
|
||||||
goto insert_cleanup;
|
goto insert_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.3 2003/04/15 01:19:49 drh Exp $
|
** $Id: pragma.c,v 1.4 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -107,7 +107,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
|||||||
zRight = sqliteStrNDup(pRight->z, pRight->n);
|
zRight = sqliteStrNDup(pRight->z, pRight->n);
|
||||||
sqliteDequote(zRight);
|
sqliteDequote(zRight);
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight) ){
|
if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
|
||||||
sqliteFree(zLeft);
|
sqliteFree(zLeft);
|
||||||
sqliteFree(zRight);
|
sqliteFree(zRight);
|
||||||
return;
|
return;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.132 2003/04/17 22:57:54 drh Exp $
|
** $Id: select.c,v 1.133 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -1917,7 +1917,7 @@ int sqliteSelect(
|
|||||||
int rc = 1; /* Value to return from this function */
|
int rc = 1; /* Value to return from this function */
|
||||||
|
|
||||||
if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;
|
if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_SELECT, 0, 0) ) return 1;
|
if( sqliteAuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||||
|
|
||||||
/* If there is are a sequence of queries, do the earlier ones first.
|
/* If there is are a sequence of queries, do the earlier ones first.
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This header file defines the interface that the SQLite library
|
** This header file defines the interface that the SQLite library
|
||||||
** presents to client programs.
|
** presents to client programs.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.44 2003/04/03 15:46:04 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.45 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_H_
|
#ifndef _SQLITE_H_
|
||||||
#define _SQLITE_H_
|
#define _SQLITE_H_
|
||||||
@ -513,7 +513,7 @@ int sqlite_aggregate_count(sqlite_func*);
|
|||||||
*/
|
*/
|
||||||
int sqlite_set_authorizer(
|
int sqlite_set_authorizer(
|
||||||
sqlite*,
|
sqlite*,
|
||||||
int (*xAuth)(void*,int,const char*,const char*),
|
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
|
||||||
void *pUserData
|
void *pUserData
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -522,7 +522,10 @@ int sqlite_set_authorizer(
|
|||||||
** be one of the values below. These values signify what kind of operation
|
** be one of the values below. These values signify what kind of operation
|
||||||
** is to be authorized. The 3rd and 4th parameters to the authorization
|
** is to be authorized. The 3rd and 4th parameters to the authorization
|
||||||
** function will be parameters or NULL depending on which of the following
|
** function will be parameters or NULL depending on which of the following
|
||||||
** codes is used as the second parameter.
|
** codes is used as the second parameter. The 5th parameter is the name
|
||||||
|
** of the database ("main", "temp", etc.) if applicable. The 6th parameter
|
||||||
|
** is the name of the trigger that is responsible for the access attempt,
|
||||||
|
** or NULL if this access attempt is directly from input SQL code.
|
||||||
**
|
**
|
||||||
** Arg-3 Arg-4
|
** Arg-3 Arg-4
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.177 2003/04/21 18:48:47 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.178 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
@ -105,6 +105,9 @@
|
|||||||
#ifndef UINT8_TYPE
|
#ifndef UINT8_TYPE
|
||||||
# define UINT8_TYPE unsigned char
|
# define UINT8_TYPE unsigned char
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef INT8_TYPE
|
||||||
|
# define INT8_TYPE signed char
|
||||||
|
#endif
|
||||||
#ifndef INTPTR_TYPE
|
#ifndef INTPTR_TYPE
|
||||||
# if SQLITE_PTR_SZ==4
|
# if SQLITE_PTR_SZ==4
|
||||||
# define INTPTR_TYPE int
|
# define INTPTR_TYPE int
|
||||||
@ -115,6 +118,7 @@
|
|||||||
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
||||||
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
||||||
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
||||||
|
typedef INT8_TYPE i8; /* 1-byte signed integer */
|
||||||
typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
|
typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
|
||||||
typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
|
typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
|
||||||
|
|
||||||
@ -290,7 +294,8 @@ struct sqlite {
|
|||||||
void *pTraceArg; /* Argument to the trace function */
|
void *pTraceArg; /* Argument to the trace function */
|
||||||
#endif
|
#endif
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */
|
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
|
||||||
|
/* Access authorization function */
|
||||||
void *pAuthArg; /* 1st argument to the access auth function */
|
void *pAuthArg; /* 1st argument to the access auth function */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -580,7 +585,8 @@ struct Token {
|
|||||||
struct Expr {
|
struct Expr {
|
||||||
u8 op; /* Operation performed by this node */
|
u8 op; /* Operation performed by this node */
|
||||||
u8 dataType; /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */
|
u8 dataType; /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */
|
||||||
u16 flags; /* Various flags. See below */
|
i8 iDb; /* Database referenced by this expression */
|
||||||
|
u8 flags; /* Various flags. See below */
|
||||||
Expr *pLeft, *pRight; /* Left and right subnodes */
|
Expr *pLeft, *pRight; /* Left and right subnodes */
|
||||||
ExprList *pList; /* A list of expressions used as function arguments
|
ExprList *pList; /* A list of expressions used as function arguments
|
||||||
** or in "<expr> IN (<expr-list)" */
|
** or in "<expr> IN (<expr-list)" */
|
||||||
@ -953,9 +959,8 @@ struct TriggerStack {
|
|||||||
int oldIdx; /* Index of vdbe cursor to "old" temp table */
|
int oldIdx; /* Index of vdbe cursor to "old" temp table */
|
||||||
int orconf; /* Current orconf policy */
|
int orconf; /* Current orconf policy */
|
||||||
int ignoreJump; /* where to jump to for a RAISE(IGNORE) */
|
int ignoreJump; /* where to jump to for a RAISE(IGNORE) */
|
||||||
Trigger *pTrigger;
|
Trigger *pTrigger; /* The trigger currently being coded */
|
||||||
|
TriggerStack *pNext; /* Next trigger down on the trigger stack */
|
||||||
TriggerStack *pNext;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1113,7 +1118,7 @@ void sqliteCreateForeignKey(Parse*, IdList*, Token*, IdList*, int);
|
|||||||
void sqliteDeferForeignKey(Parse*, int);
|
void sqliteDeferForeignKey(Parse*, int);
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
void sqliteAuthRead(Parse*,Expr*,SrcList*,int);
|
void sqliteAuthRead(Parse*,Expr*,SrcList*,int);
|
||||||
int sqliteAuthCheck(Parse*,int, const char*, const char*);
|
int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*);
|
||||||
#else
|
#else
|
||||||
# define sqliteAuthRead(a,b,c,d)
|
# define sqliteAuthRead(a,b,c,d)
|
||||||
# define sqliteAuthCheck(a,b,c,d) SQLITE_OK
|
# define sqliteAuthCheck(a,b,c,d) SQLITE_OK
|
||||||
|
144
src/tclsqlite.c
144
src/tclsqlite.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** A TCL Interface to SQLite
|
** A TCL Interface to SQLite
|
||||||
**
|
**
|
||||||
** $Id: tclsqlite.c,v 1.46 2003/04/03 15:46:04 drh Exp $
|
** $Id: tclsqlite.c,v 1.47 2003/04/22 20:30:39 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
||||||
|
|
||||||
@ -53,6 +53,7 @@ struct SqliteDb {
|
|||||||
char *zBusy; /* The busy callback routine */
|
char *zBusy; /* The busy callback routine */
|
||||||
char *zBegin; /* The begin-transaction callback routine */
|
char *zBegin; /* The begin-transaction callback routine */
|
||||||
char *zCommit; /* The commit-transaction callback routine */
|
char *zCommit; /* The commit-transaction callback routine */
|
||||||
|
char *zAuth; /* The authorization callback routine */
|
||||||
SqlFunc *pFunc; /* List of SQL functions */
|
SqlFunc *pFunc; /* List of SQL functions */
|
||||||
int rc; /* Return code of most recent sqlite_exec() */
|
int rc; /* Return code of most recent sqlite_exec() */
|
||||||
};
|
};
|
||||||
@ -268,6 +269,9 @@ static void DbDeleteCmd(void *db){
|
|||||||
if( pDb->zCommit ){
|
if( pDb->zCommit ){
|
||||||
Tcl_Free(pDb->zCommit);
|
Tcl_Free(pDb->zCommit);
|
||||||
}
|
}
|
||||||
|
if( pDb->zAuth ){
|
||||||
|
Tcl_Free(pDb->zAuth);
|
||||||
|
}
|
||||||
Tcl_Free((char*)pDb);
|
Tcl_Free((char*)pDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,6 +355,76 @@ static void tclSqlFunc(sqlite_func *context, int argc, const char **argv){
|
|||||||
sqlite_set_result_string(context, Tcl_GetStringResult(p->interp), -1);
|
sqlite_set_result_string(context, Tcl_GetStringResult(p->interp), -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
|
/*
|
||||||
|
** This is the authentication function. It appends the authentication
|
||||||
|
** type code and the two arguments to zCmd[] then invokes the result
|
||||||
|
** on the interpreter. The reply is examined to determine if the
|
||||||
|
** authentication fails or succeeds.
|
||||||
|
*/
|
||||||
|
static int auth_callback(
|
||||||
|
void *pArg,
|
||||||
|
int code,
|
||||||
|
const char *zArg1,
|
||||||
|
const char *zArg2,
|
||||||
|
const char *zArg3,
|
||||||
|
const char *zArg4
|
||||||
|
){
|
||||||
|
char *zCode;
|
||||||
|
Tcl_DString str;
|
||||||
|
int rc;
|
||||||
|
const char *zReply;
|
||||||
|
SqliteDb *pDb = (SqliteDb*)pArg;
|
||||||
|
|
||||||
|
switch( code ){
|
||||||
|
case SQLITE_COPY : zCode="SQLITE_COPY"; break;
|
||||||
|
case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
|
||||||
|
case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
|
||||||
|
case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
|
||||||
|
case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
|
||||||
|
case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
|
||||||
|
case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
|
||||||
|
case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
|
||||||
|
case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
|
||||||
|
case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
|
||||||
|
case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
|
||||||
|
case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
|
||||||
|
case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
|
||||||
|
case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
|
||||||
|
case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
|
||||||
|
case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
|
||||||
|
case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
|
||||||
|
case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
|
||||||
|
case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
|
||||||
|
case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
|
||||||
|
case SQLITE_READ : zCode="SQLITE_READ"; break;
|
||||||
|
case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
|
||||||
|
case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
|
||||||
|
case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
|
||||||
|
default : zCode="????"; break;
|
||||||
|
}
|
||||||
|
Tcl_DStringInit(&str);
|
||||||
|
Tcl_DStringAppend(&str, pDb->zAuth, -1);
|
||||||
|
Tcl_DStringAppendElement(&str, zCode);
|
||||||
|
Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
|
||||||
|
Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
|
||||||
|
Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
|
||||||
|
Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
|
||||||
|
rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
|
||||||
|
Tcl_DStringFree(&str);
|
||||||
|
zReply = Tcl_GetStringResult(pDb->interp);
|
||||||
|
if( strcmp(zReply,"SQLITE_OK")==0 ){
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else if( strcmp(zReply,"SQLITE_DENY")==0 ){
|
||||||
|
rc = SQLITE_DENY;
|
||||||
|
}else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
|
||||||
|
rc = SQLITE_IGNORE;
|
||||||
|
}else{
|
||||||
|
rc = 999;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The "sqlite" command below creates a new Tcl command for each
|
** The "sqlite" command below creates a new Tcl command for each
|
||||||
@ -369,16 +443,17 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
SqliteDb *pDb = (SqliteDb*)cd;
|
SqliteDb *pDb = (SqliteDb*)cd;
|
||||||
int choice;
|
int choice;
|
||||||
static const char *DB_strs[] = {
|
static const char *DB_strs[] = {
|
||||||
"begin_hook", "busy", "changes",
|
"authorizer", "begin_hook", "busy",
|
||||||
"close", "commit_hook", "complete",
|
"changes", "close", "commit_hook",
|
||||||
"errorcode", "eval", "function",
|
"complete", "errorcode", "eval",
|
||||||
"last_insert_rowid", "timeout", 0
|
"function", "last_insert_rowid", "timeout",
|
||||||
|
0
|
||||||
};
|
};
|
||||||
enum DB_enum {
|
enum DB_enum {
|
||||||
DB_BEGIN_HOOK, DB_BUSY, DB_CHANGES,
|
DB_AUTHORIZER, DB_BEGIN_HOOK, DB_BUSY,
|
||||||
DB_CLOSE, DB_COMMIT_HOOK, DB_COMPLETE,
|
DB_CHANGES, DB_CLOSE, DB_COMMIT_HOOK,
|
||||||
DB_ERRORCODE, DB_EVAL, DB_FUNCTION,
|
DB_COMPLETE, DB_ERRORCODE, DB_EVAL,
|
||||||
DB_LAST_INSERT_ROWID, DB_TIMEOUT,
|
DB_FUNCTION, DB_LAST_INSERT_ROWID,DB_TIMEOUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
if( objc<2 ){
|
if( objc<2 ){
|
||||||
@ -391,6 +466,57 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
|
|
||||||
switch( (enum DB_enum)choice ){
|
switch( (enum DB_enum)choice ){
|
||||||
|
|
||||||
|
/* $db authorizer ?CALLBACK?
|
||||||
|
**
|
||||||
|
** Invoke the given callback to authorize each SQL operation as it is
|
||||||
|
** compiled. 5 arguments are appended to the callback before it is
|
||||||
|
** invoked:
|
||||||
|
**
|
||||||
|
** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
|
||||||
|
** (2) First descriptive name (depends on authorization type)
|
||||||
|
** (3) Second descriptive name
|
||||||
|
** (4) Name of the database (ex: "main", "temp")
|
||||||
|
** (5) Name of trigger that is doing the access
|
||||||
|
**
|
||||||
|
** The callback should return on of the following strings: SQLITE_OK,
|
||||||
|
** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
|
||||||
|
**
|
||||||
|
** If this method is invoked with no arguments, the current authorization
|
||||||
|
** callback string is returned.
|
||||||
|
*/
|
||||||
|
case DB_AUTHORIZER: {
|
||||||
|
if( objc>3 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
|
||||||
|
}else if( objc==2 ){
|
||||||
|
if( pDb->zBegin ){
|
||||||
|
Tcl_AppendResult(interp, pDb->zAuth, 0);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
char *zAuth;
|
||||||
|
int len;
|
||||||
|
if( pDb->zAuth ){
|
||||||
|
Tcl_Free(pDb->zAuth);
|
||||||
|
}
|
||||||
|
zAuth = Tcl_GetStringFromObj(objv[2], &len);
|
||||||
|
if( zAuth && len>0 ){
|
||||||
|
pDb->zAuth = Tcl_Alloc( len + 1 );
|
||||||
|
strcpy(pDb->zAuth, zAuth);
|
||||||
|
}else{
|
||||||
|
pDb->zAuth = 0;
|
||||||
|
}
|
||||||
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
|
if( pDb->zAuth ){
|
||||||
|
pDb->interp = interp;
|
||||||
|
sqlite_set_authorizer(pDb->db, auth_callback, pDb);
|
||||||
|
}else{
|
||||||
|
sqlite_set_authorizer(pDb->db, 0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* $db begin_callback ?CALLBACK?
|
/* $db begin_callback ?CALLBACK?
|
||||||
**
|
**
|
||||||
** Invoke the given callback at the beginning of every SQL transaction.
|
** Invoke the given callback at the beginning of every SQL transaction.
|
||||||
|
124
src/test1.c
124
src/test1.c
@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.22 2003/02/16 22:21:32 drh Exp $
|
** $Id: test1.c,v 1.23 2003/04/22 20:30:40 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@ -588,125 +588,6 @@ static int sqlite_datatypes(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
|
||||||
/*
|
|
||||||
** Information used by the authentication function.
|
|
||||||
*/
|
|
||||||
typedef struct AuthInfo AuthInfo;
|
|
||||||
struct AuthInfo {
|
|
||||||
Tcl_Interp *interp; /* Interpreter to use */
|
|
||||||
int nCmd; /* Number of characters in zCmd[] */
|
|
||||||
char zCmd[500]; /* Command to invoke */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
** We create a single static authenticator. This won't work in a
|
|
||||||
** multi-threaded environment, but the test fixture is not multithreaded.
|
|
||||||
** And be making it static, we don't have to worry about deallocating
|
|
||||||
** after a test in order to void memory leaks.
|
|
||||||
*/
|
|
||||||
static AuthInfo authInfo;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This is the authentication function. It appends the authentication
|
|
||||||
** type code and the two arguments to zCmd[] then invokes the result
|
|
||||||
** on the interpreter. The reply is examined to determine if the
|
|
||||||
** authentication fails or succeeds.
|
|
||||||
*/
|
|
||||||
static int auth_callback(
|
|
||||||
void *NotUsed,
|
|
||||||
int code,
|
|
||||||
const char *zArg1,
|
|
||||||
const char *zArg2
|
|
||||||
){
|
|
||||||
char *zCode;
|
|
||||||
Tcl_DString str;
|
|
||||||
int rc;
|
|
||||||
const char *zReply;
|
|
||||||
switch( code ){
|
|
||||||
case SQLITE_COPY : zCode="SQLITE_COPY"; break;
|
|
||||||
case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
|
|
||||||
case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
|
|
||||||
case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
|
|
||||||
case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
|
|
||||||
case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
|
|
||||||
case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
|
|
||||||
case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
|
|
||||||
case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
|
|
||||||
case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
|
|
||||||
case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
|
|
||||||
case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
|
|
||||||
case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
|
|
||||||
case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
|
|
||||||
case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
|
|
||||||
case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
|
|
||||||
case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
|
|
||||||
case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
|
|
||||||
case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
|
|
||||||
case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
|
|
||||||
case SQLITE_READ : zCode="SQLITE_READ"; break;
|
|
||||||
case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
|
|
||||||
case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
|
|
||||||
case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
|
|
||||||
default : zCode="????"; break;
|
|
||||||
}
|
|
||||||
Tcl_DStringInit(&str);
|
|
||||||
Tcl_DStringAppend(&str, authInfo.zCmd, -1);
|
|
||||||
Tcl_DStringAppendElement(&str, zCode);
|
|
||||||
Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
|
|
||||||
Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
|
|
||||||
rc = Tcl_GlobalEval(authInfo.interp, Tcl_DStringValue(&str));
|
|
||||||
Tcl_DStringFree(&str);
|
|
||||||
zReply = Tcl_GetStringResult(authInfo.interp);
|
|
||||||
if( strcmp(zReply,"SQLITE_OK")==0 ){
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}else if( strcmp(zReply,"SQLITE_DENY")==0 ){
|
|
||||||
rc = SQLITE_DENY;
|
|
||||||
}else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
|
|
||||||
rc = SQLITE_IGNORE;
|
|
||||||
}else{
|
|
||||||
rc = 999;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This routine creates a new authenticator. It fills in the zCmd[]
|
|
||||||
** field of the authentication function state variable and then registers
|
|
||||||
** the authentication function with the SQLite library.
|
|
||||||
*/
|
|
||||||
static int test_set_authorizer(
|
|
||||||
void *NotUsed,
|
|
||||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
|
||||||
int argc, /* Number of arguments */
|
|
||||||
char **argv /* Text of each argument */
|
|
||||||
){
|
|
||||||
sqlite *db;
|
|
||||||
char *zCmd;
|
|
||||||
if( argc!=3 ){
|
|
||||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
|
||||||
" DB CALLBACK\"", 0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
|
||||||
zCmd = argv[2];
|
|
||||||
if( zCmd[0]==0 ){
|
|
||||||
sqlite_set_authorizer(db, 0, 0);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
if( strlen(zCmd)>sizeof(authInfo.zCmd) ){
|
|
||||||
Tcl_AppendResult(interp, "command too big", 0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
authInfo.interp = interp;
|
|
||||||
authInfo.nCmd = strlen(zCmd);
|
|
||||||
strcpy(authInfo.zCmd, zCmd);
|
|
||||||
sqlite_set_authorizer(db, auth_callback, 0);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Usage: sqlite_compile DB SQL TAILVAR
|
** Usage: sqlite_compile DB SQL TAILVAR
|
||||||
**
|
**
|
||||||
@ -878,9 +759,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
|
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
|
||||||
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
|
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
|
||||||
{ "sqlite_datatypes", (Tcl_CmdProc*)sqlite_datatypes },
|
{ "sqlite_datatypes", (Tcl_CmdProc*)sqlite_datatypes },
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
|
||||||
{ "sqlite_set_authorizer", (Tcl_CmdProc*)test_set_authorizer },
|
|
||||||
#endif
|
|
||||||
#ifdef MEMORY_DEBUG
|
#ifdef MEMORY_DEBUG
|
||||||
{ "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
|
{ "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
|
||||||
{ "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },
|
{ "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },
|
||||||
|
@ -98,11 +98,13 @@ void sqliteBeginTrigger(
|
|||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
{
|
{
|
||||||
int code = SQLITE_CREATE_TRIGGER;
|
int code = SQLITE_CREATE_TRIGGER;
|
||||||
|
const char *zDb = db->aDb[tab->iDb].zName;
|
||||||
|
const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
|
||||||
if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
|
if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
|
||||||
if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
|
if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
|
||||||
goto trigger_cleanup;
|
goto trigger_cleanup;
|
||||||
}
|
}
|
||||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0)){
|
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
|
||||||
goto trigger_cleanup;
|
goto trigger_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,9 +399,11 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
|
|||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
{
|
{
|
||||||
int code = SQLITE_DROP_TRIGGER;
|
int code = SQLITE_DROP_TRIGGER;
|
||||||
|
const char *zDb = db->aDb[pTrigger->iDb].zName;
|
||||||
|
const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
|
||||||
if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
|
if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
|
||||||
if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName) ||
|
if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
|
||||||
sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTrigger->iDb),0) ){
|
sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
|
||||||
goto drop_trigger_cleanup;
|
goto drop_trigger_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle UPDATE statements.
|
** to handle UPDATE statements.
|
||||||
**
|
**
|
||||||
** $Id: update.c,v 1.61 2003/04/20 17:29:24 drh Exp $
|
** $Id: update.c,v 1.62 2003/04/22 20:30:40 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ void sqliteUpdate(
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
|
rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
|
||||||
pTab->aCol[j].zName);
|
pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
|
||||||
if( rc==SQLITE_DENY ){
|
if( rc==SQLITE_DENY ){
|
||||||
goto update_cleanup;
|
goto update_cleanup;
|
||||||
}else if( rc==SQLITE_IGNORE ){
|
}else if( rc==SQLITE_IGNORE ){
|
||||||
|
491
test/auth.test
491
test/auth.test
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
|||||||
# interface is pretty well tested. This file contains some addition
|
# interface is pretty well tested. This file contains some addition
|
||||||
# tests for fringe issues that the main test suite does not cover.
|
# tests for fringe issues that the main test suite does not cover.
|
||||||
#
|
#
|
||||||
# $Id: tclsqlite.test,v 1.11 2003/04/03 15:46:05 drh Exp $
|
# $Id: tclsqlite.test,v 1.12 2003/04/22 20:30:40 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -29,7 +29,7 @@ do_test tcl-1.1 {
|
|||||||
do_test tcl-1.2 {
|
do_test tcl-1.2 {
|
||||||
set v [catch {db bogus} msg]
|
set v [catch {db bogus} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {bad option "bogus": must be begin_hook, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, or timeout}}
|
} {1 {bad option "bogus": must be authorizer, begin_hook, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, or timeout}}
|
||||||
do_test tcl-1.3 {
|
do_test tcl-1.3 {
|
||||||
execsql {CREATE TABLE t1(a int, b int)}
|
execsql {CREATE TABLE t1(a int, b int)}
|
||||||
execsql {INSERT INTO t1 VALUES(10,20)}
|
execsql {INSERT INTO t1 VALUES(10,20)}
|
||||||
|
Reference in New Issue
Block a user