-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
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
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
-5707b3d56efb6e988f816abefb1836f2f3254117
\ No newline at end of file
+45de93f913a18026a45de6254963dbcd1b0f1a19
\ No newline at end of file
** 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"
}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 ){
}
/*
-** 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){
- 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);
- pParse->nErr++;
- }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
- rc = SQLITE_DENY;
- sqliteAuthBadReturnCode(pParse, 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){
+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_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);
+ rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2);
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);
- }
+ sqliteSetString(&pParse->zErrMsg, "not authorized", 0);
pParse->nErr++;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
+ rc = SQLITE_DENY;
sqliteAuthBadReturnCode(pParse, rc);
}
return rc;
** 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 <ctype.h>
** 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;
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.
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);
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);
pParse->nErr++;
return;
}
- if( sqliteAuthDelete(pParse, pTable->zName, 1) ){
- return;
- }
/* Generate code to remove the table from the master table
** on disk.
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
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.
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);
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);
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 "
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,
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,
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
** 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"
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;
}
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.
*/
** 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"
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.
pParse->nErr++;
goto insert_cleanup;
}
- if( sqliteAuthInsert(pParse, zTab, 0) ){
+ if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){
goto insert_cleanup;
}
** 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}
//
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;}
** 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"
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.
*/
** 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_
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:
-*/
-#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? */
+** 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_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
*************************************************************************
** 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"
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);
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
** 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"
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);
){
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.
** 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);
" 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){
/* 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;
trigger_cleanup:
+ sqliteFree(zName);
sqliteIdListDelete(pColumns);
sqliteExprDelete(pWhen);
sqliteDeleteTriggerStep(pStepList);
Table *pTable;
Vdbe *v;
- if( sqliteAuthCommand(pParse, "DROP", "TRIGGER") ) return;
zName = sqliteStrNDup(pName->z, pName->n);
/* ensure that the trigger being dropped exists */
}
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.
** 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"
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
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
}
# 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]
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
}
}
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 {
- proc auth {code arg1 arg2} {
- if {$code=="SQLITE_INSERT_ROW"
- && [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}}
+ execsql {SELECT name FROM sqlite_master}
+} {}
do_test auth-1.3 {
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_DENY
}
return SQLITE_OK
}
catchsql {CREATE TABLE t1(a,b,c)}
-} {0 {}}
+} {1 {not authorized}}
do_test auth-1.4 {
execsql {SELECT name FROM sqlite_master}
-} {t1}
+} {}
+
do_test auth-1.5 {
proc auth {code arg1 arg2} {
- if {$code=="SQLITE_INSERT_ROW"
- && [string compare -nocase $arg1 sqlite_master]==0} {
- return BOGUS
- }
- 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} {
+ if {$code=="SQLITE_INSERT"
+ && [string compare -nocase $arg1 sqlite_temp_master]==0} {
return SQLITE_DENY
}
return SQLITE_OK
}
- catchsql {DROP TABLE t1}
-} {1 {deletion from table sqlite_master is prohibited}}
+ 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_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} {
+ if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
return SQLITE_DENY
}
return SQLITE_OK
}
- catchsql {INSERT INTO t1 VALUES(1,2,3)}
-} {1 {insertion into table t1 is prohibited}}
+ 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_ROW"
- && [string compare -nocase $arg1 t1]==0} {
+ if {$code=="SQLITE_INSERT"
+ && [string compare -nocase $arg1 sqlite_master]==0} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
- catchsql {INSERT INTO t1 VALUES(1,2,3)}
+ catchsql {CREATE TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.10 {
- execsql {SELECT * FROM t1}
+ 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 t1]==0} {
- return SQLITE_OK
+ if {$code=="SQLITE_CREATE_TABLE"} {
+ return SQLITE_IGNORE
}
return SQLITE_OK
}
- catchsql {INSERT INTO t1 VALUES(1,2,3)}
+ catchsql {CREATE TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.12 {
- execsql {SELECT * FROM t1}
-} {1 2 3}
+ execsql {SELECT name FROM sqlite_master}
+} {}
do_test auth-1.13 {
proc auth {code arg1 arg2} {
- if {$code=="SQLITE_DELETE_ROW"
- && [string compare -nocase $arg1 t1]==0} {
- return SQLITE_DENY
+ if {$code=="SQLITE_INSERT"
+ && [string compare -nocase $arg1 sqlite_temp_master]==0} {
+ return SQLITE_IGNORE
}
return SQLITE_OK
}
- catchsql {DELETE FROM t1 WHERE a=1}
-} {1 {deletion from table t1 is prohibited}}
+ catchsql {CREATE TEMP TABLE t1(a,b,c)}
+} {0 {}}
do_test auth-1.14 {
- execsql {SELECT * FROM t1}
-} {1 2 3}
+ execsql {SELECT name FROM sqlite_temp_master}
+} {}
do_test auth-1.15 {
proc auth {code arg1 arg2} {
- if {$code=="SQLITE_DELETE_ROW"
- && [string compare -nocase $arg1 t1]==0} {
+ if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
return SQLITE_IGNORE
}
return SQLITE_OK
}
- catchsql {DELETE FROM t1 WHERE a=1}
+ catchsql {CREATE TEMP TABLE t1(a,b,c)}
} {0 {}}
do_test auth-1.16 {
- execsql {SELECT * FROM t1}
-} {1 2 3}
+ execsql {SELECT name FROM sqlite_temp_master}
+} {}
+
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
+ if {$code=="SQLITE_CREATE_TABLE"} {
+ return SQLITE_DEBY
}
return SQLITE_OK
}
- catchsql {SELECT * FROM t1}
-} {1 {access to t1.a is prohibited}}
+ catchsql {CREATE TEMP TABLE t1(a,b,c)}
+} {0 {}}
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}}
+ execsql {SELECT name FROM sqlite_temp_master}
+} {t1}
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
+ if {$code=="SQLITE_CREATE_TEMP_TABLE"} {
+ return SQLITE_DEBY
}
return SQLITE_OK
}
- catchsql {UPDATE t1 SET b=33, c=44 WHERE a IS NULL}
+ catchsql {CREATE TABLE t2(a,b,c)}
} {0 {}}
-do_test auth-1.32 {
- execsql {SELECT b, c FROM t1}
-} {33 44}
+do_test auth-1.20 {
+ execsql {SELECT name FROM sqlite_master}
+} {t2}
+
+
+
-
} ;# End of the "if( db command exists )"
finish_test