Back to index

php5  5.3.10
auth.c
Go to the documentation of this file.
00001 /*
00002 ** 2003 January 11
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains code used to implement the sqlite_set_authorizer()
00013 ** API.  This facility is an optional feature of the library.  Embedded
00014 ** systems that do not need this facility may omit it by recompiling
00015 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
00016 **
00017 ** $Id: auth.c 195361 2005-09-07 15:11:33Z iliaa $
00018 */
00019 #include "sqliteInt.h"
00020 
00021 /*
00022 ** All of the code in this file may be omitted by defining a single
00023 ** macro.
00024 */
00025 #ifndef SQLITE_OMIT_AUTHORIZATION
00026 
00027 /*
00028 ** Set or clear the access authorization function.
00029 **
00030 ** The access authorization function is be called during the compilation
00031 ** phase to verify that the user has read and/or write access permission on
00032 ** various fields of the database.  The first argument to the auth function
00033 ** is a copy of the 3rd argument to this routine.  The second argument
00034 ** to the auth function is one of these constants:
00035 **
00036 **       SQLITE_COPY
00037 **       SQLITE_CREATE_INDEX
00038 **       SQLITE_CREATE_TABLE
00039 **       SQLITE_CREATE_TEMP_INDEX
00040 **       SQLITE_CREATE_TEMP_TABLE
00041 **       SQLITE_CREATE_TEMP_TRIGGER
00042 **       SQLITE_CREATE_TEMP_VIEW
00043 **       SQLITE_CREATE_TRIGGER
00044 **       SQLITE_CREATE_VIEW
00045 **       SQLITE_DELETE
00046 **       SQLITE_DROP_INDEX
00047 **       SQLITE_DROP_TABLE
00048 **       SQLITE_DROP_TEMP_INDEX
00049 **       SQLITE_DROP_TEMP_TABLE
00050 **       SQLITE_DROP_TEMP_TRIGGER
00051 **       SQLITE_DROP_TEMP_VIEW
00052 **       SQLITE_DROP_TRIGGER
00053 **       SQLITE_DROP_VIEW
00054 **       SQLITE_INSERT
00055 **       SQLITE_PRAGMA
00056 **       SQLITE_READ
00057 **       SQLITE_SELECT
00058 **       SQLITE_TRANSACTION
00059 **       SQLITE_UPDATE
00060 **
00061 ** The third and fourth arguments to the auth function are the name of
00062 ** the table and the column that are being accessed.  The auth function
00063 ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE.  If
00064 ** SQLITE_OK is returned, it means that access is allowed.  SQLITE_DENY
00065 ** means that the SQL statement will never-run - the sqlite_exec() call
00066 ** will return with an error.  SQLITE_IGNORE means that the SQL statement
00067 ** should run but attempts to read the specified column will return NULL
00068 ** and attempts to write the column will be ignored.
00069 **
00070 ** Setting the auth function to NULL disables this hook.  The default
00071 ** setting of the auth function is NULL.
00072 */
00073 int sqlite_set_authorizer(
00074   sqlite *db,
00075   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
00076   void *pArg
00077 ){
00078   db->xAuth = xAuth;
00079   db->pAuthArg = pArg;
00080   return SQLITE_OK;
00081 }
00082 
00083 /*
00084 ** Write an error message into pParse->zErrMsg that explains that the
00085 ** user-supplied authorization function returned an illegal value.
00086 */
00087 static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
00088   sqliteErrorMsg(pParse, "illegal return value (%d) from the "
00089     "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
00090     "or SQLITE_DENY", rc);
00091   pParse->rc = SQLITE_MISUSE;
00092 }
00093 
00094 /*
00095 ** The pExpr should be a TK_COLUMN expression.  The table referred to
00096 ** is in pTabList or else it is the NEW or OLD table of a trigger.  
00097 ** Check to see if it is OK to read this particular column.
00098 **
00099 ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN 
00100 ** instruction into a TK_NULL.  If the auth function returns SQLITE_DENY,
00101 ** then generate an error.
00102 */
00103 void sqliteAuthRead(
00104   Parse *pParse,        /* The parser context */
00105   Expr *pExpr,          /* The expression to check authorization on */
00106   SrcList *pTabList     /* All table that pExpr might refer to */
00107 ){
00108   sqlite *db = pParse->db;
00109   int rc;
00110   Table *pTab;          /* The table being read */
00111   const char *zCol;     /* Name of the column of the table */
00112   int iSrc;             /* Index in pTabList->a[] of table being read */
00113   const char *zDBase;   /* Name of database being accessed */
00114   TriggerStack *pStack; /* The stack of current triggers */
00115 
00116   if( db->xAuth==0 ) return;
00117   assert( pExpr->op==TK_COLUMN );
00118   for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
00119     if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
00120   }
00121   if( iSrc>=0 && iSrc<pTabList->nSrc ){
00122     pTab = pTabList->a[iSrc].pTab;
00123   }else if( (pStack = pParse->trigStack)!=0 ){
00124     /* This must be an attempt to read the NEW or OLD pseudo-tables
00125     ** of a trigger.
00126     */
00127     assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
00128     pTab = pStack->pTab;
00129   }else{
00130     return;
00131   }
00132   if( pTab==0 ) return;
00133   if( pExpr->iColumn>=0 ){
00134     assert( pExpr->iColumn<pTab->nCol );
00135     zCol = pTab->aCol[pExpr->iColumn].zName;
00136   }else if( pTab->iPKey>=0 ){
00137     assert( pTab->iPKey<pTab->nCol );
00138     zCol = pTab->aCol[pTab->iPKey].zName;
00139   }else{
00140     zCol = "ROWID";
00141   }
00142   assert( pExpr->iDb<db->nDb );
00143   zDBase = db->aDb[pExpr->iDb].zName;
00144   rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
00145                  pParse->zAuthContext);
00146   if( rc==SQLITE_IGNORE ){
00147     pExpr->op = TK_NULL;
00148   }else if( rc==SQLITE_DENY ){
00149     if( db->nDb>2 || pExpr->iDb!=0 ){
00150       sqliteErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
00151          zDBase, pTab->zName, zCol);
00152     }else{
00153       sqliteErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
00154     }
00155     pParse->rc = SQLITE_AUTH;
00156   }else if( rc!=SQLITE_OK ){
00157     sqliteAuthBadReturnCode(pParse, rc);
00158   }
00159 }
00160 
00161 /*
00162 ** Do an authorization check using the code and arguments given.  Return
00163 ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY.  If SQLITE_DENY
00164 ** is returned, then the error count and error message in pParse are
00165 ** modified appropriately.
00166 */
00167 int sqliteAuthCheck(
00168   Parse *pParse,
00169   int code,
00170   const char *zArg1,
00171   const char *zArg2,
00172   const char *zArg3
00173 ){
00174   sqlite *db = pParse->db;
00175   int rc;
00176 
00177   if( db->init.busy || db->xAuth==0 ){
00178     return SQLITE_OK;
00179   }
00180   rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
00181   if( rc==SQLITE_DENY ){
00182     sqliteErrorMsg(pParse, "not authorized");
00183     pParse->rc = SQLITE_AUTH;
00184   }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
00185     rc = SQLITE_DENY;
00186     sqliteAuthBadReturnCode(pParse, rc);
00187   }
00188   return rc;
00189 }
00190 
00191 /*
00192 ** Push an authorization context.  After this routine is called, the
00193 ** zArg3 argument to authorization callbacks will be zContext until
00194 ** popped.  Or if pParse==0, this routine is a no-op.
00195 */
00196 void sqliteAuthContextPush(
00197   Parse *pParse,
00198   AuthContext *pContext, 
00199   const char *zContext
00200 ){
00201   pContext->pParse = pParse;
00202   if( pParse ){
00203     pContext->zAuthContext = pParse->zAuthContext;
00204     pParse->zAuthContext = zContext;
00205   }
00206 }
00207 
00208 /*
00209 ** Pop an authorization context that was previously pushed
00210 ** by sqliteAuthContextPush
00211 */
00212 void sqliteAuthContextPop(AuthContext *pContext){
00213   if( pContext->pParse ){
00214     pContext->pParse->zAuthContext = pContext->zAuthContext;
00215     pContext->pParse = 0;
00216   }
00217 }
00218 
00219 #endif /* SQLITE_OMIT_AUTHORIZATION */