Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The sqlite_exec() function now returns SQLITE_AUTH when authorization fails. Ticket #231. (CVS 857) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d93c1aeb544a5b1056424945eb438542 |
User & Date: | drh 2003-01-31 17:21:50.000 |
Context
2003-02-01
| ||
13:53 | When a CREATE TABLE ... AS SELECT statement fails, make sure the table name is removed from the internal hash tables. Ticket #238. (CVS 858) (check-in: 65264780c5 user: drh tags: trunk) | |
2003-01-31
| ||
17:21 | The sqlite_exec() function now returns SQLITE_AUTH when authorization fails. Ticket #231. (CVS 857) (check-in: d93c1aeb54 user: drh tags: trunk) | |
17:16 | Allow double-quoted strings as string constants in the IN operator. As a side-efffect, allow the GROUP BY clause to refer to columns by their integer column number. Ticket #237. (CVS 856) (check-in: 187d9c4058 user: drh tags: trunk) | |
Changes
Changes to src/auth.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the sqlite_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the sqlite_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** ** $Id: auth.c,v 1.4 2003/01/31 17:21:50 drh Exp $ */ #include "sqliteInt.h" /* ** All of the code in this file may be omitted by defining a single ** macro. */ |
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | static void sqliteAuthBadReturnCode(Parse *pParse, int rc){ char zBuf[20]; sprintf(zBuf, "(%d)", rc); sqliteSetString(&pParse->zErrMsg, "illegal return value ", zBuf, " from the authorization function - should be SQLITE_OK, " "SQLITE_IGNORE, or SQLITE_DENY", 0); pParse->nErr++; } /* ** The pExpr should be a TK_COLUMN expression. The table referred to ** is in pTabList with an offset of base. Check to see if it is OK to read ** this particular column. ** | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | static void sqliteAuthBadReturnCode(Parse *pParse, int rc){ char zBuf[20]; sprintf(zBuf, "(%d)", rc); sqliteSetString(&pParse->zErrMsg, "illegal return value ", zBuf, " from the authorization function - should be SQLITE_OK, " "SQLITE_IGNORE, or SQLITE_DENY", 0); pParse->nErr++; pParse->rc = SQLITE_MISUSE; } /* ** The pExpr should be a TK_COLUMN expression. The table referred to ** is in pTabList with an offset of base. Check to see if it is OK to read ** this particular column. ** |
︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 | rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol); if( rc==SQLITE_IGNORE ){ pExpr->op = TK_NULL; }else if( rc==SQLITE_DENY ){ sqliteSetString(&pParse->zErrMsg,"access to ", pTab->zName, ".", zCol, " is prohibited", 0); pParse->nErr++; }else if( rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse, rc); } } /* ** Do an authorization check using the code and arguments given. Return | > | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol); if( rc==SQLITE_IGNORE ){ pExpr->op = TK_NULL; }else if( rc==SQLITE_DENY ){ sqliteSetString(&pParse->zErrMsg,"access to ", pTab->zName, ".", zCol, " is prohibited", 0); pParse->nErr++; pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse, rc); } } /* ** Do an authorization check using the code and arguments given. Return |
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | int rc; if( db->xAuth==0 ){ return SQLITE_OK; } 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; sqliteAuthBadReturnCode(pParse, rc); } return rc; } #endif /* SQLITE_OMIT_AUTHORIZATION */ | > | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | int rc; if( db->xAuth==0 ){ return SQLITE_OK; } rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2); if( rc==SQLITE_DENY ){ sqliteSetString(&pParse->zErrMsg, "not authorized", 0); pParse->rc = SQLITE_AUTH; pParse->nErr++; }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ rc = SQLITE_DENY; sqliteAuthBadReturnCode(pParse, rc); } return rc; } #endif /* SQLITE_OMIT_AUTHORIZATION */ |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.44 2003/01/31 17:21:50 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | */ typedef struct SqliteDb SqliteDb; struct SqliteDb { sqlite *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ SqlFunc *pFunc; /* List of SQL functions */ }; /* ** An instance of this structure passes information thru the sqlite ** logic from the original TCL command into the callback routine. */ typedef struct CallbackData CallbackData; | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | */ typedef struct SqliteDb SqliteDb; struct SqliteDb { sqlite *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ SqlFunc *pFunc; /* List of SQL functions */ int rc; /* Return code of most recent sqlite_exec() */ }; /* ** An instance of this structure passes information thru the sqlite ** logic from the original TCL command into the callback routine. */ typedef struct CallbackData CallbackData; |
︙ | ︙ | |||
324 325 326 327 328 329 330 | ** subroutine to be invoked. */ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { "busy", "changes", "close", | | | < > | | > | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | ** subroutine to be invoked. */ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { "busy", "changes", "close", "complete", "errorcode", "eval", "function", "last_insert_rowid", "open_aux_file", "timeout", 0 }; enum DB_enum { DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMPLETE, DB_ERRORCODE, DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID,DB_OPEN_AUX_FILE, DB_TIMEOUT, }; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ |
︙ | ︙ | |||
426 427 428 429 430 431 432 433 434 435 436 437 438 439 | return TCL_ERROR; } isComplete = sqlite_complete( Tcl_GetStringFromObj(objv[2], 0) ); pResult = Tcl_GetObjResult(interp); Tcl_SetBooleanObj(pResult, isComplete); break; } /* ** $db eval $sql ?array { ...code... }? ** ** The SQL statement in $sql is evaluated. For each row, the values are ** placed in elements of the array named "array" and ...code... is executed. ** If "array" and "code" are omitted, then no callback is every invoked. | > > > > > > > > > > > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | return TCL_ERROR; } isComplete = sqlite_complete( Tcl_GetStringFromObj(objv[2], 0) ); pResult = Tcl_GetObjResult(interp); Tcl_SetBooleanObj(pResult, isComplete); break; } /* ** $db errorcode ** ** Return the numeric error code that was returned by the most recent ** call to sqlite_exec(). */ case DB_ERRORCODE: { Tcl_SetObjResult(interp, Tcl_NewIntObj(pDb->rc)); break; } /* ** $db eval $sql ?array { ...code... }? ** ** The SQL statement in $sql is evaluated. For each row, the values are ** placed in elements of the array named "array" and ...code... is executed. ** If "array" and "code" are omitted, then no callback is every invoked. |
︙ | ︙ | |||
479 480 481 482 483 484 485 486 487 488 489 490 491 492 | if( cbData.tcl_rc==TCL_BREAK ){ cbData.tcl_rc = TCL_OK; } }else{ Tcl_Obj *pList = Tcl_NewObj(); cbData.tcl_rc = TCL_OK; rc = sqlite_exec(pDb->db, zSql, DbEvalCallback2, pList, &zErrMsg); Tcl_SetObjResult(interp, pList); } if( rc==SQLITE_ABORT ){ if( zErrMsg ) free(zErrMsg); rc = cbData.tcl_rc; }else if( zErrMsg ){ Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); free(zErrMsg); rc = TCL_ERROR; | > | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | if( cbData.tcl_rc==TCL_BREAK ){ cbData.tcl_rc = TCL_OK; } }else{ Tcl_Obj *pList = Tcl_NewObj(); cbData.tcl_rc = TCL_OK; rc = sqlite_exec(pDb->db, zSql, DbEvalCallback2, pList, &zErrMsg); Tcl_SetObjResult(interp, pList); } pDb->rc = rc; if( rc==SQLITE_ABORT ){ if( zErrMsg ) free(zErrMsg); rc = cbData.tcl_rc; }else if( zErrMsg ){ Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); free(zErrMsg); rc = TCL_ERROR; |
︙ | ︙ | |||
567 568 569 570 571 572 573 574 575 576 577 578 579 580 | int rc; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "FILENAME"); return TCL_ERROR; } zFilename = Tcl_GetStringFromObj(objv[2], 0); rc = sqlite_open_aux_file(pDb->db, zFilename, &zErrMsg); if( rc!=0 ){ if( zErrMsg ){ Tcl_AppendResult(interp, zErrMsg, 0); free(zErrMsg); }else{ Tcl_AppendResult(interp, sqlite_error_string(rc), 0); } | > | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | int rc; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "FILENAME"); return TCL_ERROR; } zFilename = Tcl_GetStringFromObj(objv[2], 0); rc = sqlite_open_aux_file(pDb->db, zFilename, &zErrMsg); pDb->rc = rc; if( rc!=0 ){ if( zErrMsg ){ Tcl_AppendResult(interp, zErrMsg, 0); free(zErrMsg); }else{ Tcl_AppendResult(interp, sqlite_error_string(rc), 0); } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** ** $Id: where.c,v 1.72 2003/01/31 17:21:50 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. |
︙ | ︙ | |||
58 59 60 61 62 63 64 | aSlot[0].p = pExpr; return 1; } if( pExpr->pLeft->op!=TK_AND ){ aSlot[0].p = pExpr->pLeft; cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight); }else{ | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | aSlot[0].p = pExpr; return 1; } if( pExpr->pLeft->op!=TK_AND ){ aSlot[0].p = pExpr->pLeft; cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight); }else{ cnt = exprSplit(nSlot, aSlot, pExpr->pLeft); cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight); } return cnt; } /* ** This routine walks (recursively) an expression tree and generates ** a bitmask indicating which tables are used in that expression |
︙ | ︙ |
Changes to test/auth.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 January 12 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_set_authorizer() API. # | | | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # 2003 January 12 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_set_authorizer() API. # # $Id: auth.test,v 1.5 2003/01/31 17:21:50 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info command sqlite_set_authorizer]!=""} { do_test auth-1.1.1 { db close set ::DB [sqlite db test.db] proc auth {code arg1 arg2} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_DENY } return SQLITE_OK } sqlite_set_authorizer $::DB ::auth catchsql {CREATE TABLE t1(a,b,c)} } {1 {not authorized}} do_test auth-1.1.2 { db errorcode } {23} do_test auth-1.2 { execsql {SELECT name FROM sqlite_master} } {} do_test auth-1.3.1 { proc auth {code arg1 arg2} { if {$code=="SQLITE_CREATE_TABLE"} { set ::authargs [list $arg1 $arg2] return SQLITE_DENY } return SQLITE_OK } catchsql {CREATE TABLE t1(a,b,c)} } {1 {not authorized}} do_test auth-1.3.2 { db errorcode } {23} do_test auth-1.3.3 { set ::authargs } {t1 {}} do_test auth-1.4 { execsql {SELECT name FROM sqlite_master} } {} do_test auth-1.5 { |
︙ | ︙ | |||
1608 1609 1610 1611 1612 1613 1614 | if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="ROWID"} { return SQLITE_IGNORE } return SQLITE_OK } catchsql {SELECT ROWID,b,c FROM t2} } {0 {{} 2 33 {} 8 9}} | | > > > | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="ROWID"} { return SQLITE_IGNORE } return SQLITE_OK } catchsql {SELECT ROWID,b,c FROM t2} } {0 {{} 2 33 {} 8 9}} do_test auth-2.9.1 { proc auth {code arg1 arg2} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="ROWID"} { return bogus } return SQLITE_OK } catchsql {SELECT ROWID,b,c FROM t2} } {1 {illegal return value (999) from the authorization function - should be SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY}} do_test auth-2.9.2 { db errorcode } {21} do_test auth-2.10 { proc auth {code arg1 arg2} { if {$code=="SQLITE_SELECT"} { return bogus } return SQLITE_OK } |
︙ | ︙ |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # This file implements regression tests for TCL interface to the # SQLite library. # # Actually, all tests are based on the TCL interface, so the main # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # This file implements regression tests for TCL interface to the # SQLite library. # # Actually, all tests are based on the TCL interface, so the main # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # # $Id: tclsqlite.test,v 1.9 2003/01/31 17:21:51 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Check the error messages generated by tclsqlite # do_test tcl-1.1 { set v [catch {sqlite bogus} msg] lappend v $msg } {1 {wrong # args: should be "sqlite HANDLE FILENAME ?MODE?"}} do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg } {1 {bad option "bogus": must be busy, changes, close, complete, errorcode, eval, function, last_insert_rowid, open_aux_file, or timeout}} do_test tcl-1.3 { execsql {CREATE TABLE t1(a int, b int)} execsql {INSERT INTO t1 VALUES(10,20)} set v [catch { db eval {SELECT * FROM t1} data { error "The error message" } |
︙ | ︙ |