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

Reply via email to