diff --git a/manifest b/manifest index 2531ee9a39..22c161506c 100644 --- a/manifest +++ b/manifest @@ -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) -D 2003-01-12T19:33:53 +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-13T23:27:32 F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -18,46 +18,46 @@ F main.mk 8b10c5df8a21cdd343986a90c75247bafaebb3aa F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea -F src/auth.c de3c70e5eab92ef5c1af87dae626022b8f46a6fd +F src/auth.c 9c2db0bc7707f2d2e227f47e3d557b41d44ade75 F src/btree.c 131b5903f66e148f0f9af0cedd1c6654932c4e04 F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda -F src/build.c 3136d7fc765cc2feee2ad987bac1c1696fdc0f0e -F src/delete.c bc807a756dde6aa16db38f6e05a90408053d2f2c +F src/build.c 94cd4ed1724b3e7304387b2caece75aff39d7f6e +F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c F src/encode.c 09d1fe8a2e97ff94cce496e2909e2ebc8947960b F src/expr.c d8b319f25335443a415a639aec8e0edc64e3ab6c F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 -F src/insert.c d19a73907ade1f2801bf8c3cb68538e8b1a05b5f +F src/insert.c db954e955970795819145a3649fd2ad116a58890 F src/main.c c8f8fdfe4548a8404fab90ff6ad374b217e6b7fa F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/os.c 28447687e7914306650f72058f62f7162faeef1f F src/os.h afa3e096213bad86845f8bdca81a9e917505e401 F src/pager.c 5b81639b38eb4250810ed2b31aada9fb040ed86b F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626 -F src/parse.y 427a17888c117cc9cc35311eda0603d55437f02b +F src/parse.y 58655a50817f93ddd0bc3d8949e267729396949c F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe -F src/select.c 1b7d20b659621bf8621dec710e9680b4c380563c +F src/select.c 5ce75c1381d8ec3b89ea4d7eb5171bc57785e610 F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e -F src/sqlite.h.in 7b35872afdba0d46890773470a12aa71d78f6d21 -F src/sqliteInt.h 01b59d2ecbd36b7ec750339bbd9401c012b463c2 +F src/sqlite.h.in 9974a66d4caa4880fe44ebdc306f5f94c6a4d9c0 +F src/sqliteInt.h bc986d4fc3d8285cec370eb5e305d5499f422a31 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64 -F src/test1.c 2a0e5cf7e66cbbb46d9f0c97ea8f406141e8b263 +F src/test1.c 921e5dda494f836d2ebea703bd5b239a7cc963d0 F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728 F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/tokenize.c 7ac1c33e0149647c9eb5959c48992df6906d4809 -F src/trigger.c dd3fb6595643e29b71d6f3ecb22afb930224633c -F src/update.c 9f2e9105c697b11b06b381910d0e429718f01cc3 +F src/trigger.c cb72a3374b21ed00a6dbd3c2c5aa27a7fa72625f +F src/update.c f06afa9bf1f777d17702e0f6e33cf44c44bc4f75 F src/util.c 354336da4a6f1c98f687a13db0c45ed9314a892b F src/vdbe.c e103bd5a154b1790dd344662dceb14566a51a879 F src/vdbe.h 754eba497cfe0c3e352b9c101ab2f811f10d0a55 F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18 F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029 -F test/auth.test 1e8e443bc8d5c4ea44176ce6d9de4157582475aa +F test/auth.test c0b3210b109f9cdde2a19c7af603a3f6c763dcf8 F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/btree.test 10e75aec120ecefc0edc4c912a0980a43db1b6c2 @@ -154,7 +154,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 7601916419489879fe963c83010b452c49ef063f -R bf3593b345d77cb3f65a7094575c0db9 +P 5707b3d56efb6e988f816abefb1836f2f3254117 +R 185c96485c9e323ed508e05878c2e1fd U drh -Z 10949dc2e6e230f66d8a085db700df05 +Z ce7138319a0232b300fa79474bc44207 diff --git a/manifest.uuid b/manifest.uuid index b1cd83be48..2c2ecf584c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5707b3d56efb6e988f816abefb1836f2f3254117 \ No newline at end of file +45de93f913a18026a45de6254963dbcd1b0f1a19 \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 8303e7a81a..ca5af14ba8 100644 --- a/src/auth.c +++ b/src/auth.c @@ -14,7 +14,7 @@ ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.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" @@ -106,7 +106,7 @@ void sqliteAuthRead( }else{ 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 ){ pExpr->op = TK_NULL; }else if( rc==SQLITE_DENY ){ @@ -119,22 +119,25 @@ void sqliteAuthRead( } /* -** Check the user-supplied authorization function to see if it is ok to -** delete 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. +** Do an authorization check using the code and arguments given. Return +** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY +** is returned, then the error count and error message in pParse are +** modified appropriately. */ -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; int rc; if( db->xAuth==0 ){ return SQLITE_OK; } - rc = db->xAuth(db->pAuthArg, SQLITE_DELETE_ROW, zName, ""); - if( rc==SQLITE_DENY || (rc==SQLITE_IGNORE && forceError) ){ - sqliteSetString(&pParse->zErrMsg,"deletion from table ", - zName, " is prohibited", 0); + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2); + if( rc==SQLITE_DENY ){ + sqliteSetString(&pParse->zErrMsg, "not authorized", 0); pParse->nErr++; }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ rc = SQLITE_DENY; @@ -143,73 +146,4 @@ int sqliteAuthDelete(Parse *pParse, const char *zName, int forceError){ 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 */ diff --git a/src/build.c b/src/build.c index b137552156..9b9cfaa42b 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** 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 @@ -315,7 +315,13 @@ void sqliteOpenMasterTable(Vdbe *v, int isTemp){ ** At the end of the CREATE TABLE statement, the sqliteEndTable() routine ** 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; Index *pIdx; char *zName; @@ -325,9 +331,31 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){ pParse->sFirstToken = *pStart; zName = sqliteTableNameFromToken(pName); 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; } + { + 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 ** holding temporary tables is open. @@ -895,7 +923,7 @@ void sqliteCreateView( const char *z; Token sEnd; - sqliteStartTable(pParse, pBegin, pName, isTemp); + sqliteStartTable(pParse, pBegin, pName, isTemp, 1); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqliteSelectDelete(pSelect); @@ -1072,9 +1100,30 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){ if( pParse->nErr || sqlite_malloc_failed ) return; pTable = sqliteTableFromToken(pParse, pName); 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; } + { + 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 ){ sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName, " may not be dropped", 0); @@ -1093,9 +1142,6 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){ pParse->nErr++; return; } - if( sqliteAuthDelete(pParse, pTable->zName, 1) ){ - return; - } /* Generate code to remove the table from the master table ** on disk. @@ -1374,9 +1420,6 @@ void sqliteCreateIndex( pParse->nErr++; 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 ** but the table associated with this index is a temporary table, it can @@ -1441,6 +1484,19 @@ void sqliteCreateIndex( 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 ** key out of the last column added to the table under construction. ** So create a fake list to simulate this. @@ -1638,9 +1694,19 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ pParse->nErr++; return; } - if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pIndex->pTable->isTemp), 1) ){ - return; +#ifndef SQLITE_OMIT_AUTHORIZATION + { + 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 */ v = sqliteGetVdbe(pParse); @@ -1837,10 +1903,8 @@ void sqliteCopy( pTab = sqliteTableNameToTable(pParse, zTab); sqliteFree(zTab); if( pTab==0 ) goto copy_cleanup; - if( sqliteAuthInsert(pParse, zTab, 0) ){ - goto copy_cleanup; - } - if( sqliteAuthCommand(pParse, "COPY", zTab) ){ + if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) + || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, 0) ){ goto copy_cleanup; } 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->nErr || sqlite_malloc_failed ) return; - if( sqliteAuthCommand(pParse, "BEGIN", "") ) return; + if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0) ) return; if( db->flags & SQLITE_InTrans ){ pParse->nErr++; 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->nErr || sqlite_malloc_failed ) return; - if( sqliteAuthCommand(pParse, "COMMIT", "") ) return; + if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0) ) return; if( (db->flags & SQLITE_InTrans)==0 ){ pParse->nErr++; sqliteSetString(&pParse->zErrMsg, @@ -1966,7 +2030,7 @@ void sqliteRollbackTransaction(Parse *pParse){ if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) 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 ){ pParse->nErr++; sqliteSetString(&pParse->zErrMsg, @@ -2075,7 +2139,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ zRight = sqliteStrNDup(pRight->z, pRight->n); sqliteDequote(zRight); } - if( sqliteAuthCommand(pParse, "PRAGMA", zLeft) ) return; + if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight) ) return; /* ** PRAGMA default_cache_size diff --git a/src/delete.c b/src/delete.c index 5c5582433d..65e5075b49 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.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" @@ -88,8 +88,7 @@ void sqliteDeleteFrom( int row_triggers_exist = 0; int oldIdx = -1; - if( pParse->nErr || sqlite_malloc_failed - || sqliteAuthCommand(pParse,"DELETE",0) ){ + if( pParse->nErr || sqlite_malloc_failed ){ pTabList = 0; goto delete_from_cleanup; } @@ -126,7 +125,9 @@ void sqliteDeleteFrom( assert( pTabList->nSrc==1 ); pTab = pTabList->a[0].pTab; 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. */ diff --git a/src/insert.c b/src/insert.c index 888f129098..93a073b501 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** 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" @@ -114,7 +114,6 @@ void sqliteInsert( int newIdx = -1; if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; - if( sqliteAuthCommand(pParse, "INSERT", 0) ) goto insert_cleanup; db = pParse->db; /* Locate the table into which we will be inserting new information. @@ -127,7 +126,7 @@ void sqliteInsert( pParse->nErr++; goto insert_cleanup; } - if( sqliteAuthInsert(pParse, zTab, 0) ){ + if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){ goto insert_cleanup; } diff --git a/src/parse.y b/src/parse.y index 1df236b0d6..73732005b6 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** 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_type {Token} @@ -85,7 +85,7 @@ cmd ::= ROLLBACK trans_opt. {sqliteRollbackTransaction(pParse);} // cmd ::= create_table create_table_args. create_table ::= CREATE(X) temp(T) TABLE nm(Y). { - sqliteStartTable(pParse,&X,&Y,T); + sqliteStartTable(pParse,&X,&Y,T,0); } %type temp {int} temp(A) ::= TEMP. {A = pParse->isTemp || !pParse->initFlag;} diff --git a/src/select.c b/src/select.c index fe90eccc5a..c989bde83b 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** 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" @@ -1781,7 +1781,7 @@ int sqliteSelect( int rc = 1; /* Value to return from this function */ 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. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 985f255a57..c31eb9faf4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** 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_ #define _SQLITE_H_ @@ -509,18 +509,42 @@ int sqlite_aggregate_count(sqlite_func*); int sqlite_set_authorizer( sqlite*, int (*xAuth)(void*,int,const char*,const char*), - void* + void *pUserData ); /* ** 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_WRITE_COLUMN 2 /* Is it OK to update the specified column? */ -#define SQLITE_DELETE_ROW 3 /* Is it OK to delete a row from the table? */ -#define SQLITE_INSERT_ROW 4 /* Is it OK to insert a new row in the table? */ -#define SQLITE_COMMAND 5 /* Is it OK to execute a particular command? */ +#define SQLITE_COPY 0 /* Table Name NULL */ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#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 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b757a8320a..38ae75c05a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** 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 "sqlite.h" @@ -938,7 +938,7 @@ void sqliteRollbackInternalChanges(sqlite*); void sqliteCommitInternalChanges(sqlite*); Table *sqliteResultSetOfSelect(Parse*,char*,Select*); void sqliteOpenMasterTable(Vdbe *v, int); -void sqliteStartTable(Parse*,Token*,Token*,int); +void sqliteStartTable(Parse*,Token*,Token*,int,int); void sqliteAddColumn(Parse*,Token*); void sqliteAddNotNull(Parse*, int); void sqliteAddPrimaryKey(Parse*, IdList*, int); @@ -1035,13 +1035,8 @@ void sqliteCreateForeignKey(Parse*, IdList*, Token*, IdList*, int); void sqliteDeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION void sqliteAuthRead(Parse*,Expr*,SrcList*,int); - int sqliteAuthDelete(Parse*,const char*, int); - int sqliteAuthInsert(Parse*,const char*, int); - int sqliteAuthCommand(Parse*,const char*,const char*); + int sqliteAuthCheck(Parse*,int, const char*, const char*); #else # define sqliteAuthRead(a,b,c,d) -# define sqliteAuthDelete(a,b,c) SQLITE_OK -# define sqliteAuthInsert(a,b,c) SQLITE_OK -# define sqliteAuthWrite(a,b,c) SQLITE_OK -# define sqliteAuthCommand(a,b,c) SQLITE_OK +# define sqliteAuthCheck(a,b,c,d) SQLITE_OK #endif diff --git a/src/test1.c b/src/test1.c index 92f186ef6c..a518e5bddc 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** 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 "tcl.h" @@ -595,17 +595,36 @@ static int auth_callback( int rc; const char *zReply; switch( code ){ - case SQLITE_READ_COLUMN: zCode="SQLITE_READ_COLUMN"; break; - case SQLITE_WRITE_COLUMN: zCode="SQLITE_WRITE_COLUMN"; break; - case SQLITE_INSERT_ROW: zCode="SQLITE_INSERT_ROW"; break; - case SQLITE_DELETE_ROW: zCode="SQLITE_DELETE_ROW"; break; - case SQLITE_COMMAND: zCode="SQLITE_COMMAND"; break; - default: zCode="unknown code"; break; + 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); + Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); rc = Tcl_GlobalEval(authInfo.interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); diff --git a/src/trigger.c b/src/trigger.c index 079a4c2f85..ce00c2b057 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -49,8 +49,7 @@ void sqliteCreateTrigger( ){ Trigger *nt; Table *tab; - - if( sqliteAuthCommand(pParse, "CREATE", "TRIGGER") ) goto trigger_cleanup; + char *zName = 0; /* Name of the trigger */ /* Check that: ** 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. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. */ - { - char *tmp_str = sqliteStrNDup(pName->z, pName->n); - if( sqliteHashFind(&(pParse->db->trigHash), tmp_str, pName->n + 1) ){ - sqliteSetNString(&pParse->zErrMsg, "trigger ", -1, - pName->z, pName->n, " already exists", -1, 0); - sqliteFree(tmp_str); - pParse->nErr++; - goto trigger_cleanup; - } - sqliteFree(tmp_str); + zName = sqliteStrNDup(pName->z, pName->n); + if( sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1) ){ + sqliteSetNString(&pParse->zErrMsg, "trigger ", -1, + pName->z, pName->n, " already exists", -1, 0); + pParse->nErr++; + goto trigger_cleanup; } { char *tmp_str = sqliteStrNDup(pTableName->z, pTableName->n); @@ -104,9 +99,15 @@ void sqliteCreateTrigger( " trigger on table: ", -1, pTableName->z, pTableName->n, 0); goto trigger_cleanup; } - if( sqliteAuthInsert(pParse, SCHEMA_TABLE(tab->isTemp), 1) ){ - goto trigger_cleanup; +#ifndef SQLITE_OMIT_AUTHORIZATION + { + 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){ @@ -116,7 +117,8 @@ void sqliteCreateTrigger( /* Build the Trigger object */ nt = (Trigger*)sqliteMalloc(sizeof(Trigger)); 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); if( sqlite_malloc_failed ) goto trigger_cleanup; nt->op = op; @@ -179,6 +181,7 @@ void sqliteCreateTrigger( trigger_cleanup: + sqliteFree(zName); sqliteIdListDelete(pColumns); sqliteExprDelete(pWhen); sqliteDeleteTriggerStep(pStepList); @@ -342,7 +345,6 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){ Table *pTable; Vdbe *v; - if( sqliteAuthCommand(pParse, "DROP", "TRIGGER") ) return; zName = sqliteStrNDup(pName->z, pName->n); /* 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); assert(pTable); - if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pTable->isTemp), 1) ){ - sqliteFree(zName); - return; +#ifndef SQLITE_OMIT_AUTHORIZATION + { + 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. diff --git a/src/update.c b/src/update.c index 7ddecaca1f..fccd86343d 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.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" @@ -53,7 +53,6 @@ void sqliteUpdate( int oldIdx = -1; /* index of trigger "old" temp table */ if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup; - if( sqliteAuthCommand(pParse, "UPDATE", 0) ) goto update_cleanup; db = pParse->db; /* Check for the special case of a VIEW with one or more ON UPDATE triggers @@ -148,8 +147,15 @@ void sqliteUpdate( goto update_cleanup; } #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 } diff --git a/test/auth.test b/test/auth.test index 2ba7fdf329..25eee7f557 100644 --- a/test/auth.test +++ b/test/auth.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # 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] @@ -23,7 +23,7 @@ do_test auth-1.1 { db close set ::DB [sqlite db test.db] proc auth {code arg1 arg2} { - if {$code=="SQLITE_INSERT_ROW" + if {$code=="SQLITE_INSERT" && [string compare -nocase $arg1 sqlite_master]==0} { return SQLITE_DENY } @@ -31,244 +31,128 @@ do_test auth-1.1 { } sqlite_set_authorizer $::DB ::auth catchsql {CREATE TABLE t1(a,b,c)} -} {1 {insertion into table sqlite_master is prohibited}} +} {1 {not authorized}} do_test auth-1.2 { + execsql {SELECT name FROM sqlite_master} +} {} +do_test auth-1.3 { 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} { return SQLITE_IGNORE } return SQLITE_OK } catchsql {CREATE TABLE t1(a,b,c)} -} {1 {insertion into table sqlite_master is prohibited}} -do_test auth-1.3 { +} {0 {}} +do_test auth-1.10 { + execsql {SELECT name FROM sqlite_master} +} {} +do_test auth-1.11 { proc auth {code arg1 arg2} { - if {$code=="SQLITE_INSERT_ROW" - && [string compare -nocase $arg1 sqlite_master]==0} { - return SQLITE_OK + if {$code=="SQLITE_CREATE_TABLE"} { + return SQLITE_IGNORE } return SQLITE_OK } catchsql {CREATE TABLE t1(a,b,c)} } {0 {}} -do_test auth-1.4 { +do_test auth-1.12 { execsql {SELECT name FROM sqlite_master} -} {t1} -do_test auth-1.5 { +} {} +do_test auth-1.13 { proc auth {code arg1 arg2} { - if {$code=="SQLITE_INSERT_ROW" - && [string compare -nocase $arg1 sqlite_master]==0} { - return BOGUS + if {$code=="SQLITE_INSERT" + && [string compare -nocase $arg1 sqlite_temp_master]==0} { + 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 } 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 {}} -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 { - execsql {SELECT * FROM t1} -} {1 2 3} -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} + execsql {SELECT name FROM sqlite_master} +} {t2} + + + - } ;# End of the "if( db command exists )" finish_test