SQLite C 接口
编译时授权回调
int sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData );
此例程使用第一个参数中提供 的特定 数据库连接注册授权回调。当 SQL 语句由sqlite3_prepare()或其变体sqlite3_prepare_v2()、 sqlite3_prepare_v3()、sqlite3_prepare16()、sqlite3_prepare16_v2()和sqlite3_prepare16_v3()编译时调用授权回调。在编译过程中的不同时间点,当创建逻辑以执行各种操作时,将调用授权方回调以查看是否允许这些操作。授权回调应该返回SQLITE_OK以允许操作,SQLITE_IGNORE禁止特定操作但允许继续编译 SQL 语句,或者SQLITE_DENY导致整个 SQL 语句被错误拒绝。如果授权方回调返回SQLITE_IGNORE、SQLITE_OK或SQLITE_DENY以外的任何值, 则触发授权方的sqlite3_prepare_v2()或等效调用将失败并显示错误消息。
当回调返回SQLITE_OK时,这意味着请求的操作是正确的。当回调返回SQLITE_DENY时,触发授权方的 sqlite3_prepare_v2()或等效调用将失败,并显示一条错误消息,说明访问被拒绝。
授权回调的第一个参数是 sqlite3_set_authorizer() 接口的第三个参数的副本。回调的第二个参数是一个整数操作代码,指定要授权的特定操作。回调的第三到第六个参数是 NULL 指针或以零结尾的字符串,其中包含有关要授权的操作的其他详细信息。应用程序必须始终准备好在授权回调的第三个到第六个参数中的任何一个中遇到 NULL 指针。
如果操作代码是SQLITE_READ 并且回调返回SQLITE_IGNORE,那么 准备好的语句语句被构造为用 NULL 值代替如果返回SQLITE_OK将被读取的表列。SQLITE_IGNORE返回 可用于拒绝不受信任的用户访问表的各个列。当一个表被SELECT引用但没有从该表中提取列值时(例如在像“SELECT count(*) FROM tab”这样的查询中),然后为该表调用一次SQLITE_READ授权回调,其列名是是一个空字符串。如果操作代码是SQLITE_DELETE并且回调返回 SQLITE_IGNORE然后DELETE操作继续但 截断优化被禁用并且所有行被单独删除。
在准备来自不受信任来源的 SQL 语句时使用授权程序 ,以确保 SQL 语句不会尝试访问它们不允许查看的数据,或者它们不会尝试执行破坏数据库的恶意语句。例如,应用程序可能允许用户输入任意 SQL 查询以供数据库评估。但是应用程序不希望用户能够对数据库进行任意更改。然后可以在准备用户输入的 SQL 时放置一个授权器,该 SQL不允许除SELECT语句之外的所有内容。
需要处理来自不受信任来源的 SQL 的应用程序还可以考虑使用sqlite3_limit()降低资源限制,并使用max_page_count PRAGMA 除了使用授权程序之外还可以 限制数据库大小。
一个数据库连接上一次只能有一个授权方。每次调用 sqlite3_set_authorizer 都会覆盖之前的调用。通过安装 NULL 回调来禁用授权方。默认情况下禁用授权方。
授权回调不能做任何会修改调用授权回调的数据库连接的事情。注意,sqlite3_prepare_v2()和sqlite3_step()都针对本段“修改”的意思修改了自己的数据库连接。
当使用sqlite3_prepare_v2()准备语句时,由于架构更改,可能会在sqlite3_step()期间重新准备语句。因此,应用程序应确保正确的授权回调在sqlite3_step()期间保持不变。
请注意,授权回调仅在 sqlite3_prepare()或其变体期间被调用。在sqlite3_step()中的语句评估期间不执行授权,除非如前一段所述,sqlite3_step() 调用 sqlite3_prepare_v2() 以在模式更改后重新准备语句。