engine/sqlite/src/auth.cpp
changeset 2 29cda98b007e
equal deleted inserted replaced
1:5f8e5adbbed9 2:29cda98b007e
       
     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.cpp 1282 2008-11-13 09:31:33Z LarsPson $
       
    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 EXPORT_C 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 */