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