Annotation of embedaddon/sqlite3/src/auth.c, revision 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>