]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Initial check-in of the code for the new sqlite_set_authorizer() API function.
authordrh <drh@noemail.net>
Sun, 12 Jan 2003 18:02:16 +0000 (18:02 +0000)
committerdrh <drh@noemail.net>
Sun, 12 Jan 2003 18:02:16 +0000 (18:02 +0000)
The code is mostly untested at this point. (CVS 827)

FossilOrigin-Name: 52d5007f64d0af5286b2a0e1f0b9e53c86bece3f

17 files changed:
Makefile.in
main.mk
manifest
manifest.uuid
src/build.c
src/delete.c
src/expr.c
src/insert.c
src/main.c
src/pager.c
src/select.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/trigger.c
src/update.c
src/util.c

index d7e0ed6036017153840a01e869247f130ed0b9b0..c05220bc3716784d8274efee75ee1b8f60534da4 100644 (file)
@@ -62,7 +62,7 @@ ENCODING = @ENCODING@
 
 # Object files for the SQLite library.
 #
-LIBOBJ = btree.lo build.lo delete.lo expr.lo func.lo hash.lo insert.lo \
+LIBOBJ = auth.lo btree.lo build.lo delete.lo expr.lo func.lo hash.lo insert.lo \
          main.lo opcodes.lo os.lo pager.lo parse.lo printf.lo random.lo \
          select.lo table.lo tokenize.lo update.lo util.lo vdbe.lo \
          where.lo trigger.lo
@@ -70,6 +70,7 @@ LIBOBJ = btree.lo build.lo delete.lo expr.lo func.lo hash.lo insert.lo \
 # All of the source code files.
 #
 SRC = \
+  $(TOP)/src/auth.c \
   $(TOP)/src/btree.c \
   $(TOP)/src/btree.h \
   $(TOP)/src/build.c \
@@ -275,6 +276,9 @@ tclsqlite.lo:       $(TOP)/src/tclsqlite.c $(HDR)
 printf.lo:     $(TOP)/src/printf.c $(HDR)
        $(LIBTOOL) $(TCC) $(TCL_FLAGS) -c $(TOP)/src/printf.c
 
+auth.lo:       $(TOP)/src/auth.c $(HDR)
+       $(LIBTOOL) $(TCC) $(TCL_FLAGS) -c $(TOP)/src/auth.c
+
 tclsqlite:     $(TOP)/src/tclsqlite.c libsqlite.la
        $(LIBTOOL) $(TCC) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite \
                $(TOP)/src/tclsqlite.c libsqlite.la $(LIBTCL)
diff --git a/main.mk b/main.mk
index 27593af659918f53ae3608b91122bf6c2352f8b6..1ed50460658d7897cc321d9215842e1ecf3abea1 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -54,7 +54,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
 
 # Object files for the SQLite library.
 #
-LIBOBJ = btree.o build.o delete.o expr.o func.o hash.o insert.o \
+LIBOBJ = auth.o btree.o build.o delete.o expr.o func.o hash.o insert.o \
          main.o opcodes.o os.o pager.o parse.o printf.o random.o \
          select.o table.o tokenize.o trigger.o update.o util.o \
          vdbe.o where.o tclsqlite.o
@@ -62,6 +62,7 @@ LIBOBJ = btree.o build.o delete.o expr.o func.o hash.o insert.o \
 # All of the source code files.
 #
 SRC = \
+  $(TOP)/src/auth.c \
   $(TOP)/src/btree.c \
   $(TOP)/src/btree.h \
   $(TOP)/src/build.c \
@@ -264,6 +265,9 @@ tclsqlite.o:        $(TOP)/src/tclsqlite.c $(HDR)
 printf.o:      $(TOP)/src/printf.c $(HDR)
        $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/printf.c
 
+auth.o:        $(TOP)/src/auth.c $(HDR)
+       $(TCCX) -c $(TOP)/src/auth.c
+
 tclsqlite:     $(TOP)/src/tclsqlite.c libsqlite.a
        $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite \
                $(TOP)/src/tclsqlite.c libsqlite.a $(LIBTCL)
index d1e1b4ebf731933e7786a37039d0e34617dd2fbe..138821de3e4f434cf785886baabccb9d8d35df69 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
-C Remove\san\sunused\svariable\sfrom\sthe\sVDBE.\s\sTicket\s#223.\s(CVS\s826)
-D 2003-01-12T17:35:00
-F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e
+C Initial\scheck-in\sof\sthe\scode\sfor\sthe\snew\ssqlite_set_authorizer()\sAPI\sfunction.\nThe\scode\sis\smostly\suntested\sat\sthis\spoint.\s(CVS\s827)
+D 2003-01-12T18:02:17
+F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 F VERSION 0b1d326c46b00250dfbd9b1a55dc0f4b7d74febc
@@ -14,44 +14,44 @@ F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
 F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
-F main.mk 9d13839b9697af332d788fe6e801e68da027cc5c
+F main.mk 8b10c5df8a21cdd343986a90c75247bafaebb3aa
 F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d
 F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
 F src/btree.c 131b5903f66e148f0f9af0cedd1c6654932c4e04
 F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
-F src/build.c f355fa02bb53cdaa417ea1c34a43de1129a57e94
-F src/delete.c 1c677cad4879485c2aea5ef40f417b3ec3f7be12
+F src/build.c 3136d7fc765cc2feee2ad987bac1c1696fdc0f0e
+F src/delete.c bc807a756dde6aa16db38f6e05a90408053d2f2c
 F src/encode.c 09d1fe8a2e97ff94cce496e2909e2ebc8947960b
-F src/expr.c 9427b4d1d04ede1095994b8e042abe2e6fea7443
+F src/expr.c d8b319f25335443a415a639aec8e0edc64e3ab6c
 F src/func.c 90c583f0b91220f7cd411a2407deaf9327245d63
 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
-F src/insert.c 74018ec733f2c443671840018e5e5f1ddbc37838
-F src/main.c cee05c2ba23b5e78f9671f319dbd68e2130e0f68
+F src/insert.c 0ea9427f7242a4432842100b41b4b81fd1999ad6
+F src/main.c c8f8fdfe4548a8404fab90ff6ad374b217e6b7fa
 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
 F src/os.c 28447687e7914306650f72058f62f7162faeef1f
 F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
-F src/pager.c 6874ea294cbca2aef6e83eb745a67c01cbb5f94b
+F src/pager.c 5b81639b38eb4250810ed2b31aada9fb040ed86b
 F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
 F src/parse.y 427a17888c117cc9cc35311eda0603d55437f02b
 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c b52c1dccbfc35ff13c84b4321a0bd2ac3a23d2f2
+F src/select.c 1b7d20b659621bf8621dec710e9680b4c380563c
 F src/shell.c c9946847b81b8b7f32ad195498dafbc623c6874f
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
-F src/sqlite.h.in 98b1574b2362abe02c4a4c73b9dbf99bcd713ab3
-F src/sqliteInt.h 4f7511446a7616ffa24542dda5bf596776852c2d
+F src/sqlite.h.in 7b35872afdba0d46890773470a12aa71d78f6d21
+F src/sqliteInt.h 01b59d2ecbd36b7ec750339bbd9401c012b463c2
 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
 F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
-F src/test1.c 5efd7a8b18ff63e570e94cd7c842a74fb08dd511
+F src/test1.c 2a0e5cf7e66cbbb46d9f0c97ea8f406141e8b263
 F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b
 F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
 F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 F src/tokenize.c 7ac1c33e0149647c9eb5959c48992df6906d4809
-F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481
-F src/update.c ab3182eae676d7f198354df6a54e8611aac6ae9c
-F src/util.c e2d108842e02810d3d3242cac0e024b09cdb3c4a
+F src/trigger.c dd3fb6595643e29b71d6f3ecb22afb930224633c
+F src/update.c 9f2e9105c697b11b06b381910d0e429718f01cc3
+F src/util.c 354336da4a6f1c98f687a13db0c45ed9314a892b
 F src/vdbe.c e103bd5a154b1790dd344662dceb14566a51a879
 F src/vdbe.h 754eba497cfe0c3e352b9c101ab2f811f10d0a55
 F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18
@@ -152,7 +152,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P fc11fa50b8f39f5e0b3674d7df832ffbca0d948f
-R 87a0a3cad3f27526e1ddc77d411afd4e
+P 0deaf563fd9784bf0795107cd10e6b3269dfecea
+R 0161ffe233937639f6afc181720e6e82
 U drh
-Z 6813c7f1dfa42fe98f14f8fc0a2f75cc
+Z 0354e92c05e165e223123b5629b1da94
index d87f7e825c2c106a5624ffa473ee11a860ce13eb..5d2e3fb99aee521ba75c94d21a98e0e3b54d40c4 100644 (file)
@@ -1 +1 @@
-0deaf563fd9784bf0795107cd10e6b3269dfecea
\ No newline at end of file
+52d5007f64d0af5286b2a0e1f0b9e53c86bece3f
\ No newline at end of file
index 30457c7ba13aebcdfda15e4e0c8898d8cc67120e..b13755215628045c9f01cd669b3fb41c437d9c79 100644 (file)
@@ -25,7 +25,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.119 2003/01/11 13:30:57 drh Exp $
+** $Id: build.c,v 1.120 2003/01/12 18:02:17 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -325,6 +325,9 @@ 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) ){
+    return;
+  }
 
   /* Before trying to create a temporary table, make sure the Btree for
   ** holding temporary tables is open.
@@ -894,7 +897,7 @@ void sqliteCreateView(
 
   sqliteStartTable(pParse, pBegin, pName, isTemp);
   p = pParse->pNewTable;
-  if( p==0 ){
+  if( p==0 || pParse->nErr ){
     sqliteSelectDelete(pSelect);
     return;
   }
@@ -1069,6 +1072,9 @@ 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) ){
+    return;
+  }
   if( pTable->readOnly ){
     sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName, 
        " may not be dropped", 0);
@@ -1087,6 +1093,9 @@ 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.
@@ -1365,6 +1374,9 @@ 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
@@ -1626,6 +1638,9 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
     pParse->nErr++;
     return;
   }
+  if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pIndex->pTable->isTemp), 1) ){
+    return;
+  }
 
   /* Generate code to remove the index and from the master table */
   v = sqliteGetVdbe(pParse);
@@ -1822,6 +1837,12 @@ 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) ){
+    goto copy_cleanup;
+  }
   v = sqliteGetVdbe(pParse);
   if( v ){
     int openOp;
@@ -1904,6 +1925,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( db->flags & SQLITE_InTrans ){
     pParse->nErr++;
     sqliteSetString(&pParse->zErrMsg, "cannot start a transaction "
@@ -1923,6 +1945,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( (db->flags & SQLITE_InTrans)==0 ){
     pParse->nErr++;
     sqliteSetString(&pParse->zErrMsg, 
@@ -1943,6 +1966,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( (db->flags & SQLITE_InTrans)==0 ){
     pParse->nErr++;
     sqliteSetString(&pParse->zErrMsg,
@@ -2051,6 +2075,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;
  
   /*
   **  PRAGMA default_cache_size
index bfcf2e4e243a49a3dc5c25b0b0769e8afac8854e..5c5582433db78ca021224ee2887b6e0a7b4dc667 100644 (file)
@@ -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.43 2003/01/11 13:30:57 drh Exp $
+** $Id: delete.c,v 1.44 2003/01/12 18:02:18 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -88,7 +88,8 @@ void sqliteDeleteFrom(
   int row_triggers_exist = 0;
   int oldIdx = -1;
 
-  if( pParse->nErr || sqlite_malloc_failed ){
+  if( pParse->nErr || sqlite_malloc_failed
+          || sqliteAuthCommand(pParse,"DELETE",0) ){
     pTabList = 0;
     goto delete_from_cleanup;
   }
@@ -125,6 +126,7 @@ 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;
 
   /* Allocate a cursor used to store the old.* data for a trigger.
   */
index 21c2c030835f92492e0401b9c26fbefd5cacb8ad..5fcfd88339e9620920cc16ad6611659001139660 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.83 2002/10/31 00:09:40 drh Exp $
+** $Id: expr.c,v 1.84 2003/01/12 18:02:18 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -430,6 +430,7 @@ int sqliteExprResolveIds(
     case TK_ID: {
       int cnt = 0;      /* Number of matches */
       int i;            /* Loop counter */
+      int rc;           /* Return code */
       char *z;
       assert( pExpr->token.z );
       z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
@@ -488,6 +489,9 @@ int sqliteExprResolveIds(
         pParse->nErr++;
         return 1;
       }
+      if( pExpr->op==TK_COLUMN ){
+        sqliteAuthRead(pParse, pExpr, pTabList, base);
+      }
       break; 
     }
   
@@ -595,6 +599,7 @@ int sqliteExprResolveIds(
       sqliteExprDelete(pRight);
       pExpr->pRight = 0;
       pExpr->op = TK_COLUMN;
+      sqliteAuthRead(pParse, pExpr, pTabList, base);
       break;
     }
 
index d03fff7019d8a5509539b6780a9550fb56427ca2..5dc8882d3274b4fec7ea678d79a93b0521c49c26 100644 (file)
@@ -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.68 2003/01/11 13:30:58 drh Exp $
+** $Id: insert.c,v 1.69 2003/01/12 18:02:18 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -114,6 +114,7 @@ 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.
index b8be0dc5b4a00384063ce34e102db8ff8426f7d1..2c602103a1d90c27b4a590e17b40b460af6f963c 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.105 2002/12/02 04:25:21 drh Exp $
+** $Id: main.c,v 1.106 2003/01/12 18:02:18 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -689,6 +689,7 @@ const char *sqlite_error_string(int rc){
     case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
     case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
     case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
+    case SQLITE_AUTH:       z = "authorization denied";                  break;
     default:                z = "unknown error";                         break;
   }
   return z;
index fb28913f1f2615772e59f8c2acf040c00a232fc0..8b618ab3b06628e6a8624ca45911d829bbbe3e66 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.66 2003/01/11 13:30:58 drh Exp $
+** @(#) $Id: pager.c,v 1.67 2003/01/12 18:02:18 drh Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -1050,6 +1050,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
     }
     pPg->pgno = pgno;
     if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
+      sqliteCheckMemory(pPager->aInJournal, pgno/8);
       pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
     }else{
       pPg->inJournal = 0;
index 129a4edd593ab445871b7939dc2c2fb1295a4871..fe90eccc5ab640e747e6c267ecc6119b2f1e6173 100644 (file)
@@ -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.119 2003/01/11 14:19:52 drh Exp $
+** $Id: select.c,v 1.120 2003/01/12 18:02:18 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1781,6 +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 there is are a sequence of queries, do the earlier ones first.
   */
index 8f9a6c83e05e7cac8d777b64aebd6df63f94883c..985f255a577eeb56d11d23987cf90fe66b7775d8 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.35 2002/11/09 00:33:17 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.36 2003/01/12 18:02:18 drh Exp $
 */
 #ifndef _SQLITE_H_
 #define _SQLITE_H_
@@ -163,6 +163,7 @@ int sqlite_exec(
 #define SQLITE_MISMATCH    20   /* Data type mismatch */
 #define SQLITE_MISUSE      21   /* Library used incorrectly */
 #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
+#define SQLITE_AUTH        23   /* Authorization denied */
 
 /*
 ** Each entry in an SQLite table has a unique integer key.  (The key is
@@ -498,6 +499,37 @@ void *sqlite_aggregate_context(sqlite_func*, int nBytes);
 */
 int sqlite_aggregate_count(sqlite_func*);
 
+/*
+** This routine registers a callback with the SQLite library.  The
+** callback is invoked for every attempt to access a column of a table
+** in the database.  The callback returns SQLITE_OK if access is allowed,
+** SQLITE_DENY if the entire SQL statement should be aborted with an error
+** and SQLITE_IGNORE if the column should be treated as a NULL value.
+*/
+int sqlite_set_authorizer(
+  sqlite*,
+  int (*xAuth)(void*,int,const char*,const char*),
+  void*
+);
+
+/*
+** 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?  */
+
+/*
+** The return value of the authorization function should be one of the
+** following constants:
+*/
+/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
+#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
+#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */
+
 /*
 ** Attempt to open the file named in the argument as the auxiliary database
 ** file.  The auxiliary database file is used to store TEMP tables.  But
index 5a4c7dc41ee2816f40095bd6a2f9e87c049d75f2..b757a8320a8e299824c4ecdf0683628a972a7ef3 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.152 2003/01/11 13:30:58 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.153 2003/01/12 18:02:18 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -154,6 +154,11 @@ extern int sqlite_iMallocFail;   /* Fail sqliteMalloc() after this many calls */
 #define MASTER_NAME       "sqlite_master"
 #define TEMP_MASTER_NAME  "sqlite_temp_master"
 
+/*
+** The name of the schema table.
+*/
+#define SCHEMA_TABLE(x)  (x?TEMP_MASTER_NAME:MASTER_NAME)
+
 /*
 ** A convenience macro that returns the number of elements in
 ** an array.
@@ -220,6 +225,10 @@ struct sqlite {
   int magic;                    /* Magic number for detect library misuse */
   int nChange;                  /* Number of rows changed */
   int recursionDepth;           /* Number of nested calls to sqlite_exec() */
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */
+  void *pAuthArg;               /* 1st argument to the access auth function */
+#endif
 };
 
 /*
@@ -899,6 +908,7 @@ void sqliteRealToSortable(double r, char *);
   void *sqliteRealloc_(void*,int,char*,int);
   char *sqliteStrDup_(const char*,char*,int);
   char *sqliteStrNDup_(const char*, int,char*,int);
+  void sqliteCheckMemory(void*,int);
 #else
   void *sqliteMalloc(int);
   void *sqliteMallocRaw(int);
@@ -906,6 +916,7 @@ void sqliteRealToSortable(double r, char *);
   void *sqliteRealloc(void*,int);
   char *sqliteStrDup(const char*);
   char *sqliteStrNDup(const char*, int);
+# define sqliteCheckMemory(a,b)
 #endif
 void sqliteSetString(char **, const char *, ...);
 void sqliteSetNString(char **, ...);
@@ -1022,3 +1033,15 @@ void sqliteDeleteTrigger(Trigger*);
 int sqliteJoinType(Parse*, Token*, Token*, Token*);
 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*);
+#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
+#endif
index 90498b123eca8478d49e17c0507efff579efcec0..92f186ef6cacf674c140ecb9c4b1e0bc749ae5fe 100644 (file)
@@ -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.14 2003/01/11 14:19:52 drh Exp $
+** $Id: test1.c,v 1.15 2003/01/12 18:02:19 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -559,6 +559,104 @@ static int sqlite_datatypes(
   return TCL_OK;
 }
 
+#ifndef SQLITE_OMIT_AUTHORIZATION
+/*
+** Information used by the authentication function. 
+*/
+typedef struct AuthInfo AuthInfo;
+struct AuthInfo {
+  Tcl_Interp *interp;    /* Interpreter to use */
+  int nCmd;              /* Number of characters in zCmd[] */
+  char zCmd[500];        /* Command to invoke */
+};
+
+/*
+** We create a single static authenticator.  This won't work in a
+** multi-threaded environment, but the test fixture is not multithreaded.
+** And be making it static, we don't have to worry about deallocating
+** after a test in order to void memory leaks.
+*/
+static AuthInfo authInfo;
+
+/*
+** This is the authentication function.  It appends the authentication
+** type code and the two arguments to zCmd[] then invokes the result
+** on the interpreter.  The reply is examined to determine if the
+** authentication fails or succeeds.
+*/
+static int auth_callback(
+  void *NotUsed, 
+  int code,
+  const char *zArg1,
+  const char *zArg2
+){
+  char *zCode;
+  Tcl_DString str;
+  int rc;
+  const char *zReply;
+  switch( code ){
+    case SQLITE_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;
+  }
+  Tcl_DStringInit(&str);
+  Tcl_DStringAppend(&str, authInfo.zCmd, -1);
+  Tcl_DStringAppendElement(&str, zCode);
+  Tcl_DStringAppendElement(&str, zArg1);
+  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
+  rc = Tcl_GlobalEval(authInfo.interp, Tcl_DStringValue(&str));
+  Tcl_DStringFree(&str);
+  zReply = Tcl_GetStringResult(authInfo.interp);
+  if( strcmp(zReply,"SQLITE_OK")==0 ){
+    rc = SQLITE_OK;
+  }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
+    rc = SQLITE_DENY;
+  }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
+    rc = SQLITE_IGNORE;
+  }else{
+    rc = 999;
+  }
+  return rc;
+}
+
+/*
+** This routine creates a new authenticator.  It fills in the zCmd[]
+** field of the authentication function state variable and then registers
+** the authentication function with the SQLite library.
+*/
+static int test_set_authorizer(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  sqlite *db;
+  char *zCmd;
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
+         " DB CALLBACK\"", 0);
+    return TCL_ERROR;
+  }
+  db = (sqlite*)strtol(argv[1], 0, 0);
+  zCmd = argv[2];
+  if( zCmd[0]==0 ){
+    sqlite_set_authorizer(db, 0, 0);
+    return TCL_OK;
+  }
+  if( strlen(zCmd)>sizeof(authInfo.zCmd) ){
+    Tcl_AppendResult(interp, "command too big", 0);
+    return TCL_ERROR;
+  }
+  authInfo.interp = interp;
+  authInfo.nCmd = strlen(zCmd);
+  strcpy(authInfo.zCmd, zCmd);
+  sqlite_set_authorizer(db, auth_callback, 0);
+  return TCL_OK;
+}
+#endif /* SQLITE_OMIT_AUTHORIZATION */
 
 /*
 ** Register commands with the TCL interpreter.
@@ -582,6 +680,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite_register_test_function",  (Tcl_CmdProc*)test_register_func    },
      { "sqlite_abort",                   (Tcl_CmdProc*)sqlite_abort          },
      { "sqlite_datatypes",               (Tcl_CmdProc*)sqlite_datatypes      },
+#ifndef SQLITE_OMIT_AUTHORIZATION
+     { "sqlite_set_authorizer",          (Tcl_CmdProc*)test_set_authorizer   },
+#endif
 #ifdef MEMORY_DEBUG
      { "sqlite_malloc_fail",             (Tcl_CmdProc*)sqlite_malloc_fail    },
      { "sqlite_malloc_stat",             (Tcl_CmdProc*)sqlite_malloc_stat    },
index 222d09de0d5bbe80127a01042fd57e7b45642a70..079a4c2f85b7e0b97104dea1a88ebcc6453299e8 100644 (file)
@@ -50,6 +50,8 @@ void sqliteCreateTrigger(
   Trigger *nt;
   Table   *tab;
 
+  if( sqliteAuthCommand(pParse, "CREATE", "TRIGGER") ) goto trigger_cleanup;
+
   /* Check that: 
   ** 1. the trigger name does not already exist.
   ** 2. the table (or view) does exist.
@@ -102,6 +104,9 @@ 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;
+    }
   }
 
   if (tr_tm == TK_INSTEAD){
@@ -337,6 +342,7 @@ 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 */
@@ -347,13 +353,18 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
     sqliteFree(zName);
     return;
   }
+  pTable = sqliteFindTable(pParse->db, pTrigger->table);
+  assert(pTable);
+  if( sqliteAuthDelete(pParse, SCHEMA_TABLE(pTable->isTemp), 1) ){
+    sqliteFree(zName);
+    return;
+  }
+
 
   /*
    * If this is not an "explain", then delete the trigger structure.
    */
   if( !pParse->explain ){
-    pTable = sqliteFindTable(pParse->db, pTrigger->table);
-    assert(pTable);
     if( pTable->pTrigger == pTrigger ){
       pTable->pTrigger = pTrigger->pNext;
     }else{
index 29a4197f982f03ca529e3657f7e8f16561d185cb..7ddecaca1f3fe50f1a72a9d848a3bccd1cedc2d1 100644 (file)
@@ -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.51 2003/01/11 13:30:58 drh Exp $
+** $Id: update.c,v 1.52 2003/01/12 18:02:19 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -53,6 +53,7 @@ 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 
@@ -110,7 +111,9 @@ void sqliteUpdate(
 
   /* Resolve the column names in all the expressions in both the
   ** WHERE clause and in the new values.  Also find the column index
-  ** for each column to be updated in the pChanges array.
+  ** for each column to be updated in the pChanges array.  For each
+  ** column to be updated, make sure we have authorization to change
+  ** that column.
   */
   if( pWhere ){
     if( sqliteExprResolveIds(pParse, base, pTabList, 0, pWhere) ){
@@ -144,6 +147,11 @@ void sqliteUpdate(
       pParse->nErr++;
       goto update_cleanup;
     }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+    if( sqliteAuthWrite(pParse, pTab, j)==SQLITE_IGNORE ){
+      aXRef[j] = -1;
+    }
+#endif
   }
 
   /* Allocate memory for the array apIdx[] and fill it with pointers to every
index 3d47bbaf66a82ba2f557f57c98a438b59459fd9d..7e4e72f58720053b0da50dbb05b96780e2900e7d 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.54 2003/01/02 14:43:57 drh Exp $
+** $Id: util.c,v 1.55 2003/01/12 18:02:19 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -84,6 +84,24 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
   return p;
 }
 
+/*
+** Check to see if the given pointer was obtained from sqliteMalloc()
+** and is able to hold at least N bytes.  Raise an exception if this
+** is not the case.
+**
+** This routine is used for testing purposes only.
+*/
+void sqliteCheckMemory(void *p, int N){
+  int *pi = p;
+  int n, k;
+  pi -= 2;
+  assert( pi[0]==0xdead1122 );
+  n = pi[1];
+  assert( N>=0 && N<n );
+  k = (n+sizeof(int)-1)/sizeof(int);
+  assert( pi[k+2]==0xdead3344 );
+}
+
 /*
 ** Free memory previously obtained from sqliteMalloc()
 */