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