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 sqlite3_mutex_enter(db->mutex); | |
76 db->xAuth = (sqlite3_xauth)xAuth; | |
77 db->pAuthArg = pArg; | |
78 sqlite3ExpirePreparedStatements(db); | |
79 sqlite3_mutex_leave(db->mutex); | |
80 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 static void sqliteAuthBadReturnCode(Parse *pParse){ | |
88 sqlite3ErrorMsg(pParse, "authorizer malfunction"); | |
89 pParse->rc = SQLITE_ERROR; | |
90 } | |
91 | |
92 /* | |
93 ** Invoke the authorization callback for permission to read column zCol from | |
94 ** table zTab in database zDb. This function assumes that an authorization | |
95 ** callback has been registered (i.e. that sqlite3.xAuth is not NULL). | |
96 ** | |
97 ** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed | |
98 ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE | |
99 ** is treated as SQLITE_DENY. In this case an error is left in pParse. | |
100 */ | |
101 int sqlite3AuthReadCol( | |
102 Parse *pParse, /* The parser context */ | |
103 const char *zTab, /* Table name */ | |
104 const char *zCol, /* Column name */ | |
105 int iDb /* Index of containing database. */ | |
106 ){ | |
107 sqlite3 *db = pParse->db; /* Database handle */ | |
108 char *zDb = db->aDb[iDb].zName; /* Name of attached database */ | |
109 int rc; /* Auth callback return code */ | |
110 | |
111 rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext | |
112 #ifdef SQLITE_USER_AUTHENTICATION | |
113 ,db->auth.zAuthUser | |
114 #endif | |
115 ); | |
116 if( rc==SQLITE_DENY ){ | |
117 if( db->nDb>2 || iDb!=0 ){ | |
118 sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); | |
119 }else{ | |
120 sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); | |
121 } | |
122 pParse->rc = SQLITE_AUTH; | |
123 }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ | |
124 sqliteAuthBadReturnCode(pParse); | |
125 } | |
126 return rc; | |
127 } | |
128 | |
129 /* | |
130 ** The pExpr should be a TK_COLUMN expression. The table referred to | |
131 ** is in pTabList or else it is the NEW or OLD table of a trigger. | |
132 ** Check to see if it is OK to read this particular column. | |
133 ** | |
134 ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN | |
135 ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, | |
136 ** then generate an error. | |
137 */ | |
138 void sqlite3AuthRead( | |
139 Parse *pParse, /* The parser context */ | |
140 Expr *pExpr, /* The expression to check authorization on */ | |
141 Schema *pSchema, /* The schema of the expression */ | |
142 SrcList *pTabList /* All table that pExpr might refer to */ | |
143 ){ | |
144 sqlite3 *db = pParse->db; | |
145 Table *pTab = 0; /* The table being read */ | |
146 const char *zCol; /* Name of the column of the table */ | |
147 int iSrc; /* Index in pTabList->a[] of table being read */ | |
148 int iDb; /* The index of the database the expression refers to */ | |
149 int iCol; /* Index of column in table */ | |
150 | |
151 if( db->xAuth==0 ) return; | |
152 iDb = sqlite3SchemaToIndex(pParse->db, pSchema); | |
153 if( iDb<0 ){ | |
154 /* An attempt to read a column out of a subquery or other | |
155 ** temporary table. */ | |
156 return; | |
157 } | |
158 | |
159 assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); | |
160 if( pExpr->op==TK_TRIGGER ){ | |
161 pTab = pParse->pTriggerTab; | |
162 }else{ | |
163 assert( pTabList ); | |
164 for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ | |
165 if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ | |
166 pTab = pTabList->a[iSrc].pTab; | |
167 break; | |
168 } | |
169 } | |
170 } | |
171 iCol = pExpr->iColumn; | |
172 if( NEVER(pTab==0) ) return; | |
173 | |
174 if( iCol>=0 ){ | |
175 assert( iCol<pTab->nCol ); | |
176 zCol = pTab->aCol[iCol].zName; | |
177 }else if( pTab->iPKey>=0 ){ | |
178 assert( pTab->iPKey<pTab->nCol ); | |
179 zCol = pTab->aCol[pTab->iPKey].zName; | |
180 }else{ | |
181 zCol = "ROWID"; | |
182 } | |
183 assert( iDb>=0 && iDb<db->nDb ); | |
184 if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ | |
185 pExpr->op = TK_NULL; | |
186 } | |
187 } | |
188 | |
189 /* | |
190 ** Do an authorization check using the code and arguments given. Return | |
191 ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY | |
192 ** is returned, then the error count and error message in pParse are | |
193 ** modified appropriately. | |
194 */ | |
195 int sqlite3AuthCheck( | |
196 Parse *pParse, | |
197 int code, | |
198 const char *zArg1, | |
199 const char *zArg2, | |
200 const char *zArg3 | |
201 ){ | |
202 sqlite3 *db = pParse->db; | |
203 int rc; | |
204 | |
205 /* Don't do any authorization checks if the database is initialising | |
206 ** or if the parser is being invoked from within sqlite3_declare_vtab. | |
207 */ | |
208 if( db->init.busy || IN_DECLARE_VTAB ){ | |
209 return SQLITE_OK; | |
210 } | |
211 | |
212 if( db->xAuth==0 ){ | |
213 return SQLITE_OK; | |
214 } | |
215 rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext | |
216 #ifdef SQLITE_USER_AUTHENTICATION | |
217 ,db->auth.zAuthUser | |
218 #endif | |
219 ); | |
220 if( rc==SQLITE_DENY ){ | |
221 sqlite3ErrorMsg(pParse, "not authorized"); | |
222 pParse->rc = SQLITE_AUTH; | |
223 }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ | |
224 rc = SQLITE_DENY; | |
225 sqliteAuthBadReturnCode(pParse); | |
226 } | |
227 return rc; | |
228 } | |
229 | |
230 /* | |
231 ** Push an authorization context. After this routine is called, the | |
232 ** zArg3 argument to authorization callbacks will be zContext until | |
233 ** popped. Or if pParse==0, this routine is a no-op. | |
234 */ | |
235 void sqlite3AuthContextPush( | |
236 Parse *pParse, | |
237 AuthContext *pContext, | |
238 const char *zContext | |
239 ){ | |
240 assert( pParse ); | |
241 pContext->pParse = pParse; | |
242 pContext->zAuthContext = pParse->zAuthContext; | |
243 pParse->zAuthContext = zContext; | |
244 } | |
245 | |
246 /* | |
247 ** Pop an authorization context that was previously pushed | |
248 ** by sqlite3AuthContextPush | |
249 */ | |
250 void sqlite3AuthContextPop(AuthContext *pContext){ | |
251 if( pContext->pParse ){ | |
252 pContext->pParse->zAuthContext = pContext->zAuthContext; | |
253 pContext->pParse = 0; | |
254 } | |
255 } | |
256 | |
257 #endif /* SQLITE_OMIT_AUTHORIZATION */ | |
OLD | NEW |