| OLD | NEW | 
 | (Empty) | 
|    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.32 2009/07/02 18:40:35 danielk1977 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){ |  | 
|   90   sqlite3ErrorMsg(pParse, "authorizer malfunction"); |  | 
|   91   pParse->rc = SQLITE_ERROR; |  | 
|   92 } |  | 
|   93  |  | 
|   94 /* |  | 
|   95 ** The pExpr should be a TK_COLUMN expression.  The table referred to |  | 
|   96 ** is in pTabList or else it is the NEW or OLD table of a trigger.   |  | 
|   97 ** Check to see if it is OK to read this particular column. |  | 
|   98 ** |  | 
|   99 ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN  |  | 
|  100 ** instruction into a TK_NULL.  If the auth function returns SQLITE_DENY, |  | 
|  101 ** then generate an error. |  | 
|  102 */ |  | 
|  103 void sqlite3AuthRead( |  | 
|  104   Parse *pParse,        /* The parser context */ |  | 
|  105   Expr *pExpr,          /* The expression to check authorization on */ |  | 
|  106   Schema *pSchema,      /* The schema of the expression */ |  | 
|  107   SrcList *pTabList     /* All table that pExpr might refer to */ |  | 
|  108 ){ |  | 
|  109   sqlite3 *db = pParse->db; |  | 
|  110   int rc; |  | 
|  111   Table *pTab = 0;      /* The table being read */ |  | 
|  112   const char *zCol;     /* Name of the column of the table */ |  | 
|  113   int iSrc;             /* Index in pTabList->a[] of table being read */ |  | 
|  114   const char *zDBase;   /* Name of database being accessed */ |  | 
|  115   int iDb;              /* The index of the database the expression refers to */ |  | 
|  116   int iCol;             /* Index of column in table */ |  | 
|  117  |  | 
|  118   if( db->xAuth==0 ) return; |  | 
|  119   iDb = sqlite3SchemaToIndex(pParse->db, pSchema); |  | 
|  120   if( iDb<0 ){ |  | 
|  121     /* An attempt to read a column out of a subquery or other |  | 
|  122     ** temporary table. */ |  | 
|  123     return; |  | 
|  124   } |  | 
|  125  |  | 
|  126   assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); |  | 
|  127   if( pExpr->op==TK_TRIGGER ){ |  | 
|  128     pTab = pParse->pTriggerTab; |  | 
|  129   }else{ |  | 
|  130     assert( pTabList ); |  | 
|  131     for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ |  | 
|  132       if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ |  | 
|  133         pTab = pTabList->a[iSrc].pTab; |  | 
|  134         break; |  | 
|  135       } |  | 
|  136     } |  | 
|  137   } |  | 
|  138   iCol = pExpr->iColumn; |  | 
|  139   if( NEVER(pTab==0) ) return; |  | 
|  140  |  | 
|  141   if( iCol>=0 ){ |  | 
|  142     assert( iCol<pTab->nCol ); |  | 
|  143     zCol = pTab->aCol[iCol].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); |  | 
|  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); |  | 
|  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   assert( pParse ); |  | 
|  217   pContext->pParse = pParse; |  | 
|  218   pContext->zAuthContext = pParse->zAuthContext; |  | 
|  219   pParse->zAuthContext = zContext; |  | 
|  220 } |  | 
|  221  |  | 
|  222 /* |  | 
|  223 ** Pop an authorization context that was previously pushed |  | 
|  224 ** by sqlite3AuthContextPush |  | 
|  225 */ |  | 
|  226 void sqlite3AuthContextPop(AuthContext *pContext){ |  | 
|  227   if( pContext->pParse ){ |  | 
|  228     pContext->pParse->zAuthContext = pContext->zAuthContext; |  | 
|  229     pContext->pParse = 0; |  | 
|  230   } |  | 
|  231 } |  | 
|  232  |  | 
|  233 #endif /* SQLITE_OMIT_AUTHORIZATION */ |  | 
| OLD | NEW |