OLD | NEW |
| (Empty) |
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 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 | |
16 */ | |
17 #include "sqliteInt.h" | |
18 | |
19 /* | |
20 ** All of the code in this file may be omitted by defining a single | |
21 ** macro. | |
22 */ | |
23 #ifndef SQLITE_OMIT_AUTHORIZATION | |
24 | |
25 /* | |
26 ** Set or clear the access authorization function. | |
27 ** | |
28 ** The access authorization function is be called during the compilation | |
29 ** phase to verify that the user has read and/or write access permission on | |
30 ** various fields of the database. The first argument to the auth function | |
31 ** is a copy of the 3rd argument to this routine. The second argument | |
32 ** to the auth function is one of these constants: | |
33 ** | |
34 ** SQLITE_CREATE_INDEX | |
35 ** SQLITE_CREATE_TABLE | |
36 ** SQLITE_CREATE_TEMP_INDEX | |
37 ** SQLITE_CREATE_TEMP_TABLE | |
38 ** SQLITE_CREATE_TEMP_TRIGGER | |
39 ** SQLITE_CREATE_TEMP_VIEW | |
40 ** SQLITE_CREATE_TRIGGER | |
41 ** SQLITE_CREATE_VIEW | |
42 ** SQLITE_DELETE | |
43 ** SQLITE_DROP_INDEX | |
44 ** SQLITE_DROP_TABLE | |
45 ** SQLITE_DROP_TEMP_INDEX | |
46 ** SQLITE_DROP_TEMP_TABLE | |
47 ** SQLITE_DROP_TEMP_TRIGGER | |
48 ** SQLITE_DROP_TEMP_VIEW | |
49 ** SQLITE_DROP_TRIGGER | |
50 ** SQLITE_DROP_VIEW | |
51 ** SQLITE_INSERT | |
52 ** SQLITE_PRAGMA | |
53 ** SQLITE_READ | |
54 ** SQLITE_SELECT | |
55 ** SQLITE_TRANSACTION | |
56 ** SQLITE_UPDATE | |
57 ** | |
58 ** The third and fourth arguments to the auth function are the name of | |
59 ** the table and the column that are being accessed. The auth function | |
60 ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If | |
61 ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY | |
62 ** means that the SQL statement will never-run - the sqlite3_exec() call | |
63 ** will return with an error. SQLITE_IGNORE means that the SQL statement | |
64 ** should run but attempts to read the specified column will return NULL | |
65 ** and attempts to write the column will be ignored. | |
66 ** | |
67 ** Setting the auth function to NULL disables this hook. The default | |
68 ** setting of the auth function is NULL. | |
69 */ | |
70 int sqlite3_set_authorizer( | |
71 sqlite3 *db, | |
72 int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), | |
73 void *pArg | |
74 ){ | |
75 #ifdef SQLITE_ENABLE_API_ARMOR | |
76 if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; | |
77 #endif | |
78 sqlite3_mutex_enter(db->mutex); | |
79 db->xAuth = (sqlite3_xauth)xAuth; | |
80 db->pAuthArg = pArg; | |
81 sqlite3ExpirePreparedStatements(db); | |
82 sqlite3_mutex_leave(db->mutex); | |
83 return SQLITE_OK; | |
84 } | |
85 | |
86 /* | |
87 ** Write an error message into pParse->zErrMsg that explains that the | |
88 ** user-supplied authorization function returned an illegal value. | |
89 */ | |
90 static void sqliteAuthBadReturnCode(Parse *pParse){ | |
91 sqlite3ErrorMsg(pParse, "authorizer malfunction"); | |
92 pParse->rc = SQLITE_ERROR; | |
93 } | |
94 | |
95 /* | |
96 ** Invoke the authorization callback for permission to read column zCol from | |
97 ** table zTab in database zDb. This function assumes that an authorization | |
98 ** callback has been registered (i.e. that sqlite3.xAuth is not NULL). | |
99 ** | |
100 ** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed | |
101 ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE | |
102 ** is treated as SQLITE_DENY. In this case an error is left in pParse. | |
103 */ | |
104 int sqlite3AuthReadCol( | |
105 Parse *pParse, /* The parser context */ | |
106 const char *zTab, /* Table name */ | |
107 const char *zCol, /* Column name */ | |
108 int iDb /* Index of containing database. */ | |
109 ){ | |
110 sqlite3 *db = pParse->db; /* Database handle */ | |
111 char *zDb = db->aDb[iDb].zName; /* Name of attached database */ | |
112 int rc; /* Auth callback return code */ | |
113 | |
114 rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext | |
115 #ifdef SQLITE_USER_AUTHENTICATION | |
116 ,db->auth.zAuthUser | |
117 #endif | |
118 ); | |
119 if( rc==SQLITE_DENY ){ | |
120 if( db->nDb>2 || iDb!=0 ){ | |
121 sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); | |
122 }else{ | |
123 sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); | |
124 } | |
125 pParse->rc = SQLITE_AUTH; | |
126 }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ | |
127 sqliteAuthBadReturnCode(pParse); | |
128 } | |
129 return rc; | |
130 } | |
131 | |
132 /* | |
133 ** The pExpr should be a TK_COLUMN expression. The table referred to | |
134 ** is in pTabList or else it is the NEW or OLD table of a trigger. | |
135 ** Check to see if it is OK to read this particular column. | |
136 ** | |
137 ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN | |
138 ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, | |
139 ** then generate an error. | |
140 */ | |
141 void sqlite3AuthRead( | |
142 Parse *pParse, /* The parser context */ | |
143 Expr *pExpr, /* The expression to check authorization on */ | |
144 Schema *pSchema, /* The schema of the expression */ | |
145 SrcList *pTabList /* All table that pExpr might refer to */ | |
146 ){ | |
147 sqlite3 *db = pParse->db; | |
148 Table *pTab = 0; /* The table being read */ | |
149 const char *zCol; /* Name of the column of the table */ | |
150 int iSrc; /* Index in pTabList->a[] of table being read */ | |
151 int iDb; /* The index of the database the expression refers to */ | |
152 int iCol; /* Index of column in table */ | |
153 | |
154 if( db->xAuth==0 ) return; | |
155 iDb = sqlite3SchemaToIndex(pParse->db, pSchema); | |
156 if( iDb<0 ){ | |
157 /* An attempt to read a column out of a subquery or other | |
158 ** temporary table. */ | |
159 return; | |
160 } | |
161 | |
162 assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); | |
163 if( pExpr->op==TK_TRIGGER ){ | |
164 pTab = pParse->pTriggerTab; | |
165 }else{ | |
166 assert( pTabList ); | |
167 for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ | |
168 if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ | |
169 pTab = pTabList->a[iSrc].pTab; | |
170 break; | |
171 } | |
172 } | |
173 } | |
174 iCol = pExpr->iColumn; | |
175 if( NEVER(pTab==0) ) return; | |
176 | |
177 if( iCol>=0 ){ | |
178 assert( iCol<pTab->nCol ); | |
179 zCol = pTab->aCol[iCol].zName; | |
180 }else if( pTab->iPKey>=0 ){ | |
181 assert( pTab->iPKey<pTab->nCol ); | |
182 zCol = pTab->aCol[pTab->iPKey].zName; | |
183 }else{ | |
184 zCol = "ROWID"; | |
185 } | |
186 assert( iDb>=0 && iDb<db->nDb ); | |
187 if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ | |
188 pExpr->op = TK_NULL; | |
189 } | |
190 } | |
191 | |
192 /* | |
193 ** Do an authorization check using the code and arguments given. Return | |
194 ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY | |
195 ** is returned, then the error count and error message in pParse are | |
196 ** modified appropriately. | |
197 */ | |
198 int sqlite3AuthCheck( | |
199 Parse *pParse, | |
200 int code, | |
201 const char *zArg1, | |
202 const char *zArg2, | |
203 const char *zArg3 | |
204 ){ | |
205 sqlite3 *db = pParse->db; | |
206 int rc; | |
207 | |
208 /* Don't do any authorization checks if the database is initialising | |
209 ** or if the parser is being invoked from within sqlite3_declare_vtab. | |
210 */ | |
211 if( db->init.busy || IN_DECLARE_VTAB ){ | |
212 return SQLITE_OK; | |
213 } | |
214 | |
215 if( db->xAuth==0 ){ | |
216 return SQLITE_OK; | |
217 } | |
218 rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext | |
219 #ifdef SQLITE_USER_AUTHENTICATION | |
220 ,db->auth.zAuthUser | |
221 #endif | |
222 ); | |
223 if( rc==SQLITE_DENY ){ | |
224 sqlite3ErrorMsg(pParse, "not authorized"); | |
225 pParse->rc = SQLITE_AUTH; | |
226 }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ | |
227 rc = SQLITE_DENY; | |
228 sqliteAuthBadReturnCode(pParse); | |
229 } | |
230 return rc; | |
231 } | |
232 | |
233 /* | |
234 ** Push an authorization context. After this routine is called, the | |
235 ** zArg3 argument to authorization callbacks will be zContext until | |
236 ** popped. Or if pParse==0, this routine is a no-op. | |
237 */ | |
238 void sqlite3AuthContextPush( | |
239 Parse *pParse, | |
240 AuthContext *pContext, | |
241 const char *zContext | |
242 ){ | |
243 assert( pParse ); | |
244 pContext->pParse = pParse; | |
245 pContext->zAuthContext = pParse->zAuthContext; | |
246 pParse->zAuthContext = zContext; | |
247 } | |
248 | |
249 /* | |
250 ** Pop an authorization context that was previously pushed | |
251 ** by sqlite3AuthContextPush | |
252 */ | |
253 void sqlite3AuthContextPop(AuthContext *pContext){ | |
254 if( pContext->pParse ){ | |
255 pContext->pParse->zAuthContext = pContext->zAuthContext; | |
256 pContext->pParse = 0; | |
257 } | |
258 } | |
259 | |
260 #endif /* SQLITE_OMIT_AUTHORIZATION */ | |
OLD | NEW |