sqlite.h


Retrollamadas de autorización en tiempo de compilado

int sqlite3_set_authorizer(
  sqlite3*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);

Esta función registra una retrollamada de autorización para una conexión de base de datos en particular, suministrada por el primer argumento. La retrollamada de autorización es invocada cuando sentencias SQL son compiladas mediante sqlite3_prepare() o sus variabtes sqlite3_prepare_v2(), sqlite3_prepare16() y sqlite3_prepare16_v2(). En varios momentos durante el proceso de compilación, como lógica creada para realizar varias acciones, la retrollamada de autorización se invoca para ver si esas acciones están permitidas. La retrollamada de autorización debe retornar SQLITE_OK para permitir la acción, SQLITE_IGNORE para no permitir la acción específica pero permitir a la sentencia SQL continúe compilándose, o SQLITE_DENY para hacer que la sentencia SQL completa sea rechazada con un error. Si la retrollamada retorna cualquier valor diferente de SQLITE_IGNORE, SQLITE_OK o SQLITE_DENY la función sqlite3_prepare_v2() o equivalente que disparó el autorizador fallará con un mensaje de error.

Cuando la retrollamada devuelve SQLITE_OK, significa que la operación requerida es correcta. Cuando la retrollamada devuelve SQLITE_DENY, la función sqlite3_prepare_v2() o equivalente que disparó el autorizador falla con un mensaje de error que explica que el acceso ha sido denegado.

El primer parámetro a la retrollamada es una copia del tercer parámetro de la función sqlite3_set_authorizer(). El segundo parámetro es un código de acción entero que especifica la acción en particular a autorizar. El tercero a sexto parámetros son cadenas terminadas en cero que contienen detalles adicionales sobre la acción a autorizar.

Si el código de acción es SQLITE_READ y la retrollamada devuelve SQLITE_IGNORE la sentencia preparada se construye para colocar un valor NULL en lugar de la columna de tabla que hubiera sido leída si se hubiera retornado SQLITE_OK. El valor de retorno SQLITE_IGNORE puede ser usado para denegar el acceso a un usuario no confiable a columnas individuales de una tabla. Si el código de acción es SQLITE_DELETE y la retrollamada devuelve SQLITE_IGNORE la operación DELETE se procesa pero la optimización de truncado se desactiva y todas las filas se borran individualmente.

Se usa un autorizador cuando se preparan sentencias SQL desde una fuente no confiable, para asegurar que las sentencias SQL no intentan acceder a datos que no están autorizados a ver, o que no intentan ejecutar sentencias maliciosas que dañen la base de datos. Por ejemplo, una aplicación puede permitir a un usuario introducir consultas SQL arbitrarias para ser evaluadas por una base de datos. Pero la aplicación no quiere que el usuario pueda hacer cambios arbitrarios en la base de datos. Un autorizador podría ponerse en marcha mientras el código SQL introducido por el usuario está siendo preparado para no permitir todo lo que no sean sentencias SELECT.

Las aplicaciones que necesiten procesar SQL desde fuentes no confiables también podrían considerar la disminución de límites de recursos usando sqlite3_limit() y limitar el tamaño de la base de datos usando el PRAGMA max_page_count además de usar un autorizador.

Sólo un único autorizador puede colocarse en una conexión de base de datos a la vez. Cada llamada a sqlite3_set_authorizer anula la llamada anterior. Para desactivar un autorizador instalar una retrollamada NULL. El autorizador está desactivado por defecto.

La retrollamada de autorización no debe hacer nada que modifique la conexión de base de datos que ha invocado a la retrollamada. Hay que tener en cuenta que tanto sqlite3_prepare_v2() como sqlite3_step() modifican sus conexiones de base de datos en el significado que tienen "modificar" en este párrafo.

Cuando sqlite3_prepare_v2() se usa para perapara una sentencia, esta podría ser repreparada durante sqlite3_step() debido a un cambio de esquema. Por lo tanto, la aplicación debe asegurarse de que la retrollamada de autorización correcta permanece en su lugar durante sqlite3_step().

Hay que tener en cuenta que la retrollamada es invocada sólo durante sqlite3_prepare() o sus variantes. No se realizan autorizaciones durante la evaluación de sentencias en sqlite3_step(), salvo que como se indicó en el párrafo anterior, sqlite3_step() invoque a sqlite3_prepare_v2() para repreparar una sentencia después de un cambio de esquema.