1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Revise the sqlite_set_authorizer API to provide more detailed information

about the SQL statement being authorized.  Only partially tested so far. (CVS 830)

FossilOrigin-Name: 45de93f913a18026a45de6254963dbcd1b0f1a19
This commit is contained in:
drh
2003-01-13 23:27:31 +00:00
parent 1962bda764
commit e5f9c6442f
14 changed files with 331 additions and 397 deletions

View File

@ -1,5 +1,5 @@
C The\sinitial\sround\sof\stests\sfor\sthe\ssqlite_set_authorizer()\sAPI.\s\sMore\sare\nneeded\sbefore\srelease.\s\sTicket\s#215.\s(CVS\s829) C Revise\sthe\ssqlite_set_authorizer\sAPI\sto\sprovide\smore\sdetailed\sinformation\nabout\sthe\sSQL\sstatement\sbeing\sauthorized.\s\sOnly\spartially\stested\sso\sfar.\s(CVS\s830)
D 2003-01-12T19:33:53 D 2003-01-13T23:27:32
F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64 F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -18,46 +18,46 @@ F main.mk 8b10c5df8a21cdd343986a90c75247bafaebb3aa
F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F src/auth.c de3c70e5eab92ef5c1af87dae626022b8f46a6fd F src/auth.c 9c2db0bc7707f2d2e227f47e3d557b41d44ade75
F src/btree.c 131b5903f66e148f0f9af0cedd1c6654932c4e04 F src/btree.c 131b5903f66e148f0f9af0cedd1c6654932c4e04
F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
F src/build.c 3136d7fc765cc2feee2ad987bac1c1696fdc0f0e F src/build.c 94cd4ed1724b3e7304387b2caece75aff39d7f6e
F src/delete.c bc807a756dde6aa16db38f6e05a90408053d2f2c F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c
F src/encode.c 09d1fe8a2e97ff94cce496e2909e2ebc8947960b F src/encode.c 09d1fe8a2e97ff94cce496e2909e2ebc8947960b
F src/expr.c d8b319f25335443a415a639aec8e0edc64e3ab6c F src/expr.c d8b319f25335443a415a639aec8e0edc64e3ab6c
F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63 F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63
F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
F src/insert.c d19a73907ade1f2801bf8c3cb68538e8b1a05b5f F src/insert.c db954e955970795819145a3649fd2ad116a58890
F src/main.c c8f8fdfe4548a8404fab90ff6ad374b217e6b7fa F src/main.c c8f8fdfe4548a8404fab90ff6ad374b217e6b7fa
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c 28447687e7914306650f72058f62f7162faeef1f F src/os.c 28447687e7914306650f72058f62f7162faeef1f
F src/os.h afa3e096213bad86845f8bdca81a9e917505e401 F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
F src/pager.c 5b81639b38eb4250810ed2b31aada9fb040ed86b F src/pager.c 5b81639b38eb4250810ed2b31aada9fb040ed86b
F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626 F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
F src/parse.y 427a17888c117cc9cc35311eda0603d55437f02b F src/parse.y 58655a50817f93ddd0bc3d8949e267729396949c
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 1b7d20b659621bf8621dec710e9680b4c380563c F src/select.c 5ce75c1381d8ec3b89ea4d7eb5171bc57785e610
F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 7b35872afdba0d46890773470a12aa71d78f6d21 F src/sqlite.h.in 9974a66d4caa4880fe44ebdc306f5f94c6a4d9c0
F src/sqliteInt.h 01b59d2ecbd36b7ec750339bbd9401c012b463c2 F src/sqliteInt.h bc986d4fc3d8285cec370eb5e305d5499f422a31
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64 F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
F src/test1.c 2a0e5cf7e66cbbb46d9f0c97ea8f406141e8b263 F src/test1.c 921e5dda494f836d2ebea703bd5b239a7cc963d0
F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b
F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728 F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
F src/tokenize.c 7ac1c33e0149647c9eb5959c48992df6906d4809 F src/tokenize.c 7ac1c33e0149647c9eb5959c48992df6906d4809
F src/trigger.c dd3fb6595643e29b71d6f3ecb22afb930224633c F src/trigger.c cb72a3374b21ed00a6dbd3c2c5aa27a7fa72625f
F src/update.c 9f2e9105c697b11b06b381910d0e429718f01cc3 F src/update.c f06afa9bf1f777d17702e0f6e33cf44c44bc4f75
F src/util.c 354336da4a6f1c98f687a13db0c45ed9314a892b F src/util.c 354336da4a6f1c98f687a13db0c45ed9314a892b
F src/vdbe.c e103bd5a154b1790dd344662dceb14566a51a879 F src/vdbe.c e103bd5a154b1790dd344662dceb14566a51a879
F src/vdbe.h 754eba497cfe0c3e352b9c101ab2f811f10d0a55 F src/vdbe.h 754eba497cfe0c3e352b9c101ab2f811f10d0a55
F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18 F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18
F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029 F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029
F test/auth.test 1e8e443bc8d5c4ea44176ce6d9de4157582475aa F test/auth.test c0b3210b109f9cdde2a19c7af603a3f6c763dcf8
F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678 F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
F test/btree.test 10e75aec120ecefc0edc4c912a0980a43db1b6c2 F test/btree.test 10e75aec120ecefc0edc4c912a0980a43db1b6c2
@ -154,7 +154,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
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 7601916419489879fe963c83010b452c49ef063f P 5707b3d56efb6e988f816abefb1836f2f3254117
R bf3593b345d77cb3f65a7094575c0db9 R 185c96485c9e323ed508e05878c2e1fd
U drh U drh
Z 10949dc2e6e230f66d8a085db700df05 Z ce7138319a0232b300fa79474bc44207

View File

@ -1 +1 @@
5707b3d56efb6e988f816abefb1836f2f3254117 45de93f913a18026a45de6254963dbcd1b0f1a19

View File

@ -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.2 2003/01/12 19:33:53 drh Exp $ ** $Id: auth.c,v 1.3 2003/01/13 23:27:32 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -106,7 +106,7 @@ void sqliteAuthRead(
}else{ }else{
zCol = "ROWID"; zCol = "ROWID";
} }
rc = db->xAuth(db->pAuthArg, SQLITE_READ_COLUMN, pTab->zName, zCol); rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol);
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 ){
@ -119,22 +119,25 @@ void sqliteAuthRead(
} }
/* /*
** Check the user-supplied authorization function to see if it is ok to ** Do an authorization check using the code and arguments given. Return
** delete rows from the table pTab. Return SQLITE_OK if it is. Return ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
** SQLITE_IGNORE if deletions should be silently omitted. Return SQLITE_DENY ** is returned, then the error count and error message in pParse are
** if an error is to be reported. In the last case, write the text of ** modified appropriately.
** the error into pParse->zErrMsg.
*/ */
int sqliteAuthDelete(Parse *pParse, const char *zName, int forceError){ int sqliteAuthCheck(
Parse *pParse,
int code,
const char *zArg1,
const char *zArg2
){
sqlite *db = pParse->db; sqlite *db = pParse->db;
int rc; int rc;
if( db->xAuth==0 ){ if( db->xAuth==0 ){
return SQLITE_OK; return SQLITE_OK;
} }
rc = db->xAuth(db->pAuthArg, SQLITE_DELETE_ROW, zName, ""); rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2);
if( rc==SQLITE_DENY || (rc==SQLITE_IGNORE && forceError) ){ if( rc==SQLITE_DENY ){
sqliteSetString(&pParse->zErrMsg,"deletion from table ", sqliteSetString(&pParse->zErrMsg, "not authorized", 0);
zName, " is prohibited", 0);
pParse->nErr++; pParse->nErr++;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
rc = SQLITE_DENY; rc = SQLITE_DENY;
@ -143,73 +146,4 @@ int sqliteAuthDelete(Parse *pParse, const char *zName, int forceError){
return rc; return rc;
} }
/*
** Check the user-supplied authorization function to see if it is ok to
** insert rows from the table pTab. Return SQLITE_OK if it is. Return
** SQLITE_IGNORE if deletions should be silently omitted. Return SQLITE_DENY
** if an error is to be reported. In the last case, write the text of
** the error into pParse->zErrMsg.
*/
int sqliteAuthInsert(Parse *pParse, const char *zName, int forceError){
sqlite *db = pParse->db;
int rc;
if( db->xAuth==0 ){
return SQLITE_OK;
}
rc = db->xAuth(db->pAuthArg, SQLITE_INSERT_ROW, zName, "");
if( rc==SQLITE_DENY || (rc==SQLITE_IGNORE && forceError) ){
sqliteSetString(&pParse->zErrMsg,"insertion into table ",
zName, " is prohibited", 0);
pParse->nErr++;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
rc = SQLITE_DENY;
sqliteAuthBadReturnCode(pParse, rc);
}
return rc;
}
/*
** Check to see if it is ok to modify column "j" of table pTab.
** Return SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY.
*/
int sqliteAuthWrite(Parse *pParse, Table *pTab, int j){
sqlite *db = pParse->db;
int rc;
if( db->xAuth==0 ) return SQLITE_OK;
rc = db->xAuth(db->pAuthArg, SQLITE_WRITE_COLUMN,
pTab->zName, pTab->aCol[j].zName);
if( rc==SQLITE_DENY ){
sqliteSetString(&pParse->zErrMsg, "changes to ", pTab->zName,
".", pTab->aCol[j].zName, " are prohibited", 0);
pParse->nErr++;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
sqliteAuthBadReturnCode(pParse, rc);
}
return rc;
}
/*
** Check to see if it is ok to execute a special command such as
** COPY or VACUUM or ROLLBACK.
*/
int sqliteAuthCommand(Parse *pParse, const char *zCmd, const char *zArg1){
sqlite *db = pParse->db;
int rc;
if( db->xAuth==0 ) return SQLITE_OK;
rc = db->xAuth(db->pAuthArg, SQLITE_COMMAND, zCmd, zArg1);
if( rc==SQLITE_DENY ){
if( zArg1 && zArg1[0] ){
sqliteSetString(&pParse->zErrMsg, "execution of the ", zCmd, " ", zArg1,
" command is prohibited", 0);
}else{
sqliteSetString(&pParse->zErrMsg, "execution of the ", zCmd,
" command is prohibited", 0);
}
pParse->nErr++;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
sqliteAuthBadReturnCode(pParse, rc);
}
return rc;
}
#endif /* SQLITE_OMIT_AUTHORIZATION */ #endif /* SQLITE_OMIT_AUTHORIZATION */

View File

@ -25,7 +25,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** PRAGMA
** **
** $Id: build.c,v 1.120 2003/01/12 18:02:17 drh Exp $ ** $Id: build.c,v 1.121 2003/01/13 23:27:32 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@ -315,7 +315,13 @@ void sqliteOpenMasterTable(Vdbe *v, int isTemp){
** At the end of the CREATE TABLE statement, the sqliteEndTable() routine ** At the end of the CREATE TABLE statement, the sqliteEndTable() routine
** is called to complete the construction of the new table record. ** is called to complete the construction of the new table record.
*/ */
void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){ void sqliteStartTable(
Parse *pParse, /* Parser context */
Token *pStart, /* The "CREATE" token */
Token *pName, /* Name of table or view to create */
int isTemp, /* True if this is a TEMP table */
int isView /* True if this is a VIEW */
){
Table *pTable; Table *pTable;
Index *pIdx; Index *pIdx;
char *zName; char *zName;
@ -325,9 +331,31 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
pParse->sFirstToken = *pStart; pParse->sFirstToken = *pStart;
zName = sqliteTableNameFromToken(pName); zName = sqliteTableNameFromToken(pName);
if( zName==0 ) return; if( zName==0 ) return;
if( sqliteAuthInsert(pParse, SCHEMA_TABLE(isTemp), 1) ){ #ifndef SQLITE_OMIT_AUTHORIZATION
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0) ){
return; return;
} }
{
int code;
if( isView ){
if( isTemp ){
code = SQLITE_CREATE_TEMP_VIEW;
}else{
code = SQLITE_CREATE_VIEW;
}
}else{
if( isTemp ){
code = SQLITE_CREATE_TEMP_TABLE;
}else{
code = SQLITE_CREATE_TABLE;
}
}
if( sqliteAuthCheck(pParse, code, zName, 0) ){
return;
}
}
#endif
/* Before trying to create a temporary table, make sure the Btree for /* Before trying to create a temporary table, make sure the Btree for
** holding temporary tables is open. ** holding temporary tables is open.
@ -895,7 +923,7 @@ void sqliteCreateView(
const char *z; const char *z;
Token sEnd; Token sEnd;
sqliteStartTable(pParse, pBegin, pName, isTemp); sqliteStartTable(pParse, pBegin, pName, isTemp, 1);
p = pParse->pNewTable; p = pParse->pNewTable;
if( p==0 || pParse->nErr ){ if( p==0 || pParse->nErr ){
sqliteSelectDelete(pSelect); sqliteSelectDelete(pSelect);
@ -1072,9 +1100,30 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
if( pParse->nErr || sqlite_malloc_failed ) return; if( pParse->nErr || sqlite_malloc_failed ) return;
pTable = sqliteTableFromToken(pParse, pName); pTable = sqliteTableFromToken(pParse, pName);
if( pTable==0 ) return; if( pTable==0 ) return;
if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pTable->isTemp), 1) ){ #ifndef SQLITE_OMIT_AUTHORIZATION
if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->isTemp),0)){
return; return;
} }
{
int code;
if( isView ){
if( pTable->isTemp ){
code = SQLITE_DROP_TEMP_VIEW;
}else{
code = SQLITE_DROP_VIEW;
}
}else{
if( pTable->isTemp ){
code = SQLITE_DROP_TEMP_TABLE;
}else{
code = SQLITE_DROP_TABLE;
}
}
if( sqliteAuthCheck(pParse, code, pTable->zName, 0) ){
return;
}
}
#endif
if( pTable->readOnly ){ if( pTable->readOnly ){
sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName, sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName,
" may not be dropped", 0); " may not be dropped", 0);
@ -1093,9 +1142,6 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
pParse->nErr++; pParse->nErr++;
return; return;
} }
if( sqliteAuthDelete(pParse, pTable->zName, 1) ){
return;
}
/* Generate code to remove the table from the master table /* Generate code to remove the table from the master table
** on disk. ** on disk.
@ -1374,9 +1420,6 @@ void sqliteCreateIndex(
pParse->nErr++; pParse->nErr++;
goto exit_create_index; goto exit_create_index;
} }
if( sqliteAuthInsert(pParse, SCHEMA_TABLE(pTab->isTemp), 1) ){
goto exit_create_index;
}
/* If this index is created while re-reading the schema from sqlite_master /* If this index is created while re-reading the schema from sqlite_master
** but the table associated with this index is a temporary table, it can ** but the table associated with this index is a temporary table, it can
@ -1441,6 +1484,19 @@ void sqliteCreateIndex(
hideName = sqliteFindIndex(db, zName)!=0; hideName = sqliteFindIndex(db, zName)!=0;
} }
/* Check for authorization to create an index.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->isTemp), 0) ){
goto exit_create_index;
}
i = SQLITE_CREATE_INDEX;
if( pTab->isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
if( sqliteAuthCheck(pParse, i, zName, pTab->zName) ){
goto exit_create_index;
}
#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
** key out of the last column added to the table under construction. ** key out of the last column added to the table under construction.
** So create a fake list to simulate this. ** So create a fake list to simulate this.
@ -1638,9 +1694,19 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
pParse->nErr++; pParse->nErr++;
return; return;
} }
if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pIndex->pTable->isTemp), 1) ){ #ifndef SQLITE_OMIT_AUTHORIZATION
return; {
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
if( sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTab->isTemp), 0) ){
return;
}
if( pTab->isTemp ) code = SQLITE_DROP_TEMP_INDEX;
if( sqliteAuthCheck(pParse, code, pIndex->zName, 0) ){
return;
}
} }
#endif
/* Generate code to remove the index and from the master table */ /* Generate code to remove the index and from the master table */
v = sqliteGetVdbe(pParse); v = sqliteGetVdbe(pParse);
@ -1837,10 +1903,8 @@ void sqliteCopy(
pTab = sqliteTableNameToTable(pParse, zTab); pTab = sqliteTableNameToTable(pParse, zTab);
sqliteFree(zTab); sqliteFree(zTab);
if( pTab==0 ) goto copy_cleanup; if( pTab==0 ) goto copy_cleanup;
if( sqliteAuthInsert(pParse, zTab, 0) ){ if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0)
goto copy_cleanup; || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, 0) ){
}
if( sqliteAuthCommand(pParse, "COPY", zTab) ){
goto copy_cleanup; goto copy_cleanup;
} }
v = sqliteGetVdbe(pParse); v = sqliteGetVdbe(pParse);
@ -1925,7 +1989,7 @@ void sqliteBeginTransaction(Parse *pParse, int onError){
if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return; if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
if( pParse->nErr || sqlite_malloc_failed ) return; if( pParse->nErr || sqlite_malloc_failed ) return;
if( sqliteAuthCommand(pParse, "BEGIN", "") ) return; if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0) ) return;
if( db->flags & SQLITE_InTrans ){ if( db->flags & SQLITE_InTrans ){
pParse->nErr++; pParse->nErr++;
sqliteSetString(&pParse->zErrMsg, "cannot start a transaction " sqliteSetString(&pParse->zErrMsg, "cannot start a transaction "
@ -1945,7 +2009,7 @@ void sqliteCommitTransaction(Parse *pParse){
if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return; if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
if( pParse->nErr || sqlite_malloc_failed ) return; if( pParse->nErr || sqlite_malloc_failed ) return;
if( sqliteAuthCommand(pParse, "COMMIT", "") ) return; if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0) ) return;
if( (db->flags & SQLITE_InTrans)==0 ){ if( (db->flags & SQLITE_InTrans)==0 ){
pParse->nErr++; pParse->nErr++;
sqliteSetString(&pParse->zErrMsg, sqliteSetString(&pParse->zErrMsg,
@ -1966,7 +2030,7 @@ void sqliteRollbackTransaction(Parse *pParse){
if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return; if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
if( pParse->nErr || sqlite_malloc_failed ) return; if( pParse->nErr || sqlite_malloc_failed ) return;
if( sqliteAuthCommand(pParse, "ROLLBACK", "") ) return; if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0) ) return;
if( (db->flags & SQLITE_InTrans)==0 ){ if( (db->flags & SQLITE_InTrans)==0 ){
pParse->nErr++; pParse->nErr++;
sqliteSetString(&pParse->zErrMsg, sqliteSetString(&pParse->zErrMsg,
@ -2075,7 +2139,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( sqliteAuthCommand(pParse, "PRAGMA", zLeft) ) return; if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight) ) return;
/* /*
** PRAGMA default_cache_size ** PRAGMA default_cache_size

View File

@ -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.44 2003/01/12 18:02:18 drh Exp $ ** $Id: delete.c,v 1.45 2003/01/13 23:27:33 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -88,8 +88,7 @@ void sqliteDeleteFrom(
int row_triggers_exist = 0; int row_triggers_exist = 0;
int oldIdx = -1; int oldIdx = -1;
if( pParse->nErr || sqlite_malloc_failed if( pParse->nErr || sqlite_malloc_failed ){
|| sqliteAuthCommand(pParse,"DELETE",0) ){
pTabList = 0; pTabList = 0;
goto delete_from_cleanup; goto delete_from_cleanup;
} }
@ -126,7 +125,9 @@ void sqliteDeleteFrom(
assert( pTabList->nSrc==1 ); assert( pTabList->nSrc==1 );
pTab = pTabList->a[0].pTab; pTab = pTabList->a[0].pTab;
assert( pTab->pSelect==0 ); /* This table is not a view */ assert( pTab->pSelect==0 ); /* This table is not a view */
if( sqliteAuthDelete(pParse, pTab->zName, 0) ) goto delete_from_cleanup; if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0) ){
goto delete_from_cleanup;
}
/* Allocate a cursor used to store the old.* data for a trigger. /* Allocate a cursor used to store the old.* data for a trigger.
*/ */

View File

@ -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.70 2003/01/12 19:33:53 drh Exp $ ** $Id: insert.c,v 1.71 2003/01/13 23:27:33 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -114,7 +114,6 @@ void sqliteInsert(
int newIdx = -1; int newIdx = -1;
if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
if( sqliteAuthCommand(pParse, "INSERT", 0) ) goto insert_cleanup;
db = pParse->db; db = pParse->db;
/* Locate the table into which we will be inserting new information. /* Locate the table into which we will be inserting new information.
@ -127,7 +126,7 @@ void sqliteInsert(
pParse->nErr++; pParse->nErr++;
goto insert_cleanup; goto insert_cleanup;
} }
if( sqliteAuthInsert(pParse, zTab, 0) ){ if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){
goto insert_cleanup; goto insert_cleanup;
} }

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** numeric codes for all of the tokens.
** **
** @(#) $Id: parse.y,v 1.86 2003/01/07 02:47:48 drh Exp $ ** @(#) $Id: parse.y,v 1.87 2003/01/13 23:27:33 drh Exp $
*/ */
%token_prefix TK_ %token_prefix TK_
%token_type {Token} %token_type {Token}
@ -85,7 +85,7 @@ cmd ::= ROLLBACK trans_opt. {sqliteRollbackTransaction(pParse);}
// //
cmd ::= create_table create_table_args. cmd ::= create_table create_table_args.
create_table ::= CREATE(X) temp(T) TABLE nm(Y). { create_table ::= CREATE(X) temp(T) TABLE nm(Y). {
sqliteStartTable(pParse,&X,&Y,T); sqliteStartTable(pParse,&X,&Y,T,0);
} }
%type temp {int} %type temp {int}
temp(A) ::= TEMP. {A = pParse->isTemp || !pParse->initFlag;} temp(A) ::= TEMP. {A = pParse->isTemp || !pParse->initFlag;}

View File

@ -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.120 2003/01/12 18:02:18 drh Exp $ ** $Id: select.c,v 1.121 2003/01/13 23:27:33 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -1781,7 +1781,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( sqliteAuthCommand(pParse, "SELECT", 0) ) return 1; if( sqliteAuthCheck(pParse, SQLITE_SELECT, 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.
*/ */

View File

@ -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.36 2003/01/12 18:02:18 drh Exp $ ** @(#) $Id: sqlite.h.in,v 1.37 2003/01/13 23:27:33 drh Exp $
*/ */
#ifndef _SQLITE_H_ #ifndef _SQLITE_H_
#define _SQLITE_H_ #define _SQLITE_H_
@ -509,18 +509,42 @@ 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*),
void* void *pUserData
); );
/* /*
** The second parameter to the access authorization function above will ** The second parameter to the access authorization function above will
** be one of these values: ** 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
** function will be parameters or NULL depending on which of the following
** codes is used as the second parameter.
**
** Arg-3 Arg-4
*/ */
#define SQLITE_READ_COLUMN 1 /* Is it OK to read the specified column? */ #define SQLITE_COPY 0 /* Table Name NULL */
#define SQLITE_WRITE_COLUMN 2 /* Is it OK to update the specified column? */ #define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
#define SQLITE_DELETE_ROW 3 /* Is it OK to delete a row from the table? */ #define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
#define SQLITE_INSERT_ROW 4 /* Is it OK to insert a new row in the table? */ #define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
#define SQLITE_COMMAND 5 /* Is it OK to execute a particular command? */ #define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name NULL */
#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name NULL */
#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
#define SQLITE_DELETE 9 /* Table Name NULL */
#define SQLITE_DROP_INDEX 10 /* Index Name NULL */
#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name NULL */
#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name NULL */
#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
#define SQLITE_DROP_TRIGGER 16 /* Trigger Name NULL */
#define SQLITE_DROP_VIEW 17 /* View Name NULL */
#define SQLITE_INSERT 18 /* Table Name NULL */
#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
#define SQLITE_READ 20 /* Table Name Column Name */
#define SQLITE_SELECT 21 /* NULL NULL */
#define SQLITE_TRANSACTION 22 /* NULL NULL */
#define SQLITE_UPDATE 23 /* Table Name Column Name */
/* /*
** The return value of the authorization function should be one of the ** The return value of the authorization function should be one of the

View File

@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.153 2003/01/12 18:02:18 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.154 2003/01/13 23:27:33 drh Exp $
*/ */
#include "config.h" #include "config.h"
#include "sqlite.h" #include "sqlite.h"
@ -938,7 +938,7 @@ void sqliteRollbackInternalChanges(sqlite*);
void sqliteCommitInternalChanges(sqlite*); void sqliteCommitInternalChanges(sqlite*);
Table *sqliteResultSetOfSelect(Parse*,char*,Select*); Table *sqliteResultSetOfSelect(Parse*,char*,Select*);
void sqliteOpenMasterTable(Vdbe *v, int); void sqliteOpenMasterTable(Vdbe *v, int);
void sqliteStartTable(Parse*,Token*,Token*,int); void sqliteStartTable(Parse*,Token*,Token*,int,int);
void sqliteAddColumn(Parse*,Token*); void sqliteAddColumn(Parse*,Token*);
void sqliteAddNotNull(Parse*, int); void sqliteAddNotNull(Parse*, int);
void sqliteAddPrimaryKey(Parse*, IdList*, int); void sqliteAddPrimaryKey(Parse*, IdList*, int);
@ -1035,13 +1035,8 @@ 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 sqliteAuthDelete(Parse*,const char*, int); int sqliteAuthCheck(Parse*,int, const char*, const char*);
int sqliteAuthInsert(Parse*,const char*, int);
int sqliteAuthCommand(Parse*,const char*,const char*);
#else #else
# define sqliteAuthRead(a,b,c,d) # define sqliteAuthRead(a,b,c,d)
# define sqliteAuthDelete(a,b,c) SQLITE_OK # define sqliteAuthCheck(a,b,c,d) SQLITE_OK
# define sqliteAuthInsert(a,b,c) SQLITE_OK
# define sqliteAuthWrite(a,b,c) SQLITE_OK
# define sqliteAuthCommand(a,b,c) SQLITE_OK
#endif #endif

View File

@ -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.15 2003/01/12 18:02:19 drh Exp $ ** $Id: test1.c,v 1.16 2003/01/13 23:27:33 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@ -595,17 +595,36 @@ static int auth_callback(
int rc; int rc;
const char *zReply; const char *zReply;
switch( code ){ switch( code ){
case SQLITE_READ_COLUMN: zCode="SQLITE_READ_COLUMN"; break; case SQLITE_COPY : zCode="SQLITE_COPY"; break;
case SQLITE_WRITE_COLUMN: zCode="SQLITE_WRITE_COLUMN"; break; case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
case SQLITE_INSERT_ROW: zCode="SQLITE_INSERT_ROW"; break; case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
case SQLITE_DELETE_ROW: zCode="SQLITE_DELETE_ROW"; break; case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
case SQLITE_COMMAND: zCode="SQLITE_COMMAND"; break; case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
default: zCode="unknown code"; 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_DStringInit(&str);
Tcl_DStringAppend(&str, authInfo.zCmd, -1); Tcl_DStringAppend(&str, authInfo.zCmd, -1);
Tcl_DStringAppendElement(&str, zCode); Tcl_DStringAppendElement(&str, zCode);
Tcl_DStringAppendElement(&str, zArg1); Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
rc = Tcl_GlobalEval(authInfo.interp, Tcl_DStringValue(&str)); rc = Tcl_GlobalEval(authInfo.interp, Tcl_DStringValue(&str));
Tcl_DStringFree(&str); Tcl_DStringFree(&str);

View File

@ -49,8 +49,7 @@ void sqliteCreateTrigger(
){ ){
Trigger *nt; Trigger *nt;
Table *tab; Table *tab;
char *zName = 0; /* Name of the trigger */
if( sqliteAuthCommand(pParse, "CREATE", "TRIGGER") ) goto trigger_cleanup;
/* Check that: /* Check that:
** 1. the trigger name does not already exist. ** 1. the trigger name does not already exist.
@ -59,16 +58,12 @@ void sqliteCreateTrigger(
** 4. That we are not trying to create an INSTEAD OF trigger on a table. ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
*/ */
{ zName = sqliteStrNDup(pName->z, pName->n);
char *tmp_str = sqliteStrNDup(pName->z, pName->n); if( sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1) ){
if( sqliteHashFind(&(pParse->db->trigHash), tmp_str, pName->n + 1) ){ sqliteSetNString(&pParse->zErrMsg, "trigger ", -1,
sqliteSetNString(&pParse->zErrMsg, "trigger ", -1, pName->z, pName->n, " already exists", -1, 0);
pName->z, pName->n, " already exists", -1, 0); pParse->nErr++;
sqliteFree(tmp_str); goto trigger_cleanup;
pParse->nErr++;
goto trigger_cleanup;
}
sqliteFree(tmp_str);
} }
{ {
char *tmp_str = sqliteStrNDup(pTableName->z, pTableName->n); char *tmp_str = sqliteStrNDup(pTableName->z, pTableName->n);
@ -104,9 +99,15 @@ void sqliteCreateTrigger(
" trigger on table: ", -1, pTableName->z, pTableName->n, 0); " trigger on table: ", -1, pTableName->z, pTableName->n, 0);
goto trigger_cleanup; goto trigger_cleanup;
} }
if( sqliteAuthInsert(pParse, SCHEMA_TABLE(tab->isTemp), 1) ){ #ifndef SQLITE_OMIT_AUTHORIZATION
goto trigger_cleanup; {
int code = SQLITE_CREATE_TRIGGER;
if( tab->isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
goto trigger_cleanup;
}
} }
#endif
} }
if (tr_tm == TK_INSTEAD){ if (tr_tm == TK_INSTEAD){
@ -116,7 +117,8 @@ void sqliteCreateTrigger(
/* Build the Trigger object */ /* Build the Trigger object */
nt = (Trigger*)sqliteMalloc(sizeof(Trigger)); nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
if( nt==0 ) goto trigger_cleanup; if( nt==0 ) goto trigger_cleanup;
nt->name = sqliteStrNDup(pName->z, pName->n); nt->name = zName;
zName = 0;
nt->table = sqliteStrNDup(pTableName->z, pTableName->n); nt->table = sqliteStrNDup(pTableName->z, pTableName->n);
if( sqlite_malloc_failed ) goto trigger_cleanup; if( sqlite_malloc_failed ) goto trigger_cleanup;
nt->op = op; nt->op = op;
@ -179,6 +181,7 @@ void sqliteCreateTrigger(
trigger_cleanup: trigger_cleanup:
sqliteFree(zName);
sqliteIdListDelete(pColumns); sqliteIdListDelete(pColumns);
sqliteExprDelete(pWhen); sqliteExprDelete(pWhen);
sqliteDeleteTriggerStep(pStepList); sqliteDeleteTriggerStep(pStepList);
@ -342,7 +345,6 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
Table *pTable; Table *pTable;
Vdbe *v; Vdbe *v;
if( sqliteAuthCommand(pParse, "DROP", "TRIGGER") ) return;
zName = sqliteStrNDup(pName->z, pName->n); zName = sqliteStrNDup(pName->z, pName->n);
/* ensure that the trigger being dropped exists */ /* ensure that the trigger being dropped exists */
@ -355,11 +357,17 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
} }
pTable = sqliteFindTable(pParse->db, pTrigger->table); pTable = sqliteFindTable(pParse->db, pTrigger->table);
assert(pTable); assert(pTable);
if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pTable->isTemp), 1) ){ #ifndef SQLITE_OMIT_AUTHORIZATION
sqliteFree(zName); {
return; int code = SQLITE_DROP_TRIGGER;
if( pTable->isTemp ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName) ||
sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->isTemp),0) ){
sqliteFree(zName);
return;
}
} }
#endif
/* /*
* If this is not an "explain", then delete the trigger structure. * If this is not an "explain", then delete the trigger structure.

View File

@ -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.52 2003/01/12 18:02:19 drh Exp $ ** $Id: update.c,v 1.53 2003/01/13 23:27:33 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -53,7 +53,6 @@ void sqliteUpdate(
int oldIdx = -1; /* index of trigger "old" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */
if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup; if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
if( sqliteAuthCommand(pParse, "UPDATE", 0) ) goto update_cleanup;
db = pParse->db; db = pParse->db;
/* Check for the special case of a VIEW with one or more ON UPDATE triggers /* Check for the special case of a VIEW with one or more ON UPDATE triggers
@ -148,8 +147,15 @@ void sqliteUpdate(
goto update_cleanup; goto update_cleanup;
} }
#ifndef SQLITE_OMIT_AUTHORIZATION #ifndef SQLITE_OMIT_AUTHORIZATION
if( sqliteAuthWrite(pParse, pTab, j)==SQLITE_IGNORE ){ {
aXRef[j] = -1; int rc;
rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
pTab->aCol[j].zName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
aXRef[j] = -1;
}
} }
#endif #endif
} }

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this script testing the sqlite_set_authorizer() API. # focus of this script testing the sqlite_set_authorizer() API.
# #
# $Id: auth.test,v 1.1 2003/01/12 19:33:54 drh Exp $ # $Id: auth.test,v 1.2 2003/01/13 23:27:34 drh Exp $
# #
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@ -23,7 +23,7 @@ do_test auth-1.1 {
db close db close
set ::DB [sqlite db test.db] set ::DB [sqlite db test.db]
proc auth {code arg1 arg2} { proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW" if {$code=="SQLITE_INSERT"
&& [string compare -nocase $arg1 sqlite_master]==0} { && [string compare -nocase $arg1 sqlite_master]==0} {
return SQLITE_DENY return SQLITE_DENY
} }
@ -31,244 +31,128 @@ do_test auth-1.1 {
} }
sqlite_set_authorizer $::DB ::auth sqlite_set_authorizer $::DB ::auth
catchsql {CREATE TABLE t1(a,b,c)} catchsql {CREATE TABLE t1(a,b,c)}
} {1 {insertion into table sqlite_master is prohibited}} } {1 {not authorized}}
do_test auth-1.2 { do_test auth-1.2 {
execsql {SELECT name FROM sqlite_master}
} {}
do_test auth-1.3 {
proc auth {code arg1 arg2} { proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW" if {$code=="SQLITE_CREATE_TABLE"} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {CREATE TABLE t1(a,b,c)}
} {1 {not authorized}}
do_test auth-1.4 {
execsql {SELECT name FROM sqlite_master}
} {}
do_test auth-1.5 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT"
&& [string compare -nocase $arg1 sqlite_temp_master]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {1 {not authorized}}
do_test auth-1.6 {
execsql {SELECT name FROM sqlite_temp_master}
} {}
do_test auth-1.7 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {1 {not authorized}}
do_test auth-1.8 {
execsql {SELECT name FROM sqlite_temp_master}
} {}
do_test auth-1.9 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT"
&& [string compare -nocase $arg1 sqlite_master]==0} { && [string compare -nocase $arg1 sqlite_master]==0} {
return SQLITE_IGNORE return SQLITE_IGNORE
} }
return SQLITE_OK return SQLITE_OK
} }
catchsql {CREATE TABLE t1(a,b,c)} catchsql {CREATE TABLE t1(a,b,c)}
} {1 {insertion into table sqlite_master is prohibited}} } {0 {}}
do_test auth-1.3 { do_test auth-1.10 {
execsql {SELECT name FROM sqlite_master}
} {}
do_test auth-1.11 {
proc auth {code arg1 arg2} { proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW" if {$code=="SQLITE_CREATE_TABLE"} {
&& [string compare -nocase $arg1 sqlite_master]==0} { return SQLITE_IGNORE
return SQLITE_OK
} }
return SQLITE_OK return SQLITE_OK
} }
catchsql {CREATE TABLE t1(a,b,c)} catchsql {CREATE TABLE t1(a,b,c)}
} {0 {}} } {0 {}}
do_test auth-1.4 { do_test auth-1.12 {
execsql {SELECT name FROM sqlite_master} execsql {SELECT name FROM sqlite_master}
} {t1} } {}
do_test auth-1.5 { do_test auth-1.13 {
proc auth {code arg1 arg2} { proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW" if {$code=="SQLITE_INSERT"
&& [string compare -nocase $arg1 sqlite_master]==0} { && [string compare -nocase $arg1 sqlite_temp_master]==0} {
return BOGUS return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.14 {
execsql {SELECT name FROM sqlite_temp_master}
} {}
do_test auth-1.15 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.16 {
execsql {SELECT name FROM sqlite_temp_master}
} {}
do_test auth-1.17 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_CREATE_TABLE"} {
return SQLITE_DEBY
}
return SQLITE_OK
}
catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.18 {
execsql {SELECT name FROM sqlite_temp_master}
} {t1}
do_test auth-1.19 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
return SQLITE_DEBY
} }
return SQLITE_OK return SQLITE_OK
} }
catchsql {CREATE TABLE t2(a,b,c)} catchsql {CREATE TABLE t2(a,b,c)}
} {1 {illegal return value (1) from the authorization function - should be SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY}}
do_test auth-1.6 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_DELETE_ROW"
&& [string compare -nocase $arg1 sqlite_master]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {DROP TABLE t1}
} {1 {deletion from table sqlite_master is prohibited}}
do_test auth-1.7 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_DELETE_ROW"
&& [string compare -nocase $arg1 sqlite_master]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {DROP TABLE t1}
} {1 {deletion from table sqlite_master is prohibited}}
do_test auth-1.8 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW"
&& [string compare -nocase $arg1 t1]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {INSERT INTO t1 VALUES(1,2,3)}
} {1 {insertion into table t1 is prohibited}}
do_test auth-1.9 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW"
&& [string compare -nocase $arg1 t1]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {INSERT INTO t1 VALUES(1,2,3)}
} {0 {}} } {0 {}}
do_test auth-1.10 {
execsql {SELECT * FROM t1}
} {}
do_test auth-1.11 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_INSERT_ROW"
&& [string compare -nocase $arg1 t1]==0} {
return SQLITE_OK
}
return SQLITE_OK
}
catchsql {INSERT INTO t1 VALUES(1,2,3)}
} {0 {}}
do_test auth-1.12 {
execsql {SELECT * FROM t1}
} {1 2 3}
do_test auth-1.13 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_DELETE_ROW"
&& [string compare -nocase $arg1 t1]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {DELETE FROM t1 WHERE a=1}
} {1 {deletion from table t1 is prohibited}}
do_test auth-1.14 {
execsql {SELECT * FROM t1}
} {1 2 3}
do_test auth-1.15 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_DELETE_ROW"
&& [string compare -nocase $arg1 t1]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {DELETE FROM t1 WHERE a=1}
} {0 {}}
do_test auth-1.16 {
execsql {SELECT * FROM t1}
} {1 2 3}
do_test auth-1.17 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_READ_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {SELECT * FROM t1}
} {1 {access to t1.a is prohibited}}
do_test auth-1.18 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_READ_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {SELECT * FROM t1}
} {0 {{} 2 3}}
do_test auth-1.19 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_WRITE_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET a=11 WHERE a=1}
} {1 {changes to t1.a are prohibited}}
do_test auth-1.20 { do_test auth-1.20 {
execsql {SELECT * FROM t1} execsql {SELECT name FROM sqlite_master}
} {1 2 3} } {t2}
do_test auth-1.21 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_WRITE_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET b=12 WHERE a=1}
} {0 {}}
do_test auth-1.22 {
execsql {SELECT * FROM t1}
} {1 12 3}
do_test auth-1.23 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_WRITE_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET a=11, b=22 WHERE a=1}
} {0 {}}
do_test auth-1.24 {
execsql {SELECT * FROM t1}
} {1 22 3}
do_test auth-1.25 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_WRITE_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET a=11, b=33 WHERE a=1}
} {1 {changes to t1.a are prohibited}}
do_test auth-1.26 {
execsql {SELECT * FROM t1}
} {1 22 3}
do_test auth-1.27 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_READ_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET b=33, c=44 WHERE a=1}
} {1 {access to t1.a is prohibited}}
do_test auth-1.28 {
execsql {SELECT b, c FROM t1}
} {22 3}
do_test auth-1.29 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_READ_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET b=33, c=44 WHERE a=1}
} {0 {}}
do_test auth-1.30 {
execsql {SELECT b, c FROM t1}
} {22 3}
do_test auth-1.31 {
proc auth {code arg1 arg2} {
if {$code=="SQLITE_READ_COLUMN"
&& [string compare -nocase $arg1 t1]==0
&& [string compare -nocase $arg2 a]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
catchsql {UPDATE t1 SET b=33, c=44 WHERE a IS NULL}
} {0 {}}
do_test auth-1.32 {
execsql {SELECT b, c FROM t1}
} {33 44}
} ;# End of the "if( db command exists )" } ;# End of the "if( db command exists )"
finish_test finish_test