|
35 | 35 | ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
|
36 | 36 |
|
37 | 37 | static PHP_GINIT_FUNCTION(sqlite3);
|
38 |
| -static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6); |
| 38 | +static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4); |
39 | 39 | static void sqlite3_param_dtor(zval *data);
|
40 | 40 | static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
|
41 | 41 |
|
@@ -159,10 +159,10 @@ PHP_METHOD(sqlite3, open)
|
159 | 159 | #endif
|
160 | 160 |
|
161 | 161 | db_obj->initialised = 1;
|
| 162 | + db_obj->authorizer_fci = empty_fcall_info; |
| 163 | + db_obj->authorizer_fcc = empty_fcall_info_cache; |
162 | 164 |
|
163 |
| - if (PG(open_basedir) && *PG(open_basedir)) { |
164 |
| - sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, NULL); |
165 |
| - } |
| 165 | + sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, db_obj); |
166 | 166 |
|
167 | 167 | #if SQLITE_VERSION_NUMBER >= 3026000
|
168 | 168 | if (SQLITE3G(dbconfig_defensive)) {
|
@@ -1350,6 +1350,40 @@ PHP_METHOD(sqlite3, enableExceptions)
|
1350 | 1350 | }
|
1351 | 1351 | /* }}} */
|
1352 | 1352 |
|
| 1353 | +/* {{{ proto bool SQLite3::setAuthorizer(mixed callback) |
| 1354 | + Register a callback function to be used as an authorizer by SQLite. The callback should return SQLite3::OK, SQLite3::IGNORE or SQLite3::DENY. */ |
| 1355 | +PHP_METHOD(sqlite3, setAuthorizer) |
| 1356 | +{ |
| 1357 | + php_sqlite3_db_object *db_obj; |
| 1358 | + zval *object = ZEND_THIS; |
| 1359 | + db_obj = Z_SQLITE3_DB_P(object); |
| 1360 | + zend_fcall_info fci; |
| 1361 | + zend_fcall_info_cache fcc; |
| 1362 | + |
| 1363 | + SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) |
| 1364 | + |
| 1365 | + ZEND_PARSE_PARAMETERS_START(1, 1) |
| 1366 | + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) |
| 1367 | + ZEND_PARSE_PARAMETERS_END(); |
| 1368 | + |
| 1369 | + /* Clear previously set callback */ |
| 1370 | + if (ZEND_FCI_INITIALIZED(db_obj->authorizer_fci)) { |
| 1371 | + zval_ptr_dtor(&db_obj->authorizer_fci.function_name); |
| 1372 | + db_obj->authorizer_fci.size = 0; |
| 1373 | + } |
| 1374 | + |
| 1375 | + /* Only enable userland authorizer if argument is not NULL */ |
| 1376 | + if (ZEND_FCI_INITIALIZED(fci)) { |
| 1377 | + db_obj->authorizer_fci = fci; |
| 1378 | + Z_ADDREF(db_obj->authorizer_fci.function_name); |
| 1379 | + db_obj->authorizer_fcc = fcc; |
| 1380 | + } |
| 1381 | + |
| 1382 | + RETURN_TRUE; |
| 1383 | +} |
| 1384 | +/* }}} */ |
| 1385 | + |
| 1386 | + |
1353 | 1387 | #if SQLITE_VERSION_NUMBER >= 3006011
|
1354 | 1388 | /* {{{ proto bool SQLite3::backup(SQLite3 destination_db[, string source_dbname = "main"[, string destination_dbname = "main"]])
|
1355 | 1389 | Backups the current database to another one. */
|
@@ -2118,6 +2152,7 @@ static const zend_function_entry php_sqlite3_class_methods[] = {
|
2118 | 2152 | PHP_ME(sqlite3, createCollation, arginfo_class_SQLite3_createCollation, ZEND_ACC_PUBLIC)
|
2119 | 2153 | PHP_ME(sqlite3, openBlob, arginfo_class_SQLite3_openBlob, ZEND_ACC_PUBLIC)
|
2120 | 2154 | PHP_ME(sqlite3, enableExceptions, arginfo_class_SQLite3_enableExceptions, ZEND_ACC_PUBLIC)
|
| 2155 | + PHP_ME(sqlite3, setAuthorizer, arginfo_class_SQLite3_setAuthorizer, ZEND_ACC_PUBLIC) |
2121 | 2156 | #if SQLITE_VERSION_NUMBER >= 3006011
|
2122 | 2157 | PHP_ME(sqlite3, backup, arginfo_class_SQLite3_backup, ZEND_ACC_PUBLIC)
|
2123 | 2158 | #endif
|
@@ -2158,32 +2193,92 @@ static const zend_function_entry php_sqlite3_result_class_methods[] = {
|
2158 | 2193 |
|
2159 | 2194 | /* {{{ Authorization Callback
|
2160 | 2195 | */
|
2161 |
| -static int php_sqlite3_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6) |
| 2196 | +static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4) |
2162 | 2197 | {
|
2163 |
| - switch (access_type) { |
2164 |
| - case SQLITE_ATTACH: |
2165 |
| - { |
2166 |
| - if (memcmp(arg3, ":memory:", sizeof(":memory:")) && *arg3) { |
2167 |
| - if (strncmp(arg3, "file:", 5) == 0) { |
| 2198 | + /* Check open_basedir restrictions first */ |
| 2199 | + if (PG(open_basedir) && *PG(open_basedir)) { |
| 2200 | + if (action == SQLITE_ATTACH) { |
| 2201 | + if (memcmp(arg1, ":memory:", sizeof(":memory:")) && *arg1) { |
| 2202 | + if (strncmp(arg1, "file:", 5) == 0) { |
2168 | 2203 | /* starts with "file:" */
|
2169 |
| - if (!arg3[5]) { |
| 2204 | + if (!arg1[5]) { |
2170 | 2205 | return SQLITE_DENY;
|
2171 | 2206 | }
|
2172 |
| - if (php_check_open_basedir(arg3 + 5)) { |
| 2207 | + if (php_check_open_basedir(arg1 + 5)) { |
2173 | 2208 | return SQLITE_DENY;
|
2174 | 2209 | }
|
2175 | 2210 | }
|
2176 |
| - if (php_check_open_basedir(arg3)) { |
| 2211 | + if (php_check_open_basedir(arg1)) { |
2177 | 2212 | return SQLITE_DENY;
|
2178 | 2213 | }
|
2179 | 2214 | }
|
2180 |
| - return SQLITE_OK; |
2181 | 2215 | }
|
| 2216 | + } |
2182 | 2217 |
|
2183 |
| - default: |
2184 |
| - /* access allowed */ |
2185 |
| - return SQLITE_OK; |
| 2218 | + php_sqlite3_db_object *db_obj = (php_sqlite3_db_object *)autharg; |
| 2219 | + zend_fcall_info *fci = &db_obj->authorizer_fci; |
| 2220 | + |
| 2221 | + /* fallback to access allowed if authorizer callback is not defined */ |
| 2222 | + if (fci->size == 0) { |
| 2223 | + return SQLITE_OK; |
| 2224 | + } |
| 2225 | + |
| 2226 | + /* call userland authorizer callback, if set */ |
| 2227 | + zval retval; |
| 2228 | + zval argv[5]; |
| 2229 | + |
| 2230 | + ZVAL_LONG(&argv[0], action); |
| 2231 | + |
| 2232 | + if (NULL == arg1) { |
| 2233 | + ZVAL_NULL(&argv[1]); |
| 2234 | + } else { |
| 2235 | + ZVAL_STRING(&argv[1], arg1); |
| 2236 | + } |
| 2237 | + |
| 2238 | + if (NULL == arg2) { |
| 2239 | + ZVAL_NULL(&argv[2]); |
| 2240 | + } else { |
| 2241 | + ZVAL_STRING(&argv[2], arg2); |
| 2242 | + } |
| 2243 | + |
| 2244 | + if (NULL == arg3) { |
| 2245 | + ZVAL_NULL(&argv[3]); |
| 2246 | + } else { |
| 2247 | + ZVAL_STRING(&argv[3], arg3); |
2186 | 2248 | }
|
| 2249 | + |
| 2250 | + if (NULL == arg4) { |
| 2251 | + ZVAL_NULL(&argv[4]); |
| 2252 | + } else { |
| 2253 | + ZVAL_STRING(&argv[4], arg4); |
| 2254 | + } |
| 2255 | + |
| 2256 | + fci->retval = &retval; |
| 2257 | + fci->param_count = 5; |
| 2258 | + fci->params = argv; |
| 2259 | + fci->no_separation = 0; |
| 2260 | + |
| 2261 | + int authreturn = SQLITE_DENY; |
| 2262 | + |
| 2263 | + if (zend_call_function(fci, &db_obj->authorizer_fcc) != SUCCESS || Z_ISUNDEF(retval)) { |
| 2264 | + php_sqlite3_error(db_obj, "An error occurred while invoking the authorizer callback"); |
| 2265 | + } else { |
| 2266 | + if (Z_TYPE(retval) != IS_LONG) { |
| 2267 | + php_sqlite3_error(db_obj, "The authorizer callback returned an invalid type: expected int"); |
| 2268 | + } else { |
| 2269 | + authreturn = Z_LVAL(retval); |
| 2270 | + |
| 2271 | + if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY) { |
| 2272 | + php_sqlite3_error(db_obj, "The authorizer callback returned an invalid value"); |
| 2273 | + authreturn = SQLITE_DENY; |
| 2274 | + } |
| 2275 | + } |
| 2276 | + } |
| 2277 | + |
| 2278 | + zend_fcall_info_args_clear(fci, 0); |
| 2279 | + zval_ptr_dtor(&retval); |
| 2280 | + |
| 2281 | + return authreturn; |
2187 | 2282 | }
|
2188 | 2283 | /* }}} */
|
2189 | 2284 |
|
@@ -2223,6 +2318,11 @@ static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
|
2223 | 2318 | return;
|
2224 | 2319 | }
|
2225 | 2320 |
|
| 2321 | + /* Release function_name from authorizer */ |
| 2322 | + if (intern->authorizer_fci.size > 0) { |
| 2323 | + zval_ptr_dtor(&intern->authorizer_fci.function_name); |
| 2324 | + } |
| 2325 | + |
2226 | 2326 | while (intern->funcs) {
|
2227 | 2327 | func = intern->funcs;
|
2228 | 2328 | intern->funcs = func->next;
|
@@ -2444,6 +2544,49 @@ PHP_MINIT_FUNCTION(sqlite3)
|
2444 | 2544 | REGISTER_LONG_CONSTANT("SQLITE3_OPEN_READWRITE", SQLITE_OPEN_READWRITE, CONST_CS | CONST_PERSISTENT);
|
2445 | 2545 | REGISTER_LONG_CONSTANT("SQLITE3_OPEN_CREATE", SQLITE_OPEN_CREATE, CONST_CS | CONST_PERSISTENT);
|
2446 | 2546 |
|
| 2547 | + /* Class constants */ |
| 2548 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "OK", sizeof("OK") - 1, SQLITE_OK); |
| 2549 | + |
| 2550 | + /* Constants for authorizer return */ |
| 2551 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DENY", sizeof("DENY") - 1, SQLITE_DENY); |
| 2552 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "IGNORE", sizeof("IGNORE") - 1, SQLITE_IGNORE); |
| 2553 | + |
| 2554 | + /* Constants for authorizer actions */ |
| 2555 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_INDEX", sizeof("CREATE_INDEX") - 1, SQLITE_CREATE_INDEX); |
| 2556 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TABLE", sizeof("CREATE_TABLE") - 1, SQLITE_CREATE_TABLE); |
| 2557 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_INDEX", sizeof("CREATE_TEMP_INDEX") - 1, SQLITE_CREATE_TEMP_INDEX); |
| 2558 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_TABLE", sizeof("CREATE_TEMP_TABLE") - 1, SQLITE_CREATE_TEMP_TABLE); |
| 2559 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_TRIGGER", sizeof("CREATE_TEMP_TRIGGER") - 1, SQLITE_CREATE_TEMP_TRIGGER); |
| 2560 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TEMP_VIEW", sizeof("CREATE_TEMP_VIEW") - 1, SQLITE_CREATE_TEMP_VIEW); |
| 2561 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_TRIGGER", sizeof("CREATE_TRIGGER") - 1, SQLITE_CREATE_TRIGGER); |
| 2562 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_VIEW", sizeof("CREATE_VIEW") - 1, SQLITE_CREATE_VIEW); |
| 2563 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DELETE", sizeof("DELETE") - 1, SQLITE_DELETE); |
| 2564 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_INDEX", sizeof("DROP_INDEX") - 1, SQLITE_DROP_INDEX); |
| 2565 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TABLE", sizeof("DROP_TABLE") - 1, SQLITE_DROP_TABLE); |
| 2566 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_INDEX", sizeof("DROP_TEMP_INDEX") - 1, SQLITE_DROP_TEMP_INDEX); |
| 2567 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_TABLE", sizeof("DROP_TEMP_TABLE") - 1, SQLITE_DROP_TEMP_TABLE); |
| 2568 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_TRIGGER", sizeof("DROP_TEMP_TRIGGER") - 1, SQLITE_DROP_TEMP_TRIGGER); |
| 2569 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TEMP_VIEW", sizeof("DROP_TEMP_VIEW") - 1, SQLITE_DROP_TEMP_VIEW); |
| 2570 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_TRIGGER", sizeof("DROP_TRIGGER") - 1, SQLITE_DROP_TRIGGER); |
| 2571 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_VIEW", sizeof("DROP_VIEW") - 1, SQLITE_DROP_VIEW); |
| 2572 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "INSERT", sizeof("INSERT") - 1, SQLITE_INSERT); |
| 2573 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "PRAGMA", sizeof("PRAGMA") - 1, SQLITE_PRAGMA); |
| 2574 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "READ", sizeof("READ") - 1, SQLITE_READ); |
| 2575 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "SELECT", sizeof("SELECT") - 1, SQLITE_SELECT); |
| 2576 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "TRANSACTION", sizeof("TRANSACTION") - 1, SQLITE_TRANSACTION); |
| 2577 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "UPDATE", sizeof("UPDATE") - 1, SQLITE_UPDATE); |
| 2578 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "ATTACH", sizeof("ATTACH") - 1, SQLITE_ATTACH); |
| 2579 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DETACH", sizeof("DETACH") - 1, SQLITE_DETACH); |
| 2580 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "ALTER_TABLE", sizeof("ALTER_TABLE") - 1, SQLITE_ALTER_TABLE); |
| 2581 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "REINDEX", sizeof("REINDEX") - 1, SQLITE_REINDEX); |
| 2582 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "ANALYZE", sizeof("ANALYZE") - 1, SQLITE_ANALYZE); |
| 2583 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "CREATE_VTABLE", sizeof("CREATE_VTABLE") - 1, SQLITE_CREATE_VTABLE); |
| 2584 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "DROP_VTABLE", sizeof("DROP_VTABLE") - 1, SQLITE_DROP_VTABLE); |
| 2585 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "FUNCTION", sizeof("FUNCTION") - 1, SQLITE_FUNCTION); |
| 2586 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "SAVEPOINT", sizeof("SAVEPOINT") - 1, SQLITE_SAVEPOINT); |
| 2587 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "COPY", sizeof("COPY") - 1, SQLITE_COPY); |
| 2588 | + zend_declare_class_constant_long(php_sqlite3_sc_entry, "RECURSIVE", sizeof("RECURSIVE") - 1, SQLITE_RECURSIVE); |
| 2589 | + |
2447 | 2590 | #ifdef SQLITE_DETERMINISTIC
|
2448 | 2591 | REGISTER_LONG_CONSTANT("SQLITE3_DETERMINISTIC", SQLITE_DETERMINISTIC, CONST_CS | CONST_PERSISTENT);
|
2449 | 2592 | #endif
|
|
0 commit comments