1e6d01c3aSdrh /*
2e6d01c3aSdrh ** 2003 January 11
3e6d01c3aSdrh **
4e6d01c3aSdrh ** The author disclaims copyright to this source code. In place of
5e6d01c3aSdrh ** a legal notice, here is a blessing:
6e6d01c3aSdrh **
7e6d01c3aSdrh ** May you do good and not evil.
8e6d01c3aSdrh ** May you find forgiveness for yourself and forgive others.
9e6d01c3aSdrh ** May you share freely, never taking more than you give.
10e6d01c3aSdrh **
11e6d01c3aSdrh *************************************************************************
1224b03fd0Sdanielk1977 ** This file contains code used to implement the sqlite3_set_authorizer()
13e6d01c3aSdrh ** API. This facility is an optional feature of the library. Embedded
14e6d01c3aSdrh ** systems that do not need this facility may omit it by recompiling
15e6d01c3aSdrh ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
16e6d01c3aSdrh */
17e6d01c3aSdrh #include "sqliteInt.h"
18e6d01c3aSdrh
19e6d01c3aSdrh /*
20e6d01c3aSdrh ** All of the code in this file may be omitted by defining a single
21e6d01c3aSdrh ** macro.
22e6d01c3aSdrh */
23e6d01c3aSdrh #ifndef SQLITE_OMIT_AUTHORIZATION
24e6d01c3aSdrh
25e6d01c3aSdrh /*
26e6d01c3aSdrh ** Set or clear the access authorization function.
27e6d01c3aSdrh **
28e6d01c3aSdrh ** The access authorization function is be called during the compilation
295fe2d8c9Sdrh ** phase to verify that the user has read and/or write access permission on
30e6d01c3aSdrh ** various fields of the database. The first argument to the auth function
31e6d01c3aSdrh ** is a copy of the 3rd argument to this routine. The second argument
32e6d01c3aSdrh ** to the auth function is one of these constants:
33e6d01c3aSdrh **
345fe2d8c9Sdrh ** SQLITE_CREATE_INDEX
355fe2d8c9Sdrh ** SQLITE_CREATE_TABLE
365fe2d8c9Sdrh ** SQLITE_CREATE_TEMP_INDEX
375fe2d8c9Sdrh ** SQLITE_CREATE_TEMP_TABLE
385fe2d8c9Sdrh ** SQLITE_CREATE_TEMP_TRIGGER
395fe2d8c9Sdrh ** SQLITE_CREATE_TEMP_VIEW
405fe2d8c9Sdrh ** SQLITE_CREATE_TRIGGER
415fe2d8c9Sdrh ** SQLITE_CREATE_VIEW
425fe2d8c9Sdrh ** SQLITE_DELETE
435fe2d8c9Sdrh ** SQLITE_DROP_INDEX
445fe2d8c9Sdrh ** SQLITE_DROP_TABLE
455fe2d8c9Sdrh ** SQLITE_DROP_TEMP_INDEX
465fe2d8c9Sdrh ** SQLITE_DROP_TEMP_TABLE
475fe2d8c9Sdrh ** SQLITE_DROP_TEMP_TRIGGER
485fe2d8c9Sdrh ** SQLITE_DROP_TEMP_VIEW
495fe2d8c9Sdrh ** SQLITE_DROP_TRIGGER
505fe2d8c9Sdrh ** SQLITE_DROP_VIEW
515fe2d8c9Sdrh ** SQLITE_INSERT
525fe2d8c9Sdrh ** SQLITE_PRAGMA
535fe2d8c9Sdrh ** SQLITE_READ
545fe2d8c9Sdrh ** SQLITE_SELECT
555fe2d8c9Sdrh ** SQLITE_TRANSACTION
565fe2d8c9Sdrh ** SQLITE_UPDATE
57e6d01c3aSdrh **
58e6d01c3aSdrh ** The third and fourth arguments to the auth function are the name of
59e6d01c3aSdrh ** the table and the column that are being accessed. The auth function
60e6d01c3aSdrh ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
61e6d01c3aSdrh ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
6224b03fd0Sdanielk1977 ** means that the SQL statement will never-run - the sqlite3_exec() call
63e6d01c3aSdrh ** will return with an error. SQLITE_IGNORE means that the SQL statement
64e6d01c3aSdrh ** should run but attempts to read the specified column will return NULL
65e6d01c3aSdrh ** and attempts to write the column will be ignored.
66e6d01c3aSdrh **
67e6d01c3aSdrh ** Setting the auth function to NULL disables this hook. The default
68e6d01c3aSdrh ** setting of the auth function is NULL.
69e6d01c3aSdrh */
sqlite3_set_authorizer(sqlite3 * db,int (* xAuth)(void *,int,const char *,const char *,const char *,const char *),void * pArg)7024b03fd0Sdanielk1977 int sqlite3_set_authorizer(
719bb575fdSdrh sqlite3 *db,
72e22a334bSdrh int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
73e6d01c3aSdrh void *pArg
74e6d01c3aSdrh ){
759ca95730Sdrh #ifdef SQLITE_ENABLE_API_ARMOR
769ca95730Sdrh if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
779ca95730Sdrh #endif
78b21c8cd4Sdrh sqlite3_mutex_enter(db->mutex);
7932c6a48bSdrh db->xAuth = (sqlite3_xauth)xAuth;
80e6d01c3aSdrh db->pAuthArg = pArg;
81d744ee0bSdrh if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1);
82b21c8cd4Sdrh sqlite3_mutex_leave(db->mutex);
83e6d01c3aSdrh return SQLITE_OK;
84e6d01c3aSdrh }
85e6d01c3aSdrh
86e6d01c3aSdrh /*
87e6d01c3aSdrh ** Write an error message into pParse->zErrMsg that explains that the
88e6d01c3aSdrh ** user-supplied authorization function returned an illegal value.
89e6d01c3aSdrh */
sqliteAuthBadReturnCode(Parse * pParse)90ce9b0157Sdrh static void sqliteAuthBadReturnCode(Parse *pParse){
91ce9b0157Sdrh sqlite3ErrorMsg(pParse, "authorizer malfunction");
92c60d0446Sdrh pParse->rc = SQLITE_ERROR;
93e6d01c3aSdrh }
94e6d01c3aSdrh
95e6d01c3aSdrh /*
9647a06346Sdan ** Invoke the authorization callback for permission to read column zCol from
9747a06346Sdan ** table zTab in database zDb. This function assumes that an authorization
9847a06346Sdan ** callback has been registered (i.e. that sqlite3.xAuth is not NULL).
9947a06346Sdan **
10047a06346Sdan ** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed
10147a06346Sdan ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
10247a06346Sdan ** is treated as SQLITE_DENY. In this case an error is left in pParse.
10347a06346Sdan */
sqlite3AuthReadCol(Parse * pParse,const char * zTab,const char * zCol,int iDb)10402470b20Sdan int sqlite3AuthReadCol(
10547a06346Sdan Parse *pParse, /* The parser context */
10647a06346Sdan const char *zTab, /* Table name */
10747a06346Sdan const char *zCol, /* Column name */
10802470b20Sdan int iDb /* Index of containing database. */
10947a06346Sdan ){
11047a06346Sdan sqlite3 *db = pParse->db; /* Database handle */
11169c33826Sdrh char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
11247a06346Sdan int rc; /* Auth callback return code */
11347a06346Sdan
114a8914faaSdrh if( db->init.busy ) return SQLITE_OK;
11532c6a48bSdrh rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
11632c6a48bSdrh #ifdef SQLITE_USER_AUTHENTICATION
11732c6a48bSdrh ,db->auth.zAuthUser
11832c6a48bSdrh #endif
11932c6a48bSdrh );
12002470b20Sdan if( rc==SQLITE_DENY ){
1216f7fbcf0Sdrh char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
1226f7fbcf0Sdrh if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
1236f7fbcf0Sdrh sqlite3ErrorMsg(pParse, "access to %z is prohibited", z);
12447a06346Sdan pParse->rc = SQLITE_AUTH;
12502470b20Sdan }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
12602470b20Sdan sqliteAuthBadReturnCode(pParse);
12747a06346Sdan }
12802470b20Sdan return rc;
12947a06346Sdan }
13047a06346Sdan
13147a06346Sdan /*
132e6d01c3aSdrh ** The pExpr should be a TK_COLUMN expression. The table referred to
1336a3ea0e6Sdrh ** is in pTabList or else it is the NEW or OLD table of a trigger.
1346a3ea0e6Sdrh ** Check to see if it is OK to read this particular column.
135e6d01c3aSdrh **
136e6d01c3aSdrh ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
137e6d01c3aSdrh ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
138e6d01c3aSdrh ** then generate an error.
139e6d01c3aSdrh */
sqlite3AuthRead(Parse * pParse,Expr * pExpr,Schema * pSchema,SrcList * pTabList)1404adee20fSdanielk1977 void sqlite3AuthRead(
141e6d01c3aSdrh Parse *pParse, /* The parser context */
142e6d01c3aSdrh Expr *pExpr, /* The expression to check authorization on */
143728b5779Sdrh Schema *pSchema, /* The schema of the expression */
1446a3ea0e6Sdrh SrcList *pTabList /* All table that pExpr might refer to */
145e6d01c3aSdrh ){
146880c15beSdanielk1977 Table *pTab = 0; /* The table being read */
147027850b6Sdrh const char *zCol; /* Name of the column of the table */
148027850b6Sdrh int iSrc; /* Index in pTabList->a[] of table being read */
149da184236Sdanielk1977 int iDb; /* The index of the database the expression refers to */
1502bd93516Sdan int iCol; /* Index of column in table */
151027850b6Sdrh
1524344dbd3Sdrh assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
15329f6a365Sdrh assert( !IN_RENAME_OBJECT );
15429f6a365Sdrh assert( pParse->db->xAuth!=0 );
155728b5779Sdrh iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
156a3e4d96fSdrh if( iDb<0 ){
157a3e4d96fSdrh /* An attempt to read a column out of a subquery or other
158a3e4d96fSdrh ** temporary table. */
159a3e4d96fSdrh return;
160a3e4d96fSdrh }
1612bd93516Sdan
1622bd93516Sdan if( pExpr->op==TK_TRIGGER ){
1632bd93516Sdan pTab = pParse->pTriggerTab;
1642bd93516Sdan }else{
1652bd93516Sdan assert( pTabList );
1665f323787Sdrh for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
16734acdc95Sdanielk1977 if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
168027850b6Sdrh pTab = pTabList->a[iSrc].pTab;
16934acdc95Sdanielk1977 break;
17034acdc95Sdanielk1977 }
17134acdc95Sdanielk1977 }
17234acdc95Sdanielk1977 }
1732bd93516Sdan iCol = pExpr->iColumn;
1745f323787Sdrh if( pTab==0 ) return;
1752bd93516Sdan
1762bd93516Sdan if( iCol>=0 ){
1772bd93516Sdan assert( iCol<pTab->nCol );
178*cf9d36d1Sdrh zCol = pTab->aCol[iCol].zCnName;
179e6d01c3aSdrh }else if( pTab->iPKey>=0 ){
180e6d01c3aSdrh assert( pTab->iPKey<pTab->nCol );
181*cf9d36d1Sdrh zCol = pTab->aCol[pTab->iPKey].zCnName;
182e6d01c3aSdrh }else{
183e6d01c3aSdrh zCol = "ROWID";
184e6d01c3aSdrh }
18529f6a365Sdrh assert( iDb>=0 && iDb<pParse->db->nDb );
18602470b20Sdan if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
18702470b20Sdan pExpr->op = TK_NULL;
18802470b20Sdan }
189e6d01c3aSdrh }
190e6d01c3aSdrh
191e6d01c3aSdrh /*
192e5f9c644Sdrh ** Do an authorization check using the code and arguments given. Return
193e5f9c644Sdrh ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
194e5f9c644Sdrh ** is returned, then the error count and error message in pParse are
195e5f9c644Sdrh ** modified appropriately.
196e6d01c3aSdrh */
sqlite3AuthCheck(Parse * pParse,int code,const char * zArg1,const char * zArg2,const char * zArg3)1974adee20fSdanielk1977 int sqlite3AuthCheck(
198e5f9c644Sdrh Parse *pParse,
199e5f9c644Sdrh int code,
200e5f9c644Sdrh const char *zArg1,
201e22a334bSdrh const char *zArg2,
202e22a334bSdrh const char *zArg3
203e5f9c644Sdrh ){
2049bb575fdSdrh sqlite3 *db = pParse->db;
205e6d01c3aSdrh int rc;
206e22a334bSdrh
207f1a381e7Sdanielk1977 /* Don't do any authorization checks if the database is initialising
208f1a381e7Sdanielk1977 ** or if the parser is being invoked from within sqlite3_declare_vtab.
209f1a381e7Sdanielk1977 */
21007052d55Sdan assert( !IN_RENAME_OBJECT || db->xAuth==0 );
21169e856aeSdrh if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){
212e6d01c3aSdrh return SQLITE_OK;
213e6d01c3aSdrh }
2149418921cSdrh
2159418921cSdrh /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
2169418921cSdrh ** callback are either NULL pointers or zero-terminated strings that
2179418921cSdrh ** contain additional details about the action to be authorized.
2189418921cSdrh **
2199418921cSdrh ** The following testcase() macros show that any of the 3rd through 6th
2209418921cSdrh ** parameters can be either NULL or a string. */
2219418921cSdrh testcase( zArg1==0 );
2229418921cSdrh testcase( zArg2==0 );
2239418921cSdrh testcase( zArg3==0 );
2249418921cSdrh testcase( pParse->zAuthContext==0 );
2259418921cSdrh
22632c6a48bSdrh rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
22732c6a48bSdrh #ifdef SQLITE_USER_AUTHENTICATION
22832c6a48bSdrh ,db->auth.zAuthUser
22932c6a48bSdrh #endif
23032c6a48bSdrh );
231e5f9c644Sdrh if( rc==SQLITE_DENY ){
2324adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "not authorized");
233dcd997eaSdrh pParse->rc = SQLITE_AUTH;
234e6d01c3aSdrh }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
235e6d01c3aSdrh rc = SQLITE_DENY;
236ce9b0157Sdrh sqliteAuthBadReturnCode(pParse);
237e6d01c3aSdrh }
238e6d01c3aSdrh return rc;
239e6d01c3aSdrh }
240e6d01c3aSdrh
24185e2096fSdrh /*
24285e2096fSdrh ** Push an authorization context. After this routine is called, the
24385e2096fSdrh ** zArg3 argument to authorization callbacks will be zContext until
24485e2096fSdrh ** popped. Or if pParse==0, this routine is a no-op.
24585e2096fSdrh */
sqlite3AuthContextPush(Parse * pParse,AuthContext * pContext,const char * zContext)2464adee20fSdanielk1977 void sqlite3AuthContextPush(
24785e2096fSdrh Parse *pParse,
24885e2096fSdrh AuthContext *pContext,
24985e2096fSdrh const char *zContext
25085e2096fSdrh ){
251eba661f8Sdrh assert( pParse );
25285e2096fSdrh pContext->pParse = pParse;
25385e2096fSdrh pContext->zAuthContext = pParse->zAuthContext;
25485e2096fSdrh pParse->zAuthContext = zContext;
25585e2096fSdrh }
25685e2096fSdrh
25785e2096fSdrh /*
25885e2096fSdrh ** Pop an authorization context that was previously pushed
2594adee20fSdanielk1977 ** by sqlite3AuthContextPush
26085e2096fSdrh */
sqlite3AuthContextPop(AuthContext * pContext)2614adee20fSdanielk1977 void sqlite3AuthContextPop(AuthContext *pContext){
26285e2096fSdrh if( pContext->pParse ){
26385e2096fSdrh pContext->pParse->zAuthContext = pContext->zAuthContext;
26485e2096fSdrh pContext->pParse = 0;
26585e2096fSdrh }
26685e2096fSdrh }
26785e2096fSdrh
268e6d01c3aSdrh #endif /* SQLITE_OMIT_AUTHORIZATION */
269