From 8e7d5ff1c1a503389e8c1a57e6b9be0ff009b75c Mon Sep 17 00:00:00 2001
From: Elijah Lynn <elijah@elijahlynn.net>
Date: Mon, 19 Jun 2017 17:07:54 -0400
Subject: [PATCH] Add PDO $options support

I may be missing something but I haven't found a way to add the --ssl-ca
MySQL option to my database connection. It appears we just need to pass
in an $options param.
---
 config-templates/config.php                   |  7 ++---
 docs/simplesamlphp-customauth.md              |  9 +++++--
 lib/SimpleSAML/Store/SQL.php                  |  3 ++-
 .../consent/lib/Consent/Store/Database.php    | 26 ++++++++++++++++---
 modules/sqlauth/lib/Auth/Source/SQL.php       |  9 ++++++-
 5 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/config-templates/config.php b/config-templates/config.php
index c3e8bb930..d6ca60672 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -1,7 +1,7 @@
 <?php
-/* 
+/*
  * The configuration of SimpleSAMLphp
- * 
+ *
  */
 
 $config = array(
@@ -39,7 +39,7 @@ $config = array(
      * - 'temdir': Saving temporary files. SimpleSAMLphp will attempt to create
      *   this directory if it doesn't exist.
      * When specified as a relative path, this is relative to the SimpleSAMLphp
-     * root directory. 
+     * root directory.
      */
     'certdir' => 'cert/',
     'loggingdir' => 'log/',
@@ -349,6 +349,7 @@ $config = array(
      */
     'database.username' => 'simplesamlphp',
     'database.password' => 'secret',
+    'database.options' => array(),
 
     /*
      * (Optional) Table prefix
diff --git a/docs/simplesamlphp-customauth.md b/docs/simplesamlphp-customauth.md
index 8f7c30f9f..8f0c2c042 100644
--- a/docs/simplesamlphp-customauth.md
+++ b/docs/simplesamlphp-customauth.md
@@ -253,9 +253,10 @@ The class follows:
          */
         private $dsn;
 
-        /* The database username & password. */
+        /* The database username, password & options. */
         private $username;
         private $password;
+        private $options;
 
         public function __construct($info, $config) {
             parent::__construct($info, $config);
@@ -272,6 +273,10 @@ The class follows:
                 throw new Exception('Missing or invalid password option in config.');
             }
             $this->password = $config['password'];
+            $this->options = $config['options'];
+            if (!is_array($config['options])) {
+                throw new Exception('Missing or invalid options option in config.');
+            }
         }
 
         /**
@@ -294,7 +299,7 @@ The class follows:
         protected function login($username, $password) {
 
             /* Connect to the database. */
-            $db = new PDO($this->dsn, $this->username, $this->password);
+            $db = new PDO($this->dsn, $this->username, $this->password, $this->options);
             $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
             /* Ensure that we are operating with UTF-8 encoding.
diff --git a/lib/SimpleSAML/Store/SQL.php b/lib/SimpleSAML/Store/SQL.php
index 4152d7afb..4f6db39b1 100644
--- a/lib/SimpleSAML/Store/SQL.php
+++ b/lib/SimpleSAML/Store/SQL.php
@@ -55,9 +55,10 @@ class SQL extends Store
         $dsn = $config->getString('store.sql.dsn');
         $username = $config->getString('store.sql.username', null);
         $password = $config->getString('store.sql.password', null);
+        $options = $config->getArray('store.sql.options', null);
         $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp');
 
-        $this->pdo = new \PDO($dsn, $username, $password);
+        $this->pdo = new \PDO($dsn, $username, $password, $options);
         $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
 
         $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
diff --git a/modules/consent/lib/Consent/Store/Database.php b/modules/consent/lib/Consent/Store/Database.php
index 348821894..ff5993dad 100644
--- a/modules/consent/lib/Consent/Store/Database.php
+++ b/modules/consent/lib/Consent/Store/Database.php
@@ -37,6 +37,11 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
      */
     private $_password;
 
+    /**
+     * Options for the database;
+     */
+    private $_options;
+
     /**
      * Table with consent.
      */
@@ -99,6 +104,14 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
             $this->_password = null;
         }
 
+        if (array_key_exists('options', $config)) {
+            if (!is_array($config['options'])) {
+                throw new Exception('consent:Database - \'options\' is supposed to be an array.');
+            }
+            $this->_options = $config['options'];
+        } else {
+            $this->_options = null;
+        }
         if (array_key_exists('table', $config)) {
             if (!is_string($config['table'])) {
                 throw new Exception('consent:Database - \'table\' is supposed to be a string.');
@@ -384,7 +397,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         // Get total number of consents
         $st = $this->_execute('SELECT COUNT(*) AS no FROM consent', array());
-        
+
         if ($st === false) {
             return array();
         }
@@ -399,7 +412,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
             'FROM (SELECT DISTINCT hashed_user_id FROM consent ) AS foo',
             array()
         );
-        
+
         if ($st === false) {
             return array();
         }
@@ -413,7 +426,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
             'SELECT COUNT(*) AS no FROM (SELECT DISTINCT service_id FROM consent) AS foo',
             array()
         );
-        
+
         if ($st === false) {
             return array();
         }
@@ -471,8 +484,13 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
         if (isset($this->_timeout)) {
             $driver_options[PDO::ATTR_TIMEOUT] = $this->_timeout;
         }
+        if (isset($this->_options)) {
+            array_merge($driver_options, $this->_options);
+        } else {
+            $this->_options = $driver_options;
+        }
 
-        $this->_db = new PDO($this->_dsn, $this->_username, $this->_password, $driver_options);
+        $this->_db = new PDO($this->_dsn, $this->_username, $this->_password, $this->_options);
 
         return $this->_db;
     }
diff --git a/modules/sqlauth/lib/Auth/Source/SQL.php b/modules/sqlauth/lib/Auth/Source/SQL.php
index 8a4b28064..7f4694211 100644
--- a/modules/sqlauth/lib/Auth/Source/SQL.php
+++ b/modules/sqlauth/lib/Auth/Source/SQL.php
@@ -29,6 +29,12 @@ class sspmod_sqlauth_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase {
 	private $password;
 
 
+    /**
+     * The options that we should connect to the database with.
+     */
+    private $options;
+
+
 	/**
 	 * The query we should use to retrieve the attributes for the user.
 	 *
@@ -68,6 +74,7 @@ class sspmod_sqlauth_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase {
 		$this->dsn = $config['dsn'];
 		$this->username = $config['username'];
 		$this->password = $config['password'];
+		$this->options = $config['options'];
 		$this->query = $config['query'];
 	}
 
@@ -79,7 +86,7 @@ class sspmod_sqlauth_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase {
 	 */
 	private function connect() {
 		try {
-			$db = new PDO($this->dsn, $this->username, $this->password);
+			$db = new PDO($this->dsn, $this->username, $this->password, $this->options);
 		} catch (PDOException $e) {
 			throw new Exception('sqlauth:' . $this->authId . ': - Failed to connect to \'' .
 				$this->dsn . '\': '. $e->getMessage());
-- 
GitLab