Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Replace sqlite4_set_authorizer() with sqlite4_authorizer_push() and sqlite4_authorizer_pop(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
555f0c788da8c8ff6eee489a2e3748c0 |
User & Date: | dan 2013-05-07 19:36:18.933 |
Context
2013-05-08
| ||
14:37 | Add tests for authorizer_push() and authorizer_pop(). check-in: 0263259ac4 user: dan tags: trunk | |
2013-05-07
| ||
19:36 | Replace sqlite4_set_authorizer() with sqlite4_authorizer_push() and sqlite4_authorizer_pop(). check-in: 555f0c788d user: dan tags: trunk | |
2013-04-29
| ||
17:48 | Fix a problem with the binary-to-decimal mode of the "varint" command-line test tool. check-in: 34281c89cf user: drh tags: trunk | |
Changes
Changes to src/auth.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2003 January 11 ** ** 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. ** ************************************************************************* | | | | | | > > | | < < | | | | > | | < < > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | > > > > > > > > > | > > | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < > | 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | /* ** 2003 January 11 ** ** 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 contains code used to implement the sqlite4_authorizer_push() ** and sqlite4_authorizer_pop() APIs. 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 -DSQLITE4_OMIT_AUTHORIZATION=1 */ #include "sqliteInt.h" /* ** All of the code in this file may be omitted by defining a single ** macro. */ #ifndef SQLITE4_OMIT_AUTHORIZATION /* ** Each authorizer callback is stored in an instance of this structure. ** The structures themselves are stored in a linked list headed at ** sqlite4.pAuth. */ struct Authorizer { void *pCtx; int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); void (*xDestroy)(void*); Authorizer *pNext; }; /* ** Push an authorizer callback onto the stack. */ int sqlite4_authorizer_push( sqlite4 *db, void *pCtx, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void (*xDestroy)(void*) ){ int rc = SQLITE4_OK; Authorizer *pNew; sqlite4_mutex_enter(db->mutex); pNew = (Authorizer *)sqlite4DbMallocZero(db, sizeof(Authorizer)); if( pNew==0 ){ rc = SQLITE4_NOMEM; }else{ pNew->pCtx = pCtx; pNew->xAuth = xAuth; pNew->xDestroy = xDestroy; pNew->pNext = db->pAuth; db->pAuth = pNew; sqlite4ExpirePreparedStatements(db); } sqlite4_mutex_leave(db->mutex); return rc; } /* ** Pop an authorizer callback from the stack. This version assumes that ** the stack is not empty and that the database handle mutex is held. */ static void authPopStack(sqlite4 *db){ Authorizer *pAuth = db->pAuth; db->pAuth = pAuth->pNext; if( pAuth->xDestroy ){ pAuth->xDestroy(pAuth->pCtx); } sqlite4DbFree(db, pAuth); } /* ** Pop an authorizer callback from the stack. */ int sqlite4_authorizer_pop(sqlite4 *db){ int rc = SQLITE4_OK; sqlite4_mutex_enter(db->mutex); if( db->pAuth==0 ){ rc = SQLITE4_ERROR; }else{ authPopStack(db); } sqlite4ExpirePreparedStatements(db); sqlite4_mutex_leave(db->mutex); return rc; } /* ** Free the entire authorization callback stack. This function is called ** as part of closing the database handle. */ void sqlite4AuthFreeAll(sqlite4 *db){ while( db->pAuth ){ authPopStack(db); } } /* ** Write an error message into pParse->zErrMsg that explains that the ** user-supplied authorization function returned an illegal value. */ static void authBadReturnCode(Parse *pParse){ sqlite4ErrorMsg(pParse, "authorizer malfunction"); pParse->rc = SQLITE4_ERROR; } /* ** Invoke the authorization callback stack with the supplied parameters. ** If no error occurs, return SQLITE4_OK, SQLITE4_IGNORE or SQLITE4_DENY. ** ** If an authorizer function returns an invalid value, return SQLITE4_DENY ** and leave an error message in pParse. */ static int authInvokeStack( Parse *pParse, int eAuth, /* Action code */ const char *z1, /* Third argument for auth callbacks */ const char *z2, /* Fourth argument for auth callbacks */ const char *z3, /* Fifth argument for auth callbacks */ const char *z4 /* Sixth argument for auth callbacks */ ){ int rc = SQLITE4_OK; Authorizer *p; for(p=pParse->db->pAuth; p; p=p->pNext){ int rcauth = p->xAuth(p->pCtx, eAuth, z1, z2, z3, z4); switch( rcauth ){ case SQLITE4_IGNORE: /* fall through */ case SQLITE4_DENY: rc = rcauth; /* fall through */ case SQLITE4_OK: case SQLITE4_ALLOW: break; default: authBadReturnCode(pParse); rcauth = SQLITE4_DENY; } if( rcauth!=SQLITE4_OK && rcauth!=SQLITE4_IGNORE ) break; } assert( rc==SQLITE4_OK || rc==SQLITE4_DENY || rc==SQLITE4_IGNORE ); return rc; } /* ** Invoke the authorization callback for permission to read column zCol from ** table zTab in database zDb. This function assumes that an authorization ** callback has been registered (i.e. that sqlite4.xAuth is not NULL). ** ** If SQLITE4_IGNORE is returned and pExpr is not NULL, then pExpr is changed ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE4_IGNORE ** is treated as SQLITE4_DENY. In this case an error is left in pParse. */ int sqlite4AuthReadCol( Parse *pParse, /* The parser context */ const char *zTab, /* Table name */ const char *zCol, /* Column name */ int iDb /* Index of containing database. */ ){ const char *zAuthContext = pParse->zAuthContext; sqlite4 *db = pParse->db; /* Database handle */ char *zDb = db->aDb[iDb].zName; /* Name of attached database */ int rc; /* Auth callback return code */ rc = authInvokeStack(pParse, SQLITE4_READ, zTab, zCol, zDb, zAuthContext); if( rc==SQLITE4_DENY && pParse->rc==SQLITE4_OK ){ if( db->nDb>2 || iDb!=0 ){ sqlite4ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); }else{ sqlite4ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); } pParse->rc = SQLITE4_AUTH; } return rc; } /* ** The pExpr should be a TK_COLUMN expression. The table referred to ** is in pTabList or else it is the NEW or OLD table of a trigger. ** Check to see if it is OK to read this particular column. |
︙ | ︙ | |||
140 141 142 143 144 145 146 | sqlite4 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ int iDb; /* The index of the database the expression refers to */ int iCol; /* Index of column in table */ | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | sqlite4 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ int iDb; /* The index of the database the expression refers to */ int iCol; /* Index of column in table */ if( db->pAuth==0 ) return; iDb = sqlite4SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other ** temporary table. */ return; } |
︙ | ︙ | |||
198 199 200 201 202 203 204 | /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite4_declare_vtab. */ if( db->init.busy || IN_DECLARE_VTAB ){ return SQLITE4_OK; } | < < < | | < < < > | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite4_declare_vtab. */ if( db->init.busy || IN_DECLARE_VTAB ){ return SQLITE4_OK; } rc = authInvokeStack(pParse, code, zArg1, zArg2, zArg3, pParse->zAuthContext); if( rc==SQLITE4_DENY && pParse->rc==SQLITE4_OK ){ sqlite4ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE4_AUTH; } return rc; } /* ** Push an authorization context. After this routine is called, the ** zArg3 argument to authorization callbacks will be zContext until ** popped. Or if pParse==0, this routine is a no-op. |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1747 1748 1749 1750 1751 1752 1753 | */ int sqlite4ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite4 *db = pParse->db; /* Database connection for malloc errors */ | | | 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 | */ int sqlite4ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite4 *db = pParse->db; /* Database connection for malloc errors */ Authorizer *pAuth; assert( pTable ); #ifndef SQLITE4_OMIT_VIRTUALTABLE if( sqlite4VtabCallConnect(pParse, pTable) ){ return SQLITE4_ERROR; } |
︙ | ︙ | |||
1801 1802 1803 1804 1805 1806 1807 | if( pSel ){ u8 enableLookaside = db->lookaside.bEnabled; n = pParse->nTab; sqlite4SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; db->lookaside.bEnabled = 0; #ifndef SQLITE4_OMIT_AUTHORIZATION | | | | | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 | if( pSel ){ u8 enableLookaside = db->lookaside.bEnabled; n = pParse->nTab; sqlite4SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; db->lookaside.bEnabled = 0; #ifndef SQLITE4_OMIT_AUTHORIZATION pAuth = db->pAuth; db->pAuth = 0; pSelTab = sqlite4ResultSetOfSelect(pParse, pSel); db->pAuth = pAuth; #else pSelTab = sqlite4ResultSetOfSelect(pParse, pSel); #endif db->lookaside.bEnabled = enableLookaside; pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); |
︙ | ︙ | |||
2598 2599 2600 2601 2602 2603 2604 | ){ Index *pRet = 0; /* Pointer to return */ Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; /* Name of the index */ int i, j; Token nullId; /* Fake token for an empty ID list */ | < < | 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 | ){ Index *pRet = 0; /* Pointer to return */ Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; /* Name of the index */ int i, j; Token nullId; /* Fake token for an empty ID list */ sqlite4 *db = pParse->db; int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ ExprListItem *pListItem; /* For looping over pList */ int nExtra = 0; char *zExtra; assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */ |
︙ | ︙ | |||
2639 2640 2641 2642 2643 2644 2645 | assert( pName==0 ); assert( pStart==0 ); pTab = pParse->pNewTable; if( !pTab ) goto exit_create_index; iDb = sqlite4SchemaToIndex(db, pTab->pSchema); } | < | 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 | assert( pName==0 ); assert( pStart==0 ); pTab = pParse->pNewTable; if( !pTab ) goto exit_create_index; iDb = sqlite4SchemaToIndex(db, pTab->pSchema); } assert( pTab!=0 ); assert( pParse->nErr==0 ); assert( IsVirtual(pTab)==0 && IsView(pTab)==0 ); /* If pName==0 it means that we are dealing with a primary key or ** UNIQUE constraint. We have to invent our own name. */ |
︙ | ︙ |
Changes to src/fkey.c.
︙ | ︙ | |||
716 717 718 719 720 721 722 | aiCol = &iCol; } #ifndef SQLITE4_OMIT_AUTHORIZATION for(i=0; i<pFKey->nCol; i++){ /* Request permission to read the parent key columns. If the ** authorization callback returns SQLITE4_IGNORE, behave as if any ** values read from the parent table are NULL. */ | < | | | | < | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | aiCol = &iCol; } #ifndef SQLITE4_OMIT_AUTHORIZATION for(i=0; i<pFKey->nCol; i++){ /* Request permission to read the parent key columns. If the ** authorization callback returns SQLITE4_IGNORE, behave as if any ** values read from the parent table are NULL. */ int rcauth; char *zCol = pTo->aCol[pIdx->aiColumn[i]].zName; rcauth = sqlite4AuthReadCol(pParse, pTo->zName, zCol, iDb); isIgnore = (rcauth==SQLITE4_IGNORE); } #endif pParse->nTab++; if( regOld!=0 ){ /* A row is being removed from the child table. Search for the parent. ** If the parent does not exist, removing the child row resolves an |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
382 383 384 385 386 387 388 389 390 391 392 393 394 395 | sqlite4KVStoreClose(pDb->pKV); pDb->pKV = 0; } sqlite4DbFree(db, pDb->pSchema); pDb->pSchema = 0; } sqlite4ResetInternalSchema(db, -1); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. */ sqlite4ConnectionClosed(db); /* Delete tokenizers */ | > > > | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | sqlite4KVStoreClose(pDb->pKV); pDb->pKV = 0; } sqlite4DbFree(db, pDb->pSchema); pDb->pSchema = 0; } sqlite4ResetInternalSchema(db, -1); /* Free any authorizer callbacks */ sqlite4AuthFreeAll(db); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. */ sqlite4ConnectionClosed(db); /* Delete tokenizers */ |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
233 234 235 236 237 238 239 | { char *zSql; zSql = sqlite4MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", db->aDb[iDb].zName, zMasterName); #ifndef SQLITE4_OMIT_AUTHORIZATION { | | | | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | { char *zSql; zSql = sqlite4MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", db->aDb[iDb].zName, zMasterName); #ifndef SQLITE4_OMIT_AUTHORIZATION { Authorizer *pAuth; pAuth = db->pAuth; db->pAuth = 0; #endif rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData, 0); #ifndef SQLITE4_OMIT_AUTHORIZATION db->pAuth = pAuth; } #endif if( rc==SQLITE4_OK ) rc = initData.rc; sqlite4DbFree(db, zSql); #ifndef SQLITE4_OMIT_ANALYZE if( rc==SQLITE4_OK ){ sqlite4AnalysisLoad(db, iDb); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
1197 1198 1199 1200 1201 1202 1203 | ** ^A call to this routine stores N bytes of pseudo-randomness into buffer P. */ void sqlite4_randomness(sqlite4_env*, int N, void *P); /* ** CAPIREF: Compile-Time Authorization Callbacks ** | | | | | | < | | > | | | | | < < | < | > | > > | > | | | | | | | | < < | | < < < < | > > | > > | | | | | < < < > > > | < | | > > > > > | | < | > | | | < < < < < < < < < < < | > | > > | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 | ** ^A call to this routine stores N bytes of pseudo-randomness into buffer P. */ void sqlite4_randomness(sqlite4_env*, int N, void *P); /* ** CAPIREF: Compile-Time Authorization Callbacks ** ** These routines are used to register and deregister authorization ** callbacks with the database connection passed as the first argument. ** ** Each database connection has a stack of authorization callbacks, which ** may be empty. Calling sqlite4_authorizer_push() adds an authorization ** callback to the top of the stack, and calling sqlite4_authorizer_pop() ** removes the topmost authorizer. When an authorization callback is ** pushed onto the stack, the application may pass a pointer to a destructor ** function as the fourth argument to sqlite3_authorizer_push(). If the ** destructor function pointer is not NULL, then it is invoked with a copy ** of the second argument to sqlite4_authorizer_push() as the only argument ** when the authorizer function is popped off the stack, or when the database ** connection is closed. ** ** Authorization callbacks are invoked by SQLite4 from within ** sqlite4_prepare() and, when repreparing statements, from within ** sqlite3_step(). During SQL statement compilation (or recompilation), ** SQLite4 invokes the authorization callbacks for each action required ** to execute the statement. "Actions" are things like reading a value ** from a specific table column, modifying, inserting or deleting a row ** within a specific database table, or creating or dropping a schema ** object. The complete list of actions [SQLITE4_CREATE_INDEX | is here]. ** ** The first parameter passed to an authorizer callback is a copy of the ** second parameter passed to the sqlite4_authorizer_push() interface. The ** second parameter to the callback is an integer [SQLITE4_COPY | action code] ** that specifies the particular action to be authorized. The third through ** sixth parameters to the callback are zero-terminated strings that contain ** additional details about the action to be authorized. ** ** An authorization callback must return one of SQLITE4_OK, SQLITE4_IGNORE, ** SQLITE4_DENY or SQLITE4_ALLOW. If any other value is returned, it is an ** error. In this case, statement compilation fails and SQLITE4_ERROR is ** returned to the user. ** ** If an authorization callback returns SQLITE4_OK or SQLITE4_ALLOW, then ** SQLite4 interprets this as an indication that permission is granted for ** the specified action. If SQLITE4_DENY is returned, then permission has ** been denied and statement compilation fails. If SQLITE4_IGNORE is returned, ** and the requested action is to read a table column ([SQLITE4_READ]), then ** permission is denied but statement compilation is allowed to continue. ** In this case, instead of reading the required value from a table column, ** the database engine substitues an SQL NULL value instead. If SQLITE4_IGNORE ** is returned by an authorization callback requesting anything other than to ** read a table column, then statement compilation is allowed to continue, ** but the requested action is silently omitted. ** ** If there is more than one authorization callback on the stack when a ** statement is compiled (or recompiled), they are invoked in turn, starting ** with the callback on the top of the stack. If a single authorization ** callback returns SQLITE4_DENY, then permission for the action is denied ** and no further authorization callbacks are invoked. If one or more ** authorization callbacks return SQLITE4_IGNORE, but all others return ** SQLITE4_OK or SQLITE4_ALLOW, then the column value is replaced by an ** SQL NULL, as described above. If all authorization callbacks return ** SQLITE_OK or SQLITE_ALLOW, then the specified action is authorized and ** statement compilation proceeds. ** ** The difference between SQLITE4_OK and SQLITE4_ALLOW is as follows - if ** an authorization callback returns SQLITE4_ALLOW, then no further callbacks ** are invoked for the action. The action is either authorized (if all ** prior authorization callbacks returned SQLITE_OK) or ignored (if one or ** more earlier callbacks returned SQLITE4_IGNORE). ** ** An authorizer callback must not do anything that will modify the state ** of the database connection that invoked the authorizer callback. Note that ** [sqlite4_prepare()] and [sqlite4_step()] both modify the state of their ** database connections for the meaning of "modify" in this paragraph. */ int sqlite4_authorizer_push( sqlite4*, void *pCtx, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void (*xDestroy)(void*) ); int sqlite4_authorizer_pop(sqlite4*); /* ** CAPIREF: Authorizer Return Codes ** ** The [sqlite4_set_authorizer | authorizer callback function] must ** return either [SQLITE4_OK] or one of these two constants in order ** to signal SQLite whether or not the action is permitted. See the ** [sqlite4_set_authorizer | authorizer documentation] for additional ** information. ** ** Note that SQLITE4_IGNORE is also used as a [SQLITE4_ROLLBACK | return code] ** from the [sqlite4_vtab_on_conflict()] interface. */ #define SQLITE4_DENY 1 /* Abort the SQL statement with an error */ #define SQLITE4_IGNORE 2 /* Don't allow access, but don't generate an error */ #define SQLITE4_ALLOW 3 /* Allow access, do not invoke further callbacks */ /* ** CAPIREF: Authorizer Action Codes ** ** The [sqlite4_set_authorizer()] interface registers a callback function ** that is invoked to authorize certain SQL statement actions. The ** second parameter to the callback is an integer code that specifies |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
547 548 549 550 551 552 553 554 555 556 557 558 559 560 | /* ** Forward references to structures */ typedef struct AggInfo AggInfo; typedef struct AggInfoCol AggInfoCol; typedef struct AggInfoFunc AggInfoFunc; typedef struct AuthContext AuthContext; typedef struct AutoincInfo AutoincInfo; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct CreateIndex CreateIndex; typedef struct Db Db; typedef struct Schema Schema; | > | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | /* ** Forward references to structures */ typedef struct AggInfo AggInfo; typedef struct AggInfoCol AggInfoCol; typedef struct AggInfoFunc AggInfoFunc; typedef struct Authorizer Authorizer; typedef struct AuthContext AuthContext; typedef struct AutoincInfo AutoincInfo; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct CreateIndex CreateIndex; typedef struct Db Db; typedef struct Schema Schema; |
︙ | ︙ | |||
827 828 829 830 831 832 833 | char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ union { volatile int isInterrupted; /* True if sqlite4_interrupt has been called */ double notUsed1; /* Spacer */ } u1; Lookaside lookaside; /* Lookaside malloc configuration */ #ifndef SQLITE4_OMIT_AUTHORIZATION | < < | | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 | char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ union { volatile int isInterrupted; /* True if sqlite4_interrupt has been called */ double notUsed1; /* Spacer */ } u1; Lookaside lookaside; /* Lookaside malloc configuration */ #ifndef SQLITE4_OMIT_AUTHORIZATION Authorizer *pAuth; /* Head of authorizer callback stack */ #endif #ifndef SQLITE4_OMIT_PROGRESS_CALLBACK int (*xProgress)(void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif #ifndef SQLITE4_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 | void sqlite4DeferForeignKey(Parse*, int); #ifndef SQLITE4_OMIT_AUTHORIZATION void sqlite4AuthRead(Parse*,Expr*,Schema*,SrcList*); int sqlite4AuthCheck(Parse*,int, const char*, const char*, const char*); void sqlite4AuthContextPush(Parse*, AuthContext*, const char*); void sqlite4AuthContextPop(AuthContext*); int sqlite4AuthReadCol(Parse*, const char *, const char *, int); #else # define sqlite4AuthRead(a,b,c,d) # define sqlite4AuthCheck(a,b,c,d,e) SQLITE4_OK # define sqlite4AuthContextPush(a,b,c) # define sqlite4AuthContextPop(a) ((void)(a)) #endif void sqlite4Attach(Parse*, Expr*, Expr*, Expr*); void sqlite4Detach(Parse*, Expr*); int sqlite4FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite4FixSrcList(DbFixer*, SrcList*); int sqlite4FixSelect(DbFixer*, Select*); int sqlite4FixExpr(DbFixer*, Expr*); | > > | 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 | void sqlite4DeferForeignKey(Parse*, int); #ifndef SQLITE4_OMIT_AUTHORIZATION void sqlite4AuthRead(Parse*,Expr*,Schema*,SrcList*); int sqlite4AuthCheck(Parse*,int, const char*, const char*, const char*); void sqlite4AuthContextPush(Parse*, AuthContext*, const char*); void sqlite4AuthContextPop(AuthContext*); int sqlite4AuthReadCol(Parse*, const char *, const char *, int); void sqlite4AuthFreeAll(sqlite4 *db); #else # define sqlite4AuthRead(a,b,c,d) # define sqlite4AuthCheck(a,b,c,d,e) SQLITE4_OK # define sqlite4AuthContextPush(a,b,c) # define sqlite4AuthContextPop(a) ((void)(a)) # define sqlite4AuthFreeAll(a) #endif void sqlite4Attach(Parse*, Expr*, Expr*, Expr*); void sqlite4Detach(Parse*, Expr*); int sqlite4FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite4FixSrcList(DbFixer*, SrcList*); int sqlite4FixSelect(DbFixer*, Select*); int sqlite4FixExpr(DbFixer*, Expr*); |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 | Tcl_AppendResult(interp, pDb->zAuth, 0); } }else{ char *zAuth; int len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } zAuth = Tcl_GetStringFromObj(objv[2], &len); if( zAuth && len>0 ){ pDb->zAuth = Tcl_Alloc( len + 1 ); memcpy(pDb->zAuth, zAuth, len+1); }else{ pDb->zAuth = 0; } if( pDb->zAuth ){ pDb->interp = interp; | > | < > | > > | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | Tcl_AppendResult(interp, pDb->zAuth, 0); } }else{ char *zAuth; int len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); sqlite4_authorizer_pop(pDb->db); } zAuth = Tcl_GetStringFromObj(objv[2], &len); if( zAuth && len>0 ){ pDb->zAuth = Tcl_Alloc( len + 1 ); memcpy(pDb->zAuth, zAuth, len+1); }else{ pDb->zAuth = 0; } if( pDb->zAuth ){ pDb->interp = interp; rc = sqlite4_authorizer_push(pDb->db, pDb, auth_callback, 0); if( rc!=SQLITE4_OK ){ Tcl_SetResult(interp, (char *)sqlite4_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } } } #endif break; } /* $db cache flush |
︙ | ︙ |
Changes to test/auth.test.
︙ | ︙ | |||
950 951 952 953 954 955 956 | } set ::authargs {} execsql { INSERT INTO t2 VALUES(1,2,3); } set ::authargs } {SQLITE4_INSERT t2 {} main {} SQLITE4_INSERT tx {} main r2 SQLITE4_READ t2 ROWID main r2} | < < < < < | 950 951 952 953 954 955 956 957 958 959 960 961 962 963 | } set ::authargs {} execsql { INSERT INTO t2 VALUES(1,2,3); } set ::authargs } {SQLITE4_INSERT t2 {} main {} SQLITE4_INSERT tx {} main r2 SQLITE4_READ t2 ROWID main r2} do_test auth-1.137 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.138 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE4_CREATE_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] |
︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | } {1 {not authorized}} do_test auth-1.230 { set ::authargs } {full_column_names on {} {}} do_test auth-1.231 { execsql2 {SELECT a FROM t2} } {a 11 a 7} | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 | } {1 {not authorized}} do_test auth-1.230 { set ::authargs } {full_column_names on {} {}} do_test auth-1.231 { execsql2 {SELECT a FROM t2} } {a 11 a 7} do_test auth-1.239 { execsql2 {SELECT a FROM t2} } {a 11 a 7} do_test auth-1.240 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE4_TRANSACTION"} { |
︙ | ︙ | |||
1888 1889 1890 1891 1892 1893 1894 | } {t3_idx1 {} main {}} do_test auth-1.283 { set ::authargs {} execsql { REINDEX BINARY; } set ::authargs | | | | 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 | } {t3_idx1 {} main {}} do_test auth-1.283 { set ::authargs {} execsql { REINDEX BINARY; } set ::authargs } {t3_idx1 {} main {}} do_test auth-1.284 { set ::authargs {} execsql { REINDEX NOCASE; } set ::authargs } {t3_idx2 {} main {}} do_test auth-1.285 { set ::authargs {} execsql { REINDEX t3; } set ::authargs } {t3_idx2 {} main {} t3_idx1 {} main {}} do_test auth-1.286 { execsql { DROP TABLE t3; } } {} ifcapable tempdb { do_test auth-1.287 { |
︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 | } {t3_idx1 {} temp {}} do_test auth-1.289 { set ::authargs {} execsql { REINDEX BINARY; } set ::authargs | | | | 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 | } {t3_idx1 {} temp {}} do_test auth-1.289 { set ::authargs {} execsql { REINDEX BINARY; } set ::authargs } {t3_idx1 {} temp {}} do_test auth-1.290 { set ::authargs {} execsql { REINDEX NOCASE; } set ::authargs } {t3_idx2 {} temp {}} do_test auth-1.291 { set ::authargs {} execsql { REINDEX temp.t3; } set ::authargs } {t3_idx2 {} temp {} t3_idx1 {} temp {}} proc auth {code args} { if {$code=="SQLITE4_REINDEX"} { set ::authargs [concat $::authargs $args] return SQLITE4_DENY } return SQLITE4_OK } |
︙ | ︙ | |||
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 | DROP TABLE t3; } } {} } } ;# ifcapable reindex ifcapable analyze { proc auth {code args} { if {$code=="SQLITE4_ANALYZE"} { set ::authargs [concat $::authargs $args] } return SQLITE4_OK } do_test auth-1.294 { set ::authargs {} execsql { | > > > > > > > < < < < | 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 | DROP TABLE t3; } } {} } } ;# ifcapable reindex proc auth {code args} { return SQLITE4_OK } do_execsql_test auth-1.294a { CREATE TABLE t4(a,b,c); CREATE INDEX t4i1 ON t4(a); CREATE INDEX t4i2 ON t4(b,a,c); INSERT INTO t4 VALUES(1,2,3); } ifcapable analyze { proc auth {code args} { if {$code=="SQLITE4_ANALYZE"} { set ::authargs [concat $::authargs $args] } return SQLITE4_OK } do_test auth-1.294 { set ::authargs {} execsql { ANALYZE; } set ::authargs } {t4 {} main {} t2 {} main {}} do_test auth-1.295 { execsql { SELECT count(*) FROM sqlite_stat1; |
︙ | ︙ | |||
2091 2092 2093 2094 2095 2096 2097 | execsql {CREATE TABLE t3(x INTEGER PRIMARY KEY, y, z)} catchsql {SELECT * FROM t3} } {1 {access to t3.x is prohibited}} do_test auth-2.1 { catchsql {SELECT y,z FROM t3} } {0 {}} do_test auth-2.2 { | | | | | | 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 | execsql {CREATE TABLE t3(x INTEGER PRIMARY KEY, y, z)} catchsql {SELECT * FROM t3} } {1 {access to t3.x is prohibited}} do_test auth-2.1 { catchsql {SELECT y,z FROM t3} } {0 {}} do_test auth-2.2 { catchsql {SELECT x,y,z FROM t3} } {1 {access to t3.x is prohibited}} do_test auth-2.3 { catchsql {SELECT x,y,z FROM t3} } {1 {access to t3.x is prohibited}} do_test auth-2.4 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE4_READ" && $arg1=="t3" && $arg2=="x"} { return SQLITE4_IGNORE } return SQLITE4_OK } execsql {INSERT INTO t3 VALUES(44,55,66)} catchsql {SELECT * FROM t3} } {0 {{} 55 66}} do_test auth-2.5 { catchsql {SELECT x,y,z FROM t3} } {0 {{} 55 66}} do_test auth-2.6 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE4_READ" && $arg1=="t3" && $arg2=="ROWID"} { return SQLITE4_IGNORE } return SQLITE4_OK } catchsql {SELECT * FROM t3} } {0 {44 55 66}} do_test auth-2.7 { catchsql {SELECT x,y,z FROM t3} } {0 {44 55 66}} do_test auth-2.8 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE4_READ" && $arg1=="t2" && $arg2=="ROWID"} { return SQLITE4_IGNORE } return SQLITE4_OK |
︙ | ︙ | |||
2306 2307 2308 2309 2310 2311 2312 | execsql { SELECT count(a) AS cnt FROM t4 ORDER BY cnt } } {1} # Ticket #1607 # | | | 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 | execsql { SELECT count(a) AS cnt FROM t4 ORDER BY cnt } } {1} # Ticket #1607 # ifcapable compound&&subquery&&analyze { ifcapable trigger { execsql { DROP TABLE tx; } ifcapable view { execsql { DROP TABLE v1chng; |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
138 139 140 141 142 143 144 145 146 147 148 149 150 151 | lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test csr1.test ckpt1.test mc1.test fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test fts5snippet.test aggerror.test attach.test autoindex1.test badutf.test between.test bigrow.test bind.test | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | lsm1.test lsm2.test lsm3.test lsm4.test lsm5.test csr1.test ckpt1.test mc1.test fts5expr1.test fts5query1.test fts5rnd1.test fts5create.test fts5snippet.test auth.test auth2.test auth3.test aggerror.test attach.test autoindex1.test badutf.test between.test bigrow.test bind.test |
︙ | ︙ |