aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/auth.c96
-rw-r--r--src/build.c106
-rw-r--r--src/delete.c9
-rw-r--r--src/insert.c5
-rw-r--r--src/parse.y4
-rw-r--r--src/select.c4
-rw-r--r--src/sqlite.h.in42
-rw-r--r--src/sqliteInt.h13
-rw-r--r--src/test1.c35
-rw-r--r--src/trigger.c48
-rw-r--r--src/update.c14
11 files changed, 213 insertions, 163 deletions
diff --git a/src/auth.c b/src/auth.c
index 8303e7a81..ca5af14ba 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,94 +119,28 @@ 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){
- 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;
diff --git a/src/build.c b/src/build.c
index b13755215..9b9cfaa42 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 <ctype.h>
@@ -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 5c5582433..65e5075b4 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 888f12909..93a073b50 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 1df236b0d..73732005b 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 fe90eccc5..c989bde83 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 985f255a5..c31eb9faf 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:
-*/
-#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
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b757a8320..38ae75c05 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 92f186ef6..a518e5bdd 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 079a4c2f8..ce00c2b05 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 7ddecaca1..fccd86343 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
}