File Coverage

auth.c
Criterion Covered Total %
statement 10 57 17.5
branch 5 40 12.5
condition n/a
subroutine n/a
pod n/a
total 15 97 15.4


line stmt bran cond sub pod time code
1             /*
2             ** 2003 January 11
3             **
4             ** The author disclaims copyright to this source code. In place of
5             ** a legal notice, here is a blessing:
6             **
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.
10             **
11             *************************************************************************
12             ** This file contains code used to implement the sqlite_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
16             **
17             ** $Id: auth.c,v 1.1.1.1 2004/08/08 15:03:56 matt Exp $
18             */
19             #include "sqliteInt.h"
20              
21             /*
22             ** All of the code in this file may be omitted by defining a single
23             ** macro.
24             */
25             #ifndef SQLITE_OMIT_AUTHORIZATION
26              
27             /*
28             ** Set or clear the access authorization function.
29             **
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:
35             **
36             ** SQLITE_COPY
37             ** SQLITE_CREATE_INDEX
38             ** SQLITE_CREATE_TABLE
39             ** SQLITE_CREATE_TEMP_INDEX
40             ** SQLITE_CREATE_TEMP_TABLE
41             ** SQLITE_CREATE_TEMP_TRIGGER
42             ** SQLITE_CREATE_TEMP_VIEW
43             ** SQLITE_CREATE_TRIGGER
44             ** SQLITE_CREATE_VIEW
45             ** SQLITE_DELETE
46             ** SQLITE_DROP_INDEX
47             ** SQLITE_DROP_TABLE
48             ** SQLITE_DROP_TEMP_INDEX
49             ** SQLITE_DROP_TEMP_TABLE
50             ** SQLITE_DROP_TEMP_TRIGGER
51             ** SQLITE_DROP_TEMP_VIEW
52             ** SQLITE_DROP_TRIGGER
53             ** SQLITE_DROP_VIEW
54             ** SQLITE_INSERT
55             ** SQLITE_PRAGMA
56             ** SQLITE_READ
57             ** SQLITE_SELECT
58             ** SQLITE_TRANSACTION
59             ** SQLITE_UPDATE
60             **
61             ** The third and fourth arguments to the auth function are the name of
62             ** the table and the column that are being accessed. The auth function
63             ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
64             ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
65             ** means that the SQL statement will never-run - the sqlite_exec() call
66             ** will return with an error. SQLITE_IGNORE means that the SQL statement
67             ** should run but attempts to read the specified column will return NULL
68             ** and attempts to write the column will be ignored.
69             **
70             ** Setting the auth function to NULL disables this hook. The default
71             ** setting of the auth function is NULL.
72             */
73 0           int sqlite_set_authorizer(
74             sqlite *db,
75             int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
76             void *pArg
77             ){
78 0           db->xAuth = xAuth;
79 0           db->pAuthArg = pArg;
80 0           return SQLITE_OK;
81             }
82              
83             /*
84             ** Write an error message into pParse->zErrMsg that explains that the
85             ** user-supplied authorization function returned an illegal value.
86             */
87 0           static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
88 0           sqliteErrorMsg(pParse, "illegal return value (%d) from the "
89             "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
90             "or SQLITE_DENY", rc);
91 0           pParse->rc = SQLITE_MISUSE;
92 0           }
93              
94             /*
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.
98             **
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.
102             */
103 389           void sqliteAuthRead(
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 */
107             ){
108 389           sqlite *db = pParse->db;
109             int rc;
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              
115 389 50         if( db->xAuth==0 ) return;
116             assert( pExpr->op==TK_COLUMN );
117 0 0         for(iSrc=0; iSrcnSrc; iSrc++){
118 0 0         if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
119             }
120 0 0         if( iSrc>=0 && iSrcnSrc ){
    0          
121 0           pTab = pTabList->a[iSrc].pTab;
122             }else{
123             /* This must be an attempt to read the NEW or OLD pseudo-tables
124             ** of a trigger.
125             */
126             TriggerStack *pStack; /* The stack of current triggers */
127 0           pStack = pParse->trigStack;
128             assert( pStack!=0 );
129             assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
130 0           pTab = pStack->pTab;
131             }
132 0 0         if( pTab==0 ) return;
133 0 0         if( pExpr->iColumn>=0 ){
134             assert( pExpr->iColumnnCol );
135 0           zCol = pTab->aCol[pExpr->iColumn].zName;
136 0 0         }else if( pTab->iPKey>=0 ){
137             assert( pTab->iPKeynCol );
138 0           zCol = pTab->aCol[pTab->iPKey].zName;
139             }else{
140 0           zCol = "ROWID";
141             }
142             assert( pExpr->iDbnDb );
143 0           zDBase = db->aDb[pExpr->iDb].zName;
144 0           rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase,
145             pParse->zAuthContext);
146 0 0         if( rc==SQLITE_IGNORE ){
147 0           pExpr->op = TK_NULL;
148 0 0         }else if( rc==SQLITE_DENY ){
149 0 0         if( db->nDb>2 || pExpr->iDb!=0 ){
    0          
150 0           sqliteErrorMsg(pParse, "access to %s.%s.%s is prohibited",
151             zDBase, pTab->zName, zCol);
152             }else{
153 0           sqliteErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
154             }
155 0           pParse->rc = SQLITE_AUTH;
156 0 0         }else if( rc!=SQLITE_OK ){
157 0           sqliteAuthBadReturnCode(pParse, rc);
158             }
159             }
160              
161             /*
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.
166             */
167 492           int sqliteAuthCheck(
168             Parse *pParse,
169             int code,
170             const char *zArg1,
171             const char *zArg2,
172             const char *zArg3
173             ){
174 492           sqlite *db = pParse->db;
175             int rc;
176              
177 492 100         if( db->init.busy || db->xAuth==0 ){
    50          
178 492           return SQLITE_OK;
179             }
180 0           rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
181 0 0         if( rc==SQLITE_DENY ){
182 0           sqliteErrorMsg(pParse, "not authorized");
183 0           pParse->rc = SQLITE_AUTH;
184 0 0         }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
    0          
185 0           rc = SQLITE_DENY;
186 0           sqliteAuthBadReturnCode(pParse, rc);
187             }
188 0           return rc;
189             }
190              
191             /*
192             ** Push an authorization context. After this routine is called, the
193             ** zArg3 argument to authorization callbacks will be zContext until
194             ** popped. Or if pParse==0, this routine is a no-op.
195             */
196 0           void sqliteAuthContextPush(
197             Parse *pParse,
198             AuthContext *pContext,
199             const char *zContext
200             ){
201 0           pContext->pParse = pParse;
202 0 0         if( pParse ){
203 0           pContext->zAuthContext = pParse->zAuthContext;
204 0           pParse->zAuthContext = zContext;
205             }
206 0           }
207              
208             /*
209             ** Pop an authorization context that was previously pushed
210             ** by sqliteAuthContextPush
211             */
212 6           void sqliteAuthContextPop(AuthContext *pContext){
213 6 50         if( pContext->pParse ){
214 0           pContext->pParse->zAuthContext = pContext->zAuthContext;
215 0           pContext->pParse = 0;
216             }
217 6           }
218              
219             #endif /* SQLITE_OMIT_AUTHORIZATION */