Any suggestions or meanings on it?
Thanks,
Mario
Short test script:
<?php
$data = array( 'one', 'two', 'three', 'four', 'five', 'six');
$db = new PDO( 'sqlite::memory:');
echo "register authorizer\n";
$db->sqliteSetAuthorizer('auth');
$db->exec( "CREATE TABLE strings( a)");
$insert = $db->prepare( 'INSERT INTO strings VALUES ( ?)');
foreach ( $data as $str) {
$insert->execute( array( $str));
}
$insert = null;
if( $delete = $db->prepare( 'DELETE FROM strings where a=?')){
if( $delete->execute(array( "six" ))){
echo "delete done!\n";
}
$delete = null;
}else{
echo "delete not prepared\n";
}
echo "unregister authorizer\n";
$db->sqliteSetAuthorizer();
if( $delete = $db->prepare( 'DELETE FROM strings where a=?')){
if( $delete->execute(array( "six" ))){
echo "delete done!\n";
}
$delete = null;
}else{
echo "delete not prepared\n";
}
function auth($type,$arga,$argb,$argc,$argd ){
echo "$type\t$arga\t$argb\t$argc\t$argd\n";
if( $type==SQLITE_DELETE ){
return SQLITE_DENY;
}
return SQLITE_OK;
}
print_r( $db->query( 'SELECT sqlite_version( *);')->fetchAll( ));
print_r( $db->query( 'SELECT * from strings;')->fetchAll( ));
?>
gives:
register authorizer
18 sqlite_master main
2 strings main
23 sqlite_master type main
23 sqlite_master name main
23 sqlite_master tbl_name main
23 sqlite_master rootpage main
23 sqlite_master sql main
20 sqlite_master ROWID main
20 sqlite_master name main
20 sqlite_master rootpage main
20 sqlite_master sql main
20 sqlite_master tbl_name main
18 strings main
9 strings main
delete not prepared
unregister authorizer
delete done!
Array
(
[0] => Array
(
[sqlite_version( *)] => 3.3.7
[0] => 3.3.7
)
)
Array
(
[0] => Array
(
[a] => one
[0] => one
)
[1] => Array
(
[a] => two
[0] => two
)
[2] => Array
(
[a] => three
[0] => three
)
[3] => Array
(
[a] => four
[0] => four
)
[4] => Array
(
[a] => five
[0] => five
)
)
diff -ur php-5.2.0/ext/pdo_sqlite/pdo_sqlite.c php-5.2.0-new/ext/pdo_sqlite/pdo_sqlite.c
--- php-5.2.0/ext/pdo_sqlite/pdo_sqlite.c 2006-01-01 13:50:12.000000000 +0100
+++ php-5.2.0-new/ext/pdo_sqlite/pdo_sqlite.c 2006-11-16 21:03:33.000000000 +0100
@@ -77,6 +77,42 @@
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(pdo_sqlite)
{
+ REGISTER_LONG_CONSTANT("SQLITE_COPY", SQLITE_COPY, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DELETE", SQLITE_DELETE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_INDEX", SQLITE_DROP_INDEX, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TABLE", SQLITE_DROP_TABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_VIEW", SQLITE_DROP_VIEW, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_INSERT", SQLITE_INSERT, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_PRAGMA", SQLITE_PRAGMA, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_READ", SQLITE_READ, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_SELECT", SQLITE_SELECT, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_TRANSACTION", SQLITE_TRANSACTION, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_UPDATE", SQLITE_UPDATE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_ATTACH", SQLITE_ATTACH, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DETACH", SQLITE_DETACH, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_REINDEX", SQLITE_REINDEX, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_ANALYZE", SQLITE_ANALYZE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE, CONST_PERSISTENT | CONST_CS);
+ // REGISTER_LONG_CONSTANT("SQLITE_FUNCTION", SQLITE_FUNCTION, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_OK", SQLITE_OK, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_DENY", SQLITE_DENY, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("SQLITE_IGNORE", SQLITE_IGNORE, CONST_PERSISTENT | CONST_CS);
+
return php_pdo_register_driver(&pdo_sqlite_driver);
}
/* }}} */
diff -ur php-5.2.0/ext/pdo_sqlite/php_pdo_sqlite_int.h php-5.2.0-new/ext/pdo_sqlite/php_pdo_sqlite_int.h
--- php-5.2.0/ext/pdo_sqlite/php_pdo_sqlite_int.h 2006-01-01 13:50:12.000000000 +0100
+++ php-5.2.0-new/ext/pdo_sqlite/php_pdo_sqlite_int.h 2006-11-16 20:51:42.000000000 +0100
@@ -49,6 +49,7 @@
typedef struct {
sqlite3 *db;
pdo_sqlite_error_info einfo;
+ zval *user_authorizer;
struct pdo_sqlite_func *funcs;
} pdo_sqlite_db_handle;
diff -ur php-5.2.0/ext/pdo_sqlite/sqlite_driver.c php-5.2.0-new/ext/pdo_sqlite/sqlite_driver.c
--- php-5.2.0/ext/pdo_sqlite/sqlite_driver.c 2006-09-16 20:30:03.000000000 +0200
+++ php-5.2.0-new/ext/pdo_sqlite/sqlite_driver.c 2006-11-17 10:05:30.552613256 +0100
@@ -593,9 +593,59 @@
RETURN_FALSE;
}
/* }}} */
+
+/* {{{ bool SQLite::sqliteSetAuthorizer( mixed callback )
+ Registers a callback for authorization with the sqlite db handle */
+static PHP_METHOD(SQLite, sqliteSetAuthorizer)
+{
+ zval *user_authorizer=NULL;
+ struct pdo_sqlite_func *func;
+ zval *callback=NULL;
+ char *cbname = NULL;
+ pdo_dbh_t *dbh;
+ pdo_sqlite_db_handle *H;
+ int ret;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z",
+ &callback)) {
+ RETURN_FALSE;
+ }
+
+ dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ PDO_CONSTRUCT_CHECK;
+ H = (pdo_sqlite_db_handle *)dbh->driver_data;
+
+ if( callback==NULL ){
+ if (H->user_authorizer!=NULL){
+ FREE_ZVAL(H->user_authorizer);
+ H->user_authorizer=NULL;
+ }
+ RETURN_TRUE;
+ }
+
+ if (!zend_is_callable(callback, 0, &cbname)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
+ efree(cbname);
+ RETURN_FALSE;
+ }
+ efree(cbname);
+
+
+ if (H->user_authorizer!=NULL){
+ FREE_ZVAL(H->user_authorizer);
+ }
+
+ MAKE_STD_ZVAL(user_authorizer);
+ ZVAL_STRING(user_authorizer, callback->value.str.val, 1);
+ H->user_authorizer=user_authorizer;
+ RETURN_TRUE;
+}
+/* }}} */
+
static zend_function_entry dbh_methods[] = {
PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(SQLite, sqliteSetAuthorizer, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
@@ -617,6 +667,10 @@
* request */
if (H) {
pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
+ if( H->user_authorizer!=0 ){
+ FREE_ZVAL(H->user_authorizer);
+ H->user_authorizer=NULL;
+ }
}
}
@@ -663,32 +717,94 @@
static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
const char *arg5, const char *arg6)
{
+ pdo_dbh_t *dbh;
+ pdo_sqlite_db_handle *H;
+ zval *callback=NULL,*zaccess_type,*zarg3,*zarg4,*zarg5,*zarg6;
+ int retval=SQLITE_OK;
char *filename;
- switch (access_type) {
- case SQLITE_COPY: {
- TSRMLS_FETCH();
- filename = make_filename_safe(arg4 TSRMLS_CC);
- if (!filename) {
- return SQLITE_DENY;
+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
+ switch (access_type) {
+ case SQLITE_COPY: {
+ TSRMLS_FETCH();
+ filename = make_filename_safe(arg4 TSRMLS_CC);
+ if (!filename) {
+ return SQLITE_DENY;
+ }
+ efree(filename);
+ }
+ case SQLITE_ATTACH: {
+ TSRMLS_FETCH();
+ filename = make_filename_safe(arg3 TSRMLS_CC);
+ if (!filename) {
+ return SQLITE_DENY;
+ }
+ efree(filename);
}
- efree(filename);
- return SQLITE_OK;
}
-
- case SQLITE_ATTACH: {
- TSRMLS_FETCH();
- filename = make_filename_safe(arg3 TSRMLS_CC);
- if (!filename) {
- return SQLITE_DENY;
+ }
+ dbh=(pdo_dbh_t*)autharg;
+ PDO_CONSTRUCT_CHECK;
+ H = (pdo_sqlite_db_handle *)dbh->driver_data;
+
+ if( H->user_authorizer ){
+ callback=(zval*)H->user_authorizer;
+ zval **args[5];
+ zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
+ zval *result = NULL;
+ zend_fcall_info fci;
+
+ MAKE_STD_ZVAL(zaccess_type);
+ ZVAL_LONG(zaccess_type,access_type);
+ args[0]=&zaccess_type;
+
+ MAKE_STD_ZVAL(zarg3);
+ ZVAL_STRING(zarg3,arg3?(char*)arg3:"", 1);
+ args[1]=&zarg3;
+
+ MAKE_STD_ZVAL(zarg4);
+ ZVAL_STRING(zarg4,arg4?(char*)arg4:"", 1);
+ args[2]=&zarg4;
+
+ MAKE_STD_ZVAL(zarg5);
+ ZVAL_STRING(zarg5,arg5?(char*)arg5:"", 1);
+ args[3]=&zarg5;
+
+ MAKE_STD_ZVAL(zarg6);
+ ZVAL_STRING(zarg6,arg6?(char*)arg6:"", 1);
+ args[4]=&zarg6;
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+ fci.function_name = callback;
+ fci.symbol_table = NULL;
+ fci.object_pp = NULL;
+ fci.retval_ptr_ptr = &result;
+ fci.param_count = 5;
+ fci.params = args;
+ fci.no_separation = 0;
+
+ if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && result) {
+ if( result->type==IS_BOOL ){
+ retval=(result->value.lval==0);
+ }else if( result->type==IS_LONG ){
+ retval=result->value.lval;
+ }else{
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid return from authorizer, need bool or int");
+ retval=SQLITE_DENY;
}
- efree(filename);
- return SQLITE_OK;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback");
+ retval=SQLITE_DENY;
}
-
- default:
- /* access allowed */
- return SQLITE_OK;
+
+ FREE_ZVAL(zaccess_type);
+ FREE_ZVAL(zarg3);
+ FREE_ZVAL(zarg4);
+ FREE_ZVAL(zarg5);
+ FREE_ZVAL(zarg6);
+
}
+ return retval;
}
static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
@@ -702,6 +818,7 @@
H->einfo.errcode = 0;
H->einfo.errmsg = NULL;
+ H->user_authorizer = NULL;
dbh->driver_data = H;
filename = make_filename_safe(dbh->data_source TSRMLS_CC);
@@ -721,9 +838,7 @@
goto cleanup;
}
- if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
- sqlite3_set_authorizer(H->db, authorizer, NULL);
- }
+ sqlite3_set_authorizer(H->db, authorizer, dbh);
if (driver_options) {
timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php