diff --git a/config/config.sample.php b/config/config.sample.php
index 268b7cc9d0811215bb3e02117abdf982282bedcc..09b59fcb5b423fd537be70a5dfa6006528d051ce 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -807,6 +807,23 @@ $CONFIG = array(
 	),
 ),
 
+/**
+ * Database types that are supported for installation
+ * Available:
+ * 	- sqlite (SQLite3)
+ * 	- mysql (MySQL)
+ * 	- pgsql (PostgreSQL)
+ * 	- oci (Oracle)
+ * 	- mssql (Microsoft SQL Server)
+ */
+'supportedDatabases' => array(
+	'sqlite',
+	'mysql',
+	'pgsql',
+	'oci',
+	'mssql'
+),
+
 /**
  * Custom CSP policy, changing this will overwrite the standard policy
  */
diff --git a/core/setup/controller.php b/core/setup/controller.php
index 53f247e9769c6ba8a2809110dba98ac72f871544..f5f05348fd12e9827b3a6d7971eb038a6f15e695 100644
--- a/core/setup/controller.php
+++ b/core/setup/controller.php
@@ -1,6 +1,7 @@
 <?php
 /**
  * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -8,7 +9,19 @@
 
 namespace OC\Core\Setup;
 
+use OCP\IConfig;
+
 class Controller {
+	/** @var \OCP\IConfig */
+	protected $config;
+
+	/**
+	 * @param IConfig $config
+	 */
+	function __construct(IConfig $config) {
+		$this->config = $config;
+	}
+
 	public function run($post) {
 		// Check for autosetup:
 		$post = $this->loadAutoConfig($post);
@@ -87,28 +100,10 @@ class Controller {
 	 * in case of errors/warnings
 	 */
 	public function getSystemInfo() {
-		$hasSQLite = class_exists('SQLite3');
-		$hasMySQL = is_callable('mysql_connect');
-		$hasPostgreSQL = is_callable('pg_connect');
-		$hasOracle = is_callable('oci_connect');
-		$hasMSSQL = is_callable('sqlsrv_connect');
-		$databases = array();
-		if ($hasSQLite) {
-			$databases['sqlite'] = 'SQLite';
-		}
-		if ($hasMySQL) {
-			$databases['mysql'] = 'MySQL/MariaDB';
-		}
-		if ($hasPostgreSQL) {
-			$databases['pgsql'] = 'PostgreSQL';
-		}
-		if ($hasOracle) {
-			$databases['oci'] = 'Oracle';
-		}
-		if ($hasMSSQL) {
-			$databases['mssql'] = 'MS SQL';
-		}
-		$datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data');
+		$setup = new \OC_Setup($this->config);
+		$databases = $setup->getSupportedDatabases();
+
+		$dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data');
 		$vulnerableToNullByte = false;
 		if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243)
 			$vulnerableToNullByte = true;
@@ -119,25 +114,25 @@ class Controller {
 		// Create data directory to test whether the .htaccess works
 		// Notice that this is not necessarily the same data directory as the one
 		// that will effectively be used.
-		@mkdir($datadir);
-		if (is_dir($datadir) && is_writable($datadir)) {
+		@mkdir($dataDir);
+		$htAccessWorking = true;
+		if (is_dir($dataDir) && is_writable($dataDir)) {
 			// Protect data directory here, so we can test if the protection is working
 			\OC_Setup::protectDataDirectory();
 
 			try {
-				$htaccessWorking = \OC_Util::isHtaccessWorking();
+				$htAccessWorking = \OC_Util::isHtaccessWorking();
 			} catch (\OC\HintException $e) {
 				$errors[] = array(
 					'error' => $e->getMessage(),
 					'hint' => $e->getHint()
 				);
-				$htaccessWorking = false;
+				$htAccessWorking = false;
 			}
 		}
 
 		if (\OC_Util::runningOnMac()) {
 			$l10n = \OC::$server->getL10N('core');
-			$themeName = \OC_Util::getTheme();
 			$theme = new \OC_Defaults();
 			$errors[] = array(
 				'error' => $l10n->t(
@@ -150,14 +145,14 @@ class Controller {
 		}
 
 		return array(
-			'hasSQLite' => $hasSQLite,
-			'hasMySQL' => $hasMySQL,
-			'hasPostgreSQL' => $hasPostgreSQL,
-			'hasOracle' => $hasOracle,
-			'hasMSSQL' => $hasMSSQL,
+			'hasSQLite' => isset($databases['sqlite']),
+			'hasMySQL' => isset($databases['mysql']),
+			'hasPostgreSQL' => isset($databases['postgre']),
+			'hasOracle' => isset($databases['oci']),
+			'hasMSSQL' => isset($databases['mssql']),
 			'databases' => $databases,
-			'directory' => $datadir,
-			'htaccessWorking' => $htaccessWorking,
+			'directory' => $dataDir,
+			'htaccessWorking' => $htAccessWorking,
 			'vulnerableToNullByte' => $vulnerableToNullByte,
 			'errors' => $errors,
 		);
diff --git a/lib/base.php b/lib/base.php
index 4af5b5150067c3341fab36bd9043f523ebde5a05..4a5f4e77a59dbc1e2d52afc4e072649dad7b928a 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -717,7 +717,7 @@ class OC {
 
 		// Check if ownCloud is installed or in maintenance (update) mode
 		if (!OC_Config::getValue('installed', false)) {
-			$controller = new OC\Core\Setup\Controller();
+			$controller = new OC\Core\Setup\Controller(\OC::$server->getConfig());
 			$controller->run($_POST);
 			exit();
 		}
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 75dc1987ee6c3d91de55f1bad148dd313717d50c..b82e0be72e83c7c60ee7d5f8824310f957339073 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -1,9 +1,27 @@
 <?php
+/**
+ * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+use OCP\IConfig;
 
 class DatabaseSetupException extends \OC\HintException {
 }
 
 class OC_Setup {
+	/** @var IConfig */
+	protected $config;
+
+	/**
+	 * @param IConfig $config
+	 */
+	function __construct(IConfig $config) {
+		$this->config = $config;
+	}
+
 	static $dbSetupClasses = array(
 		'mysql' => '\OC\Setup\MySQL',
 		'pgsql' => '\OC\Setup\PostgreSQL',
@@ -13,15 +31,99 @@ class OC_Setup {
 		'sqlite3' => '\OC\Setup\Sqlite',
 	);
 
+	/**
+	 * @return OC_L10N
+	 */
 	public static function getTrans(){
 		return \OC::$server->getL10N('lib');
 	}
 
+	/**
+	 * Wrapper around the "class_exists" PHP function to be able to mock it
+	 * @param string $name
+	 * @return bool
+	 */
+	public function class_exists($name) {
+		return class_exists($name);
+	}
+
+	/**
+	 * Wrapper around the "is_callable" PHP function to be able to mock it
+	 * @param string $name
+	 * @return bool
+	 */
+	public function is_callable($name) {
+		return is_callable($name);
+	}
+
+	/**
+	 * Get the available and supported databases of this instance
+	 *
+	 * @throws Exception
+	 * @return array
+	 */
+	public function getSupportedDatabases() {
+		$availableDatabases = array(
+			'sqlite' =>  array(
+				'type' => 'class',
+				'call' => 'SQLite3',
+				'name' => 'SQLite'
+			),
+			'mysql' => array(
+				'type' => 'function',
+				'call' => 'mysql_connect',
+				'name' => 'MySQL/MariaDB'
+			),
+			'pgsql' => array(
+				'type' => 'function',
+				'call' => 'oci_connect',
+				'name' => 'PostgreSQL'
+			),
+			'oci' => array(
+				'type' => 'function',
+				'call' => 'oci_connect',
+				'name' => 'Oracle'
+			),
+			'mssql' => array(
+				'type' => 'function',
+				'call' => 'sqlsrv_connect',
+				'name' => 'MS SQL'
+			)
+		);
+		$configuredDatabases = $this->config->getSystemValue('supportedDatabases',
+			array('sqlite', 'mysql', 'pgsql', 'oci', 'mssql'));
+		if(!is_array($configuredDatabases)) {
+			throw new Exception('Supported databases are not properly configured.');
+		}
+
+		$supportedDatabases = array();
+
+		foreach($configuredDatabases as $database) {
+			if(array_key_exists($database, $availableDatabases)) {
+				$working = false;
+				if($availableDatabases[$database]['type'] === 'class') {
+					$working = $this->class_exists($availableDatabases[$database]['call']);
+				} elseif ($availableDatabases[$database]['type'] === 'function') {
+					$working = $this->is_callable($availableDatabases[$database]['call']);
+				}
+				if($working) {
+					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
+				}
+			}
+		}
+
+		return $supportedDatabases;
+	}
+
+	/**
+	 * @param $options
+	 * @return array
+	 */
 	public static function install($options) {
 		$l = self::getTrans();
 
 		$error = array();
-		$dbtype = $options['dbtype'];
+		$dbType = $options['dbtype'];
 
 		if(empty($options['adminlogin'])) {
 			$error[] = $l->t('Set an admin username.');
@@ -33,25 +135,25 @@ class OC_Setup {
 			$options['directory'] = OC::$SERVERROOT."/data";
 		}
 
-		if (!isset(self::$dbSetupClasses[$dbtype])) {
-			$dbtype = 'sqlite';
+		if (!isset(self::$dbSetupClasses[$dbType])) {
+			$dbType = 'sqlite';
 		}
 
 		$username = htmlspecialchars_decode($options['adminlogin']);
 		$password = htmlspecialchars_decode($options['adminpass']);
-		$datadir = htmlspecialchars_decode($options['directory']);
+		$dataDir = htmlspecialchars_decode($options['directory']);
 
-		$class = self::$dbSetupClasses[$dbtype];
+		$class = self::$dbSetupClasses[$dbType];
 		/** @var \OC\Setup\AbstractDatabase $dbSetup */
 		$dbSetup = new $class(self::getTrans(), 'db_structure.xml');
 		$error = array_merge($error, $dbSetup->validate($options));
 
 		// validate the data directory
 		if (
-			(!is_dir($datadir) and !mkdir($datadir)) or
-			!is_writable($datadir)
+			(!is_dir($dataDir) and !mkdir($dataDir)) or
+			!is_writable($dataDir)
 		) {
-			$error[] = $l->t("Can't create or write into the data directory %s", array($datadir));
+			$error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
 		}
 
 		if(count($error) != 0) {
@@ -59,7 +161,7 @@ class OC_Setup {
 		}
 
 		//no errors, good
-		if(    isset($options['trusted_domains'])
+		if(isset($options['trusted_domains'])
 		    && is_array($options['trusted_domains'])) {
 			$trustedDomains = $options['trusted_domains'];
 		} else {
@@ -67,12 +169,12 @@ class OC_Setup {
 		}
 
 		if (OC_Util::runningOnWindows()) {
-			$datadir = rtrim(realpath($datadir), '\\');
+			$dataDir = rtrim(realpath($dataDir), '\\');
 		}
 
-		//use sqlite3 when available, otherise sqlite2 will be used.
-		if($dbtype=='sqlite' and class_exists('SQLite3')) {
-			$dbtype='sqlite3';
+		//use sqlite3 when available, otherwise sqlite2 will be used.
+		if($dbType=='sqlite' and class_exists('SQLite3')) {
+			$dbType='sqlite3';
 		}
 
 		//generate a random salt that is used to salt the local user passwords
@@ -85,9 +187,9 @@ class OC_Setup {
 
 		//write the config file
 		\OC::$server->getConfig()->setSystemValue('trusted_domains', $trustedDomains);
-		\OC::$server->getConfig()->setSystemValue('datadirectory', $datadir);
+		\OC::$server->getConfig()->setSystemValue('datadirectory', $dataDir);
 		\OC::$server->getConfig()->setSystemValue('overwrite.cli.url', \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . OC::$WEBROOT);
-		\OC::$server->getConfig()->setSystemValue('dbtype', $dbtype);
+		\OC::$server->getConfig()->setSystemValue('dbtype', $dbType);
 		\OC::$server->getConfig()->setSystemValue('version', implode('.', OC_Util::getVersion()));
 
 		try {
@@ -110,8 +212,7 @@ class OC_Setup {
 		//create the user and group
 		try {
 			OC_User::createUser($username, $password);
-		}
-		catch(Exception $exception) {
+		} catch(Exception $exception) {
 			$error[] = $exception->getMessage();
 		}
 
diff --git a/lib/private/util.php b/lib/private/util.php
index d600f8a5e64a2902d3a425675710166487d62e2f..6cd982c222ee27b4f99bace11844ca9e10ddd3d7 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -436,12 +436,9 @@ class OC_Util {
 		}
 
 		$webServerRestart = false;
-		//check for database drivers
-		if (!(is_callable('sqlite_open') or class_exists('SQLite3'))
-			and !is_callable('mysql_connect')
-			and !is_callable('pg_connect')
-			and !is_callable('oci_connect')
-		) {
+		$setup = new OC_Setup($config);
+		$availableDatabases = $setup->getSupportedDatabases();
+		if (empty($availableDatabases)) {
 			$errors[] = array(
 				'error' => $l->t('No database drivers (sqlite, mysql, or postgresql) installed.'),
 				'hint' => '' //TODO: sane hint
diff --git a/tests/lib/setup.php b/tests/lib/setup.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c1569dd8004b757e150bb9edd7517f0038986ed
--- /dev/null
+++ b/tests/lib/setup.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+use OCP\IConfig;
+
+class Test_OC_Setup extends PHPUnit_Framework_TestCase {
+
+	/** @var IConfig */
+	protected $config;
+	/** @var \OC_Setup */
+	protected $setupClass;
+
+	public function setUp() {
+		$this->config = $this->getMock('\OCP\IConfig');
+		$this->setupClass = $this->getMock('\OC_Setup', array('class_exists', 'is_callable'), array($this->config));
+	}
+
+	public function testGetSupportedDatabasesWithOneWorking() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->will($this->returnValue(
+				array('sqlite', 'mysql', 'oci')
+			));
+		$this->setupClass
+			->expects($this->once())
+			->method('class_exists')
+			->will($this->returnValue(true));
+		$this->setupClass
+			->expects($this->exactly(2))
+			->method('is_callable')
+			->will($this->returnValue(false));
+		$result = $this->setupClass->getSupportedDatabases();
+		$expectedResult = array(
+			'sqlite' => 'SQLite'
+		);
+
+		$this->assertSame($expectedResult, $result);
+	}
+
+	public function testGetSupportedDatabasesWithNoWorking() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->will($this->returnValue(
+				array('sqlite', 'mysql', 'oci', 'pgsql')
+			));
+		$this->setupClass
+			->expects($this->once())
+			->method('class_exists')
+			->will($this->returnValue(false));
+		$this->setupClass
+			->expects($this->exactly(3))
+			->method('is_callable')
+			->will($this->returnValue(false));
+		$result = $this->setupClass->getSupportedDatabases();
+
+		$this->assertSame(array(), $result);
+	}
+
+	public function testGetSupportedDatabasesWitAllWorking() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->will($this->returnValue(
+				array('sqlite', 'mysql', 'pgsql', 'oci', 'mssql')
+			));
+		$this->setupClass
+			->expects($this->once())
+			->method('class_exists')
+			->will($this->returnValue(true));
+		$this->setupClass
+			->expects($this->exactly(4))
+			->method('is_callable')
+			->will($this->returnValue(true));
+		$result = $this->setupClass->getSupportedDatabases();
+		$expectedResult = array(
+			'sqlite' => 'SQLite',
+			'mysql' => 'MySQL/MariaDB',
+			'pgsql' => 'PostgreSQL',
+			'oci' => 'Oracle',
+			'mssql' => 'MS SQL'
+		);
+		$this->assertSame($expectedResult, $result);
+	}
+
+	/**
+	 * @expectedException \Exception
+	 * @expectedExceptionMessage Supported databases are not properly configured.
+	 */
+	public function testGetSupportedDatabaseException() {
+		$this->config
+			->expects($this->once())
+			->method('getSystemValue')
+			->will($this->returnValue('NotAnArray'));
+		$this->setupClass->getSupportedDatabases();
+	}
+}
\ No newline at end of file