Example #1
0
 *
 * Initialize configuration database
 *
 * @copyright Noumenia (C) 2015 - All rights reserved - Software Development - www.noumenia.gr
 * @license GNU GPL v3.0
 * @package aetolos
 * @subpackage databaseinit
 */
// No direct access - loadable only
if (!defined('AET_IN')) {
    die("No Access");
}
// Open database
$db = new DatabaseSqlite3();
$rc = $db->open();
if ($rc === false) {
    echo "[ERROR] Encountered an error while opening the database.\n";
    exit(9);
}
// Load global configuration from database
$rc = Config::loadDatabase($db);
if ($rc === false) {
    echo "[ERROR] Encountered an error while loading the global configuration. If this is a new installation, please run the setup to initialize the database.\n";
    exit(9);
}
// Check database version
$rc = Config::read('aetolos|dbversion');
if (AET_DB_VER !== $rc) {
    echo "[ERROR] Database mismatch error. Please run the setup to update the database.\n";
    exit(9);
}
Example #2
0
 /**
  * Setup configuration database, handle versioning and upgrades
  * @param DatabaseSqlite3 &$db Database object
  * @return void
  */
 public static function setupDatabase(&$db)
 {
     Log::debug('Checking Aetolos database');
     // Global configuration table
     $rc = $db->query(self::$schemaConfig);
     if ($rc === false) {
         return false;
     }
     // Verify that the table was created successfully
     $db->query("SELECT 1 FROM `sqlite_master` WHERE type='table' AND name='config'");
     $db->next_row();
     if (!isset($db->row[0]) || $db->row[0] !== "1") {
         Log::error('Error while creating table: config');
         return false;
     }
     // Check database version or check for an empty/new database
     $db->query("SELECT Value FROM `config` WHERE Config='aetolos|dbversion'");
     $db->next_row();
     if ($db->row === false) {
         // New database, set default values
         $config = array();
         // Aetolos
         $config['aetolos|version'] = AET_VER;
         $config['aetolos|dbversion'] = AET_DB_VER;
         $config['aetolos|features'] = 'php|opendkim|nsd|clamav|spamassassin|postfix|dovecot|mariadb|roundcube|apache';
         // Smarty
         $config['smarty|templateDirectory'] = dirname(__DIR__) . '/templates';
         $config['smarty|compileDirectory'] = dirname(__DIR__) . '/smarty/templates_c';
         $config['smarty|cacheDirectory'] = dirname(__DIR__) . '/smarty/cache';
         $config['smarty|configDirectory'] = dirname(__DIR__) . '/smarty/configs';
         $config['smarty|pluginsDirectory'] = dirname(__DIR__) . '/smarty/libs/plugins';
         $config['smarty|cacheLifetime'] = 14400;
         $config['smarty|debug'] = false;
         // PHP
         $config['php|iniFile'] = '/etc/php.ini';
         // NSD
         $config['nsd'] = 'enabled';
         $config['nsd|nsdConfFile'] = '/etc/nsd/nsd.conf';
         $config['nsd|directoryConfD'] = '/etc/nsd/conf.d';
         $config['nsd|selinuxModule'] = '';
         // ClamAV
         $config['clamav'] = 'enabled';
         $config['clamav|clamdConfFile'] = '/etc/clamd.d/clamd.conf';
         $config['clamav|clamdSysconfigFile'] = '/etc/sysconfig/clamd';
         $config['clamav|clamdSystemdFile'] = '/usr/lib/systemd/system/clamd.service';
         $config['clamav|clamdTmpfilesFile'] = '/usr/lib/tmpfiles.d/clamd.conf';
         $config['clamav|freshclamFile'] = '/etc/freshclam.conf';
         $config['clamav|clamavMilterFile'] = '/etc/mail/clamav-milter.conf';
         $config['clamav|clamavMilterTmp'] = '/usr/lib/tmpfiles.d/clamav-milter.conf';
         $config['clamav|selinuxModule'] = '';
         // Spamassassin
         $config['spamassassin'] = 'enabled';
         $config['spamassassin|initPreFile'] = '/etc/mail/spamassassin/init.pre';
         $config['spamassassin|milterFile'] = '/etc/sysconfig/spamass-milter';
         $config['spamassassin|localCfFile'] = '/etc/mail/spamassassin/local.cf';
         $config['spamassassin|selinuxModule'] = '';
         // Postfix
         $config['postfix'] = 'enabled';
         $config['postfix|postfixDirectory'] = '/etc/postfix';
         $config['postfix|virtualDomainsFile'] = '/etc/postfix/virtual_mailbox_domains';
         $config['postfix|selinuxModule'] = '';
         // OpenDKIM
         $config['opendkim'] = 'enabled';
         $config['opendkim|opendkimConfFile'] = '/etc/opendkim.conf';
         // Dovecot
         $config['dovecot'] = 'enabled';
         $config['dovecot|confFile'] = '/etc/dovecot/dovecot.conf';
         $config['dovecot|directoryConfD'] = '/etc/dovecot/conf.d';
         $config['dovecot|selinuxModule'] = '';
         // MariaDB
         $config['mariadb'] = 'enabled';
         $config['mariadb|serverFile'] = '/etc/my.cnf.d/server.cnf';
         // Roundcube
         $config['roundcube'] = 'enabled';
         $config['roundcube|dbPassword'] = hash('sha256', openssl_random_pseudo_bytes(16));
         $config['roundcube|desKey'] = mb_substr(hash('sha256', openssl_random_pseudo_bytes(16)), rand(0, 40), 24);
         $config['roundcube|configFile'] = '/etc/roundcubemail/config.inc.php';
         // Apache
         $config['apache'] = 'enabled';
         $config['apache|directoryConf'] = '/etc/httpd/conf';
         $config['apache|directoryConfD'] = '/etc/httpd/conf.d';
         $config['apache|directoryConfModulesD'] = '/etc/httpd/conf.modules.d';
         $config['apache|maxClients'] = 50;
         $config['apache|selinuxModule'] = '';
         // PKI/TLS
         $config['pkitls|directoryCerts'] = '/etc/pki/tls/certs';
         $config['pkitls|directoryPrivate'] = '/etc/pki/tls/private';
         // Write to global configuration and save to database
         foreach ($config as $key => $value) {
             Config::write($db, $key, $value);
         }
     } else {
         if (isset($db->row[0]) && $db->row[0] !== AET_DB_VER) {
             // Current version number
             $ver = (int) $db->row[0];
             // Back to the future?
             if ($ver > AET_DB_VER) {
                 Log::error('The database version ' . $ver . ' is higher than the supported version ' . AET_DB_VER . ' of this Aetolos installation');
                 return false;
             }
             // Loop while current version requires updating
             while ($ver < AET_DB_VER) {
                 // Version numbers
                 switch ($ver) {
                     case 1:
                         /*
                          * WTF?
                          *
                          * You are probably wondering what is the meaning of the following block of code,
                          * well so have I, like many others who have stumbled uppon this issue. The 1st
                          * iteration of the database used 'UNIQUE' on two columns that had to be removed
                          * by altering the table schema. Apparently this is not supported by SQlite3,
                          * thus the only solution was to create a temporary table, copy the rows, delete
                          * the old table, create a table with the new schema, copy the rows and finally
                          * delete the temporary table. Note to self: RTFM
                          *
                          */
                         $db->conn->beginTransaction();
                         $rc1 = $db->query('CREATE TABLE `virtualHost_backup` ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Created DATETIME DEFAULT CURRENT_TIMESTAMP, DomainName VARCHAR(253) NOT NULL UNIQUE, UnixName VARCHAR(32) NOT NULL, DbPrefix VARCHAR(8) NOT NULL, IpAddress VARCHAR(39) NOT NULL, Home VARCHAR(255) NOT NULL, DomainZoneVersion INTEGER DEFAULT 1, AdminEmail VARCHAR(255), Quota INTEGER DEFAULT 0, BandwidthLimit INTEGER, MaxEmails INTEGER, MaxDatabases INTEGER, MaxSubDomains INTEGER, MaxParkedDomains INTEGER, ParkedUnder INTEGER, FOREIGN KEY(ParkedUnder) REFERENCES virtualHost(Id) )');
                         $rc2 = $db->query('INSERT INTO `virtualHost_backup` SELECT *,null FROM `virtualHost`');
                         $rc3 = $db->query('DROP TABLE `virtualHost`');
                         $rc4 = $db->query('CREATE TABLE `virtualHost` ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Created DATETIME DEFAULT CURRENT_TIMESTAMP, DomainName VARCHAR(253) NOT NULL UNIQUE, UnixName VARCHAR(32) NOT NULL, DbPrefix VARCHAR(8) NOT NULL, IpAddress VARCHAR(39) NOT NULL, Home VARCHAR(255) NOT NULL, DomainZoneVersion INTEGER DEFAULT 1, AdminEmail VARCHAR(255), Quota INTEGER DEFAULT 0, BandwidthLimit INTEGER, MaxEmails INTEGER, MaxDatabases INTEGER, MaxSubDomains INTEGER, MaxParkedDomains INTEGER, ParkedUnder INTEGER, FOREIGN KEY(ParkedUnder) REFERENCES virtualHost(Id) )');
                         $rc5 = $db->query('INSERT INTO `virtualHost` SELECT * FROM `virtualHost_backup`');
                         $rc6 = $db->query('DROP TABLE `virtualHost_backup`');
                         if ($rc1 === true && $rc2 === true && $rc3 === true && $rc4 === true && $rc5 === true && $rc6 === true) {
                             $db->conn->commit();
                         } else {
                             $db->conn->rollBack();
                             return false;
                         }
                         $db->query("UPDATE `config` SET Value='2' WHERE Config='aetolos|dbversion'");
                         $ver++;
                         break;
                     case 2:
                         /*
                          * OpenDKIM configuration parameters
                          */
                         $db->conn->beginTransaction();
                         $rc1 = $db->query('INSERT OR REPLACE INTO `config` (Config, Value) VALUES ("opendkim", "enabled")');
                         $rc2 = $db->query('INSERT OR REPLACE INTO `config` (Config, Value) VALUES ("opendkim|opendkimConfFile", "/etc/opendkim.conf")');
                         $rc3 = $db->query("UPDATE `config` SET Value='php|opendkim|nsd|clamav|spamassassin|postfix|dovecot|mariadb|roundcube|apache' WHERE Config='aetolos|features'");
                         if ($rc1 === true && $rc2 === true && $rc3 === true) {
                             $db->conn->commit();
                         } else {
                             $db->conn->rollBack();
                             return false;
                         }
                         $db->query("UPDATE `config` SET Value='3' WHERE Config='aetolos|dbversion'");
                         $ver++;
                         break;
                     case 3:
                         /*
                          * Spamassassin configuration parameter
                          */
                         $db->conn->beginTransaction();
                         $rc1 = $db->query('INSERT OR REPLACE INTO `config` (Config, Value) VALUES ("spamassassin|initPreFile", "/etc/mail/spamassassin/init.pre")');
                         if ($rc1 === true) {
                             $db->conn->commit();
                         } else {
                             $db->conn->rollBack();
                             return false;
                         }
                         $db->query("UPDATE `config` SET Value='4' WHERE Config='aetolos|dbversion'");
                         $ver++;
                         break;
                     case 4:
                         /*
                          * Spamassassin configuration parameter
                          */
                         $db->conn->beginTransaction();
                         $rc1 = $db->query('INSERT OR REPLACE INTO `config` (Config, Value) VALUES ("spamassassin|milterFile", "/etc/sysconfig/spamass-milter")');
                         if ($rc1 === true) {
                             $db->conn->commit();
                         } else {
                             $db->conn->rollBack();
                             return false;
                         }
                         $db->query("UPDATE `config` SET Value='5' WHERE Config='aetolos|dbversion'");
                         $ver++;
                         break;
                 }
             }
         }
         // Load existing table data
         $rc = Config::loadDatabase($db);
         if ($rc === false) {
             return false;
         }
     }
     // Virtual host configuration table
     $rc = $db->query(self::$schemaVirtualHost);
     if ($rc === false) {
         return false;
     }
     // DNS configuration table
     $rc = $db->query(self::$schemaVirtualHostNs);
     if ($rc === false) {
         return false;
     }
     // Mail servers configuration table
     $rc = $db->query(self::$schemaVirtualHostMx);
     if ($rc === false) {
         return false;
     }
     // Verify that the table was created successfully
     $db->query("SELECT 1 FROM `sqlite_master` WHERE type='table' AND name='virtualHost'");
     $db->next_row();
     if (!isset($db->row[0]) || $db->row[0] !== "1") {
         Log::error('Error while creating table: virtualHost');
         return false;
     }
     return $db;
 }