4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
12 ** This file contains code used to implement the sqlite3_set_authorizer()
13 ** API. This facility is an optional feature of the library. Embedded
14 ** systems that do not need this facility may omit it by recompiling
15 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
19 #include "sqliteInt.h"
22 ** All of the code in this file may be omitted by defining a single
25 #ifndef SQLITE_OMIT_AUTHORIZATION
28 ** Set or clear the access authorization function.
30 ** The access authorization function is be called during the compilation
31 ** phase to verify that the user has read and/or write access permission on
32 ** various fields of the database. The first argument to the auth function
33 ** is a copy of the 3rd argument to this routine. The second argument
34 ** to the auth function is one of these constants:
36 ** SQLITE_CREATE_INDEX
37 ** SQLITE_CREATE_TABLE
38 ** SQLITE_CREATE_TEMP_INDEX
39 ** SQLITE_CREATE_TEMP_TABLE
40 ** SQLITE_CREATE_TEMP_TRIGGER
41 ** SQLITE_CREATE_TEMP_VIEW
42 ** SQLITE_CREATE_TRIGGER
47 ** SQLITE_DROP_TEMP_INDEX
48 ** SQLITE_DROP_TEMP_TABLE
49 ** SQLITE_DROP_TEMP_TRIGGER
50 ** SQLITE_DROP_TEMP_VIEW
51 ** SQLITE_DROP_TRIGGER
60 ** The third and fourth arguments to the auth function are the name of
61 ** the table and the column that are being accessed. The auth function
62 ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
63 ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
64 ** means that the SQL statement will never-run - the sqlite3_exec() call
65 ** will return with an error. SQLITE_IGNORE means that the SQL statement
66 ** should run but attempts to read the specified column will return NULL
67 ** and attempts to write the column will be ignored.
69 ** Setting the auth function to NULL disables this hook. The default
70 ** setting of the auth function is NULL.
72 int sqlite3_set_authorizer(
74 int (*xAuth
)(void*,int,const char*,const char*,const char*,const char*),
79 sqlite3ExpirePreparedStatements(db
);
84 ** Write an error message into pParse->zErrMsg that explains that the
85 ** user-supplied authorization function returned an illegal value.
87 static void sqliteAuthBadReturnCode(Parse
*pParse
, int rc
){
88 sqlite3ErrorMsg(pParse
, "illegal return value (%d) from the "
89 "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
90 "or SQLITE_DENY", rc
);
91 pParse
->rc
= SQLITE_ERROR
;
95 ** The pExpr should be a TK_COLUMN expression. The table referred to
96 ** is in pTabList or else it is the NEW or OLD table of a trigger.
97 ** Check to see if it is OK to read this particular column.
99 ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
100 ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
101 ** then generate an error.
103 void sqlite3AuthRead(
104 Parse
*pParse
, /* The parser context */
105 Expr
*pExpr
, /* The expression to check authorization on */
106 SrcList
*pTabList
/* All table that pExpr might refer to */
108 sqlite3
*db
= pParse
->db
;
110 Table
*pTab
; /* The table being read */
111 const char *zCol
; /* Name of the column of the table */
112 int iSrc
; /* Index in pTabList->a[] of table being read */
113 const char *zDBase
; /* Name of database being accessed */
114 TriggerStack
*pStack
; /* The stack of current triggers */
116 if( db
->xAuth
==0 ) return;
117 assert( pExpr
->op
==TK_COLUMN
);
118 for(iSrc
=0; pTabList
&& iSrc
<pTabList
->nSrc
; iSrc
++){
119 if( pExpr
->iTable
==pTabList
->a
[iSrc
].iCursor
) break;
121 if( iSrc
>=0 && pTabList
&& iSrc
<pTabList
->nSrc
){
122 pTab
= pTabList
->a
[iSrc
].pTab
;
123 }else if( (pStack
= pParse
->trigStack
)!=0 ){
124 /* This must be an attempt to read the NEW or OLD pseudo-tables
127 assert( pExpr
->iTable
==pStack
->newIdx
|| pExpr
->iTable
==pStack
->oldIdx
);
132 if( pTab
==0 ) return;
133 if( pExpr
->iColumn
>=0 ){
134 assert( pExpr
->iColumn
<pTab
->nCol
);
135 zCol
= pTab
->aCol
[pExpr
->iColumn
].zName
;
136 }else if( pTab
->iPKey
>=0 ){
137 assert( pTab
->iPKey
<pTab
->nCol
);
138 zCol
= pTab
->aCol
[pTab
->iPKey
].zName
;
142 assert( pExpr
->iDb
<db
->nDb
);
143 zDBase
= db
->aDb
[pExpr
->iDb
].zName
;
144 rc
= db
->xAuth(db
->pAuthArg
, SQLITE_READ
, pTab
->zName
, zCol
, zDBase
,
145 pParse
->zAuthContext
);
146 if( rc
==SQLITE_IGNORE
){
148 }else if( rc
==SQLITE_DENY
){
149 if( db
->nDb
>2 || pExpr
->iDb
!=0 ){
150 sqlite3ErrorMsg(pParse
, "access to %s.%s.%s is prohibited",
151 zDBase
, pTab
->zName
, zCol
);
153 sqlite3ErrorMsg(pParse
, "access to %s.%s is prohibited",pTab
->zName
,zCol
);
155 pParse
->rc
= SQLITE_AUTH
;
156 }else if( rc
!=SQLITE_OK
){
157 sqliteAuthBadReturnCode(pParse
, rc
);
162 ** Do an authorization check using the code and arguments given. Return
163 ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
164 ** is returned, then the error count and error message in pParse are
165 ** modified appropriately.
167 int sqlite3AuthCheck(
174 sqlite3
*db
= pParse
->db
;
177 /* Don't do any authorization checks if the database is initialising. */
185 rc
= db
->xAuth(db
->pAuthArg
, code
, zArg1
, zArg2
, zArg3
, pParse
->zAuthContext
);
186 if( rc
==SQLITE_DENY
){
187 sqlite3ErrorMsg(pParse
, "not authorized");
188 pParse
->rc
= SQLITE_AUTH
;
189 }else if( rc
!=SQLITE_OK
&& rc
!=SQLITE_IGNORE
){
191 sqliteAuthBadReturnCode(pParse
, rc
);
197 ** Push an authorization context. After this routine is called, the
198 ** zArg3 argument to authorization callbacks will be zContext until
199 ** popped. Or if pParse==0, this routine is a no-op.
201 void sqlite3AuthContextPush(
203 AuthContext
*pContext
,
206 pContext
->pParse
= pParse
;
208 pContext
->zAuthContext
= pParse
->zAuthContext
;
209 pParse
->zAuthContext
= zContext
;
214 ** Pop an authorization context that was previously pushed
215 ** by sqlite3AuthContextPush
217 void sqlite3AuthContextPop(AuthContext
*pContext
){
218 if( pContext
->pParse
){
219 pContext
->pParse
->zAuthContext
= pContext
->zAuthContext
;
220 pContext
->pParse
= 0;
224 #endif /* SQLITE_OMIT_AUTHORIZATION */