diff options
Diffstat (limited to 'libraries/sqlite/win32/auth.c')
-rwxr-xr-x | libraries/sqlite/win32/auth.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/auth.c b/libraries/sqlite/win32/auth.c new file mode 100755 index 0000000..5630c23 --- /dev/null +++ b/libraries/sqlite/win32/auth.c | |||
@@ -0,0 +1,234 @@ | |||
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 | ** $Id: auth.c,v 1.29 2007/09/18 15:55:07 drh 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_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 | ||
43 | ** SQLITE_CREATE_VIEW | ||
44 | ** SQLITE_DELETE | ||
45 | ** SQLITE_DROP_INDEX | ||
46 | ** SQLITE_DROP_TABLE | ||
47 | ** SQLITE_DROP_TEMP_INDEX | ||
48 | ** SQLITE_DROP_TEMP_TABLE | ||
49 | ** SQLITE_DROP_TEMP_TRIGGER | ||
50 | ** SQLITE_DROP_TEMP_VIEW | ||
51 | ** SQLITE_DROP_TRIGGER | ||
52 | ** SQLITE_DROP_VIEW | ||
53 | ** SQLITE_INSERT | ||
54 | ** SQLITE_PRAGMA | ||
55 | ** SQLITE_READ | ||
56 | ** SQLITE_SELECT | ||
57 | ** SQLITE_TRANSACTION | ||
58 | ** SQLITE_UPDATE | ||
59 | ** | ||
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. | ||
68 | ** | ||
69 | ** Setting the auth function to NULL disables this hook. The default | ||
70 | ** setting of the auth function is NULL. | ||
71 | */ | ||
72 | int sqlite3_set_authorizer( | ||
73 | sqlite3 *db, | ||
74 | int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), | ||
75 | void *pArg | ||
76 | ){ | ||
77 | sqlite3_mutex_enter(db->mutex); | ||
78 | db->xAuth = xAuth; | ||
79 | db->pAuthArg = pArg; | ||
80 | sqlite3ExpirePreparedStatements(db); | ||
81 | sqlite3_mutex_leave(db->mutex); | ||
82 | return SQLITE_OK; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | ** Write an error message into pParse->zErrMsg that explains that the | ||
87 | ** user-supplied authorization function returned an illegal value. | ||
88 | */ | ||
89 | static void sqliteAuthBadReturnCode(Parse *pParse, int rc){ | ||
90 | sqlite3ErrorMsg(pParse, "illegal return value (%d) from the " | ||
91 | "authorization function - should be SQLITE_OK, SQLITE_IGNORE, " | ||
92 | "or SQLITE_DENY", rc); | ||
93 | pParse->rc = SQLITE_ERROR; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | ** The pExpr should be a TK_COLUMN expression. The table referred to | ||
98 | ** is in pTabList or else it is the NEW or OLD table of a trigger. | ||
99 | ** Check to see if it is OK to read this particular column. | ||
100 | ** | ||
101 | ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN | ||
102 | ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, | ||
103 | ** then generate an error. | ||
104 | */ | ||
105 | void sqlite3AuthRead( | ||
106 | Parse *pParse, /* The parser context */ | ||
107 | Expr *pExpr, /* The expression to check authorization on */ | ||
108 | Schema *pSchema, /* The schema of the expression */ | ||
109 | SrcList *pTabList /* All table that pExpr might refer to */ | ||
110 | ){ | ||
111 | sqlite3 *db = pParse->db; | ||
112 | int rc; | ||
113 | Table *pTab = 0; /* The table being read */ | ||
114 | const char *zCol; /* Name of the column of the table */ | ||
115 | int iSrc; /* Index in pTabList->a[] of table being read */ | ||
116 | const char *zDBase; /* Name of database being accessed */ | ||
117 | TriggerStack *pStack; /* The stack of current triggers */ | ||
118 | int iDb; /* The index of the database the expression refers to */ | ||
119 | |||
120 | if( db->xAuth==0 ) return; | ||
121 | if( pExpr->op!=TK_COLUMN ) return; | ||
122 | iDb = sqlite3SchemaToIndex(pParse->db, pSchema); | ||
123 | if( iDb<0 ){ | ||
124 | /* An attempt to read a column out of a subquery or other | ||
125 | ** temporary table. */ | ||
126 | return; | ||
127 | } | ||
128 | for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){ | ||
129 | if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; | ||
130 | } | ||
131 | if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){ | ||
132 | pTab = pTabList->a[iSrc].pTab; | ||
133 | }else if( (pStack = pParse->trigStack)!=0 ){ | ||
134 | /* This must be an attempt to read the NEW or OLD pseudo-tables | ||
135 | ** of a trigger. | ||
136 | */ | ||
137 | assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx ); | ||
138 | pTab = pStack->pTab; | ||
139 | } | ||
140 | if( pTab==0 ) return; | ||
141 | if( pExpr->iColumn>=0 ){ | ||
142 | assert( pExpr->iColumn<pTab->nCol ); | ||
143 | zCol = pTab->aCol[pExpr->iColumn].zName; | ||
144 | }else if( pTab->iPKey>=0 ){ | ||
145 | assert( pTab->iPKey<pTab->nCol ); | ||
146 | zCol = pTab->aCol[pTab->iPKey].zName; | ||
147 | }else{ | ||
148 | zCol = "ROWID"; | ||
149 | } | ||
150 | assert( iDb>=0 && iDb<db->nDb ); | ||
151 | zDBase = db->aDb[iDb].zName; | ||
152 | rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, | ||
153 | pParse->zAuthContext); | ||
154 | if( rc==SQLITE_IGNORE ){ | ||
155 | pExpr->op = TK_NULL; | ||
156 | }else if( rc==SQLITE_DENY ){ | ||
157 | if( db->nDb>2 || iDb!=0 ){ | ||
158 | sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", | ||
159 | zDBase, pTab->zName, zCol); | ||
160 | }else{ | ||
161 | sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol); | ||
162 | } | ||
163 | pParse->rc = SQLITE_AUTH; | ||
164 | }else if( rc!=SQLITE_OK ){ | ||
165 | sqliteAuthBadReturnCode(pParse, rc); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | ** Do an authorization check using the code and arguments given. Return | ||
171 | ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY | ||
172 | ** is returned, then the error count and error message in pParse are | ||
173 | ** modified appropriately. | ||
174 | */ | ||
175 | int sqlite3AuthCheck( | ||
176 | Parse *pParse, | ||
177 | int code, | ||
178 | const char *zArg1, | ||
179 | const char *zArg2, | ||
180 | const char *zArg3 | ||
181 | ){ | ||
182 | sqlite3 *db = pParse->db; | ||
183 | int rc; | ||
184 | |||
185 | /* Don't do any authorization checks if the database is initialising | ||
186 | ** or if the parser is being invoked from within sqlite3_declare_vtab. | ||
187 | */ | ||
188 | if( db->init.busy || IN_DECLARE_VTAB ){ | ||
189 | return SQLITE_OK; | ||
190 | } | ||
191 | |||
192 | if( db->xAuth==0 ){ | ||
193 | return SQLITE_OK; | ||
194 | } | ||
195 | rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext); | ||
196 | if( rc==SQLITE_DENY ){ | ||
197 | sqlite3ErrorMsg(pParse, "not authorized"); | ||
198 | pParse->rc = SQLITE_AUTH; | ||
199 | }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ | ||
200 | rc = SQLITE_DENY; | ||
201 | sqliteAuthBadReturnCode(pParse, rc); | ||
202 | } | ||
203 | return rc; | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | ** Push an authorization context. After this routine is called, the | ||
208 | ** zArg3 argument to authorization callbacks will be zContext until | ||
209 | ** popped. Or if pParse==0, this routine is a no-op. | ||
210 | */ | ||
211 | void sqlite3AuthContextPush( | ||
212 | Parse *pParse, | ||
213 | AuthContext *pContext, | ||
214 | const char *zContext | ||
215 | ){ | ||
216 | pContext->pParse = pParse; | ||
217 | if( pParse ){ | ||
218 | pContext->zAuthContext = pParse->zAuthContext; | ||
219 | pParse->zAuthContext = zContext; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | ** Pop an authorization context that was previously pushed | ||
225 | ** by sqlite3AuthContextPush | ||
226 | */ | ||
227 | void sqlite3AuthContextPop(AuthContext *pContext){ | ||
228 | if( pContext->pParse ){ | ||
229 | pContext->pParse->zAuthContext = pContext->zAuthContext; | ||
230 | pContext->pParse = 0; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | #endif /* SQLITE_OMIT_AUTHORIZATION */ | ||