Annotation of embedaddon/sqlite3/src/auth.c, revision 1.1.1.1
1.1 misho 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 = 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: if( rc==SQLITE_DENY ){
113: if( db->nDb>2 || iDb!=0 ){
114: sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
115: }else{
116: sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
117: }
118: pParse->rc = SQLITE_AUTH;
119: }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
120: sqliteAuthBadReturnCode(pParse);
121: }
122: return rc;
123: }
124:
125: /*
126: ** The pExpr should be a TK_COLUMN expression. The table referred to
127: ** is in pTabList or else it is the NEW or OLD table of a trigger.
128: ** Check to see if it is OK to read this particular column.
129: **
130: ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
131: ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
132: ** then generate an error.
133: */
134: void sqlite3AuthRead(
135: Parse *pParse, /* The parser context */
136: Expr *pExpr, /* The expression to check authorization on */
137: Schema *pSchema, /* The schema of the expression */
138: SrcList *pTabList /* All table that pExpr might refer to */
139: ){
140: sqlite3 *db = pParse->db;
141: Table *pTab = 0; /* The table being read */
142: const char *zCol; /* Name of the column of the table */
143: int iSrc; /* Index in pTabList->a[] of table being read */
144: int iDb; /* The index of the database the expression refers to */
145: int iCol; /* Index of column in table */
146:
147: if( db->xAuth==0 ) return;
148: iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
149: if( iDb<0 ){
150: /* An attempt to read a column out of a subquery or other
151: ** temporary table. */
152: return;
153: }
154:
155: assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
156: if( pExpr->op==TK_TRIGGER ){
157: pTab = pParse->pTriggerTab;
158: }else{
159: assert( pTabList );
160: for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
161: if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
162: pTab = pTabList->a[iSrc].pTab;
163: break;
164: }
165: }
166: }
167: iCol = pExpr->iColumn;
168: if( NEVER(pTab==0) ) return;
169:
170: if( iCol>=0 ){
171: assert( iCol<pTab->nCol );
172: zCol = pTab->aCol[iCol].zName;
173: }else if( pTab->iPKey>=0 ){
174: assert( pTab->iPKey<pTab->nCol );
175: zCol = pTab->aCol[pTab->iPKey].zName;
176: }else{
177: zCol = "ROWID";
178: }
179: assert( iDb>=0 && iDb<db->nDb );
180: if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
181: pExpr->op = TK_NULL;
182: }
183: }
184:
185: /*
186: ** Do an authorization check using the code and arguments given. Return
187: ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
188: ** is returned, then the error count and error message in pParse are
189: ** modified appropriately.
190: */
191: int sqlite3AuthCheck(
192: Parse *pParse,
193: int code,
194: const char *zArg1,
195: const char *zArg2,
196: const char *zArg3
197: ){
198: sqlite3 *db = pParse->db;
199: int rc;
200:
201: /* Don't do any authorization checks if the database is initialising
202: ** or if the parser is being invoked from within sqlite3_declare_vtab.
203: */
204: if( db->init.busy || IN_DECLARE_VTAB ){
205: return SQLITE_OK;
206: }
207:
208: if( db->xAuth==0 ){
209: return SQLITE_OK;
210: }
211: rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
212: if( rc==SQLITE_DENY ){
213: sqlite3ErrorMsg(pParse, "not authorized");
214: pParse->rc = SQLITE_AUTH;
215: }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
216: rc = SQLITE_DENY;
217: sqliteAuthBadReturnCode(pParse);
218: }
219: return rc;
220: }
221:
222: /*
223: ** Push an authorization context. After this routine is called, the
224: ** zArg3 argument to authorization callbacks will be zContext until
225: ** popped. Or if pParse==0, this routine is a no-op.
226: */
227: void sqlite3AuthContextPush(
228: Parse *pParse,
229: AuthContext *pContext,
230: const char *zContext
231: ){
232: assert( pParse );
233: pContext->pParse = pParse;
234: pContext->zAuthContext = pParse->zAuthContext;
235: pParse->zAuthContext = zContext;
236: }
237:
238: /*
239: ** Pop an authorization context that was previously pushed
240: ** by sqlite3AuthContextPush
241: */
242: void sqlite3AuthContextPop(AuthContext *pContext){
243: if( pContext->pParse ){
244: pContext->pParse->zAuthContext = pContext->zAuthContext;
245: pContext->pParse = 0;
246: }
247: }
248:
249: #endif /* SQLITE_OMIT_AUTHORIZATION */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>