tbrehm
2012-05-10 e94a9fb5e4b6a2bc07e0bb4cf8ea35fc70c4bbf0
server/plugins-available/apache2_plugin.inc.php
@@ -110,6 +110,13 @@
      //* Create a SSL Certificate
      if($data['new']['ssl_action'] == 'create') {
         //* Rename files if they exist
         if(file_exists($key_file)) rename($key_file,$key_file.'.bak');
         if(file_exists($key_file2)) rename($key_file2,$key_file2.'.bak');
         if(file_exists($csr_file)) rename($csr_file,$csr_file.'.bak');
         if(file_exists($crt_file)) rename($crt_file,$crt_file.'.bak');
         $rand_file = $ssl_dir.'/random_file';
         $rand_data = md5(uniqid(microtime(),1));
         for($i=0; $i<1000; $i++) {
@@ -133,11 +140,11 @@
        output_password        = $ssl_password
        [ req_distinguished_name ]
        C                      = ".$data['new']['ssl_country']."
        ST                     = ".$data['new']['ssl_state']."
        L                      = ".$data['new']['ssl_locality']."
        O                      = ".$data['new']['ssl_organisation']."
        OU                     = ".$data['new']['ssl_organisation_unit']."
        C                      = ".trim($data['new']['ssl_country'])."
        ST                     = ".trim($data['new']['ssl_state'])."
        L                      = ".trim($data['new']['ssl_locality'])."
        O                      = ".trim($data['new']['ssl_organisation'])."
        OU                     = ".trim($data['new']['ssl_organisation_unit'])."
        CN                     = $domain
        emailAddress           = webmaster@".$data['new']['domain']."
@@ -167,7 +174,7 @@
               $app->log("Creating CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
               if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file",LOGLEVEL_ERROR);
            };
            if (filesize($crt_file)==0 || !file_exists($crt_file)){
            if (@filesize($crt_file)==0 || !file_exists($crt_file)){
               exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file ");
               $app->log("Creating self-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
            };
@@ -288,21 +295,49 @@
         $app->log('Websites cannot be owned by the root user or group.',LOGLEVEL_WARN);
         return 0;
      }
      if(trim($data['new']['domain']) == '') {
         $app->log('domain is empty',LOGLEVEL_WARN);
         return 0;
      }
      
      // Create group and user, if not exist
      $app->uses('system');
      if($web_config['connect_userid_to_webid'] == 'y') {
         //* Calculate the uid and gid
         $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
         $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
         $fixed_uid_param = '--uid '.$fixed_uid_gid;
         $fixed_gid_param = '--gid '.$fixed_uid_gid;
         //* Check if a ispconfigend user and group exists and create them
         if(!$app->system->is_group('ispconfigend')) {
            exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
         }
         if(!$app->system->is_user('ispconfigend')) {
            exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
         }
      } else {
         $fixed_uid_param = '';
         $fixed_gid_param = '';
      }
      $groupname = escapeshellcmd($data['new']['system_group']);
      if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
         exec('groupadd '.$groupname);
         exec('groupadd '.$fixed_gid_param.' '.$groupname);
         if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
         $app->log('Adding the group: '.$groupname,LOGLEVEL_DEBUG);
      }
      $username = escapeshellcmd($data['new']['system_user']);
      if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
         exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname -G sshusers $username -s /bin/false");
         if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname -G sshusers $username -s /bin/false");
         if($web_config['add_web_users_to_sshusers_group'] == 'y') {
            exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
            if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
         } else {
            exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
            if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
         }
         $app->log('Adding the user: '.$username,LOGLEVEL_DEBUG);
      }
@@ -339,7 +374,13 @@
         unset($tmp_docroot[count($tmp_docroot)-1]);
         $old_dir = implode('/',$tmp_docroot);
         exec('rm -rf '.$data['new']['document_root']);
         //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path
         if(@is_dir($data['new']['document_root'])) {
            rename($data['new']['document_root'],$data['new']['document_root'].'_bak_'.date('Y_m_d'));
            $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d'),LOGLEVEL_DEBUG);
         }
         //* Create new base directory, if it does not exist yet
         if(!is_dir($new_dir)) exec('mkdir -p '.$new_dir);
         exec('mv '.$data['old']['document_root'].' '.$new_dir);
         $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir,LOGLEVEL_DEBUG);
@@ -553,7 +594,7 @@
      //* If the security level is set to high
      if($this->action == 'insert' && $data['new']['type'] == 'vhost') {
      if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
         if($web_config['security_level'] == 20) {
            $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']));
@@ -565,11 +606,13 @@
         
            // Set Log symlink to 755 to make the logs accessible by the FTP user
            $this->_exec("chmod 755 ".escapeshellcmd($data["new"]["document_root"])."/log");
            $command = 'usermod';
            $command .= ' --groups sshusers';
            $command .= ' '.escapeshellcmd($data['new']['system_user']);
            $this->_exec($command);
            if($web_config['add_web_users_to_sshusers_group'] == 'y') {
               $command = 'usermod';
               $command .= ' --groups sshusers';
               $command .= ' '.escapeshellcmd($data['new']['system_user']);
               $this->_exec($command);
            }
            //* if we have a chrooted Apache environment
            if($apache_chrooted) {
@@ -585,8 +628,14 @@
            //* add the Apache user to the client group
            $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
            //* Chown all default directories
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/cgi-bin'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/log'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/ssl'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/tmp'));
            $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/web'));
            /*
            * Workaround for jailkit: If jailkit is enabled for the site, the 
@@ -605,11 +654,20 @@
         } else {
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/*'));
            $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/cgi-bin'));
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/log'));
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/ssl'));
            $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/web'));
            // make temp directory writable for Apache and the website users
            $this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
            $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/cgi-bin'));
            $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root'].'/log'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/tmp'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/ssl'));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/web'));
         }
      }
@@ -637,7 +695,7 @@
         if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
            $php_ini_content .= file_get_contents($master_php_ini_path)."\n";
         }
         $php_ini_content .= trim($data['new']['custom_php_ini']);
         $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini']));
         file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
      } else {
         $has_custom_php_ini = false;
@@ -662,6 +720,11 @@
      $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
      $vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
      $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
      // Custom Apache directives
      // Make sure we only have Unix linebreaks
      $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
      $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
      // Check if a SSL cert exists
      $ssl_dir = $data['new']['document_root'].'/ssl';
@@ -703,7 +766,7 @@
      // Rewrite rules
      $rewrite_rules = array();
      if($data['new']['redirect_type'] != '') {
      if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
         if(substr($data['new']['redirect_path'],-1) != '/') $data['new']['redirect_path'] .= '/';
         if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){
            $rewrite_target = 'http'.substr($data['new']['redirect_path'],8);
@@ -730,7 +793,7 @@
                     'rewrite_target_ssl' => $rewrite_target_ssl);
               break;
            case '*':
               $rewrite_rules[] = array(   'rewrite_domain'    => $data['new']['domain'],
               $rewrite_rules[] = array(   'rewrite_domain'    => '(^|\.)'.$data['new']['domain'],
                  'rewrite_type'       => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
                  'rewrite_target'    => $rewrite_target,
                  'rewrite_target_ssl' => $rewrite_target_ssl);
@@ -769,7 +832,7 @@
            }
            $app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG);
            // Rewriting
            if($alias['redirect_type'] != '') {
            if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') {
               if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/';
               if(substr($alias['redirect_path'],0,8) == '[scheme]'){
                  $rewrite_target = 'http'.substr($alias['redirect_path'],8);
@@ -796,7 +859,7 @@
                           'rewrite_target_ssl' => $rewrite_target_ssl);
                     break;
                  case '*':
                     $rewrite_rules[] = array(   'rewrite_domain'    => $alias['domain'],
                     $rewrite_rules[] = array(   'rewrite_domain'    => '(^|\.)'.$alias['domain'],
                        'rewrite_type'       => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
                        'rewrite_target'    => $rewrite_target,
                        'rewrite_target_ssl' => $rewrite_target_ssl);
@@ -862,15 +925,32 @@
         $fcgi_tpl = new tpl();
         $fcgi_tpl->newTemplate('php-fcgi-starter.master');
         
         // Support for multiple PHP versions (FastCGI)
         if(trim($data['new']['fastcgi_php_version']) != ''){
            $default_fastcgi_php = false;
            list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
            if(substr($custom_fastcgi_php_ini_dir,-1) != '/') $custom_fastcgi_php_ini_dir .= '/';
         } else {
            $default_fastcgi_php = true;
         }
         if($has_custom_php_ini) {
            $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_php_ini_dir));
         } else {
            $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
            if($default_fastcgi_php){
               $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
            } else {
               $fcgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_fastcgi_php_ini_dir));
            }
         }
         $fcgi_tpl->setVar('document_root',escapeshellcmd($data['new']['document_root']));
         $fcgi_tpl->setVar('php_fcgi_children',escapeshellcmd($fastcgi_config['fastcgi_children']));
         $fcgi_tpl->setVar('php_fcgi_max_requests',escapeshellcmd($fastcgi_config['fastcgi_max_requests']));
         $fcgi_tpl->setVar('php_fcgi_bin',escapeshellcmd($fastcgi_config['fastcgi_bin']));
         if($default_fastcgi_php){
            $fcgi_tpl->setVar('php_fcgi_bin',escapeshellcmd($fastcgi_config['fastcgi_bin']));
         } else {
            $fcgi_tpl->setVar('php_fcgi_bin',escapeshellcmd($custom_fastcgi_php_executable));
         }
         $fcgi_tpl->setVar('security_level',intval($web_config['security_level']));
         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
@@ -891,7 +971,62 @@
         $tpl->setVar('fastcgi_starter_script',$fastcgi_config['fastcgi_starter_script']);
         $tpl->setVar('fastcgi_config_syntax',$fastcgi_config['fastcgi_config_syntax']);
      } else {
         //remove the php fastgi starter script if available
         if ($data['old']['php'] == 'fast-cgi') {
            $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
            $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$fastcgi_config['fastcgi_starter_path']);
            $fastcgi_starter_path = str_replace('[client_id]',$client_id,$fastcgi_starter_path);
            if (is_dir($fastcgi_starter_path)) {
               exec('rm -rf '.$fastcgi_starter_path);
            }
         }
      }
      /**
      * PHP-FPM
      */
      // Support for multiple PHP versions
      if($data['new']['php'] == 'php-fpm'){
         if(trim($data['new']['fastcgi_php_version']) != ''){
            $default_php_fpm = false;
            list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
            if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
         } else {
            $default_php_fpm = true;
         }
      } else {
         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
            $default_php_fpm = false;
            list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
            if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
         } else {
            $default_php_fpm = true;
         }
      }
      if($default_php_fpm){
         $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
      } else {
         $pool_dir = $custom_php_fpm_pool_dir;
      }
      if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
      $pool_name = 'web'.$data['new']['domain_id'];
      $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
      if(substr($socket_dir,-1) != '/') $socket_dir .= '/';
      if($data['new']['php_fpm_use_socket'] == 'y'){
         $use_tcp = 0;
         $use_socket = 1;
      } else {
         $use_tcp = 1;
         $use_socket = 0;
      }
      $tpl->setVar('use_tcp', $use_tcp);
      $tpl->setVar('use_socket', $use_socket);
      $fpm_socket = $socket_dir.$pool_name.'.sock';
      $tpl->setVar('fpm_socket', $fpm_socket);
      $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
      /**
       * install cgi starter script and add script alias to config.
@@ -1051,6 +1186,11 @@
            unlink($vhost_symlink);
            $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
         }
         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
         if(is_link($vhost_symlink)) {
            unlink($vhost_symlink);
            $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
         }
         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
         unlink($vhost_file);
         $app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG);
@@ -1079,6 +1219,8 @@
         $this->awstats_update($data,$web_config);
      }
      
      $this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir);
      if($web_config['check_apache_config'] == 'y') {
         //* Test if apache starts with the new configuration file
         $apache_online_status_before_restart = $this->_checkTcp('localhost',80);
@@ -1095,7 +1237,13 @@
         if($apache_online_status_before_restart && !$apache_online_status_after_restart) {
            $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the configuration. Saved non-working config as '.$vhost_file.'.err',LOGLEVEL_WARN);
            copy($vhost_file,$vhost_file.'.err');
            copy($vhost_file.'~',$vhost_file);
            if(is_file($vhost_file.'~')) {
               //* Copy back the last backup file
               copy($vhost_file.'~',$vhost_file);
            } else {
               //* There is no backup file, so we create a empty vhost file with a warning message inside
               file_put_contents($vhost_file,"# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
            }
            $app->services->restartService('httpd','restart');
         }
      } else {
@@ -1175,6 +1323,11 @@
            if (is_dir($fastcgi_starter_path)) {
               exec('rm -rf '.$fastcgi_starter_path);
            }
         }
         // remove PHP-FPM pool
         if ($data['old']['php'] == 'php-fpm') {
            $this->php_fpm_pool_delete($data,$web_config);
         }
         //remove the php cgi starter script if available
@@ -1315,12 +1468,18 @@
      }
      
      //* Create the folder path, if it does not exist
      if(!is_dir($folder_path)) exec('mkdir -p '.$folder_path);
      if(!is_dir($folder_path)) {
         exec('mkdir -p '.$folder_path);
         chown($folder_path,$website['system_user']);
         chgrp($folder_path,$website['system_group']);
      }
      
      //* Create empty .htpasswd file, if it does not exist
      if(!is_file($folder_path.'.htpasswd')) {
         touch($folder_path.'.htpasswd');
         chmod($folder_path.'.htpasswd',0755);
         chown($folder_path.'.htpasswd',$website['system_user']);
         chgrp($folder_path.'.htpasswd',$website['system_group']);
         $app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
      }
      
@@ -1358,7 +1517,9 @@
      //if(!is_file($folder_path.'.htaccess')) {
         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user";
         file_put_contents($folder_path.'.htaccess',$ht_file);
         chmod($folder_path.'.htpasswd',0755);
         chmod($folder_path.'.htaccess',0755);
         chown($folder_path.'.htaccess',$website['system_user']);
         chgrp($folder_path.'.htaccess',$website['system_group']);
         $app->log('Created file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
      //}
      
@@ -1470,7 +1631,9 @@
         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user";
         file_put_contents($new_folder_path.'.htaccess',$ht_file);
         chmod($new_folder_path.'.htpasswd',0755);
         $app->log('Created file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
         chown($folder_path.'.htpasswd',$website['system_user']);
         chgrp($folder_path.'.htpasswd',$website['system_group']);
         $app->log('Created file '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
      }
      
      //* Remove .htaccess file
@@ -1508,6 +1671,7 @@
         $domain = $sitedata['domain'];
         $user = $sitedata['system_user'];
         $group = $sitedata['system_group'];
         $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
         /* Check if this is a chrooted setup */
         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
@@ -1516,13 +1680,25 @@
         } else {
            $apache_chrooted = false;
         }
         //* We dont want to have relative paths here
         if(stristr($webdav_user_dir,'..')  || stristr($webdav_user_dir,'./')) {
            $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot,LOGLEVEL_WARN);
            return false;
         }
         //* Check if the resulting path exists if yes, if it is inside the docroot
         if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir),0,strlen($documentRoot)) != $documentRoot) {
            $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot,LOGLEVEL_WARN);
            return false;
         }
         /*
          * First the webdav-root - folder has to exist
         */
         if(!is_dir($documentRoot . '/webdav/' . $data['new']['dir'])) {
            $app->log('Webdav User directory '.$documentRoot.'/webdav/'.$data['new']['dir'].' does not exist. Creating it now.',LOGLEVEL_DEBUG);
            exec('mkdir -p '.escapeshellcmd($documentRoot . '/webdav/' . $data['new']['dir']));
         if(!is_dir($webdav_user_dir)) {
            $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.',LOGLEVEL_DEBUG);
            exec('mkdir -p '.escapeshellcmd($webdav_user_dir));
         }
         /*
@@ -1535,19 +1711,19 @@
          * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
          * pwd-files are owned by root)
         */
         $this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'. $data['new']['dir'] . ' -R'));
         $this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/' . $data['new']['dir'] . ' -R'));
         $this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
         $this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
         /*
          * if the user is active, we have to write/update the password - file
          * if the user is inactive, we have to inactivate the user by removing the user from the file
         */
         if ($data['new']['active'] == 'y') {
            $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['new']['dir'] . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
            $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
         }
         else {
            /* empty pwd removes the user! */
            $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['new']['dir'] . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
            $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
         }
         /*
@@ -1699,6 +1875,7 @@
                  $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
                  $output .= "      <Location /webdav/" . $fn . ">\n";
                  $output .= "        DAV On\n";
                  $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
                  $output .= "        AuthType Digest\n";
                  $output .= "        AuthName \"" . $fn . "\"\n";
                  $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
@@ -1743,6 +1920,7 @@
      
      $awstats_conf_dir = $web_config['awstats_conf_dir'];
      
      if(!is_dir($data['new']['document_root']."/web/stats/")) mkdir($data['new']['document_root']."/web/stats");
      if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
            unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
@@ -1774,6 +1952,225 @@
      }
   }
   
   //* Update the PHP-FPM pool configuration file
   private function php_fpm_pool_update ($data,$web_config,$pool_dir,$pool_name,$socket_dir) {
      global $app, $conf;
      //$reload = false;
      if($data['new']['php'] == 'php-fpm'){
         if(trim($data['new']['fastcgi_php_version']) != ''){
            $default_php_fpm = false;
            list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
            if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
         } else {
            $default_php_fpm = true;
         }
      } else {
         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
            $default_php_fpm = false;
            list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
            if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
         } else {
            $default_php_fpm = true;
         }
      }
      $app->uses("getconf");
      $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
      if($data['new']['php'] != 'php-fpm'){
         if(@is_file($pool_dir.$pool_name.'.conf')){
            unlink($pool_dir.$pool_name.'.conf');
            //$reload = true;
         }
         if($data['old']['php'] == 'php-fpm'){
            if(!$default_php_fpm){
               $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
            } else {
               $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
            }
         }
         //if($reload == true) $app->services->restartService('php-fpm','reload');
         return;
      }
      $app->load('tpl');
      $tpl = new tpl();
      $tpl->newTemplate('php_fpm_pool.conf.master');
      if($data['new']['php_fpm_use_socket'] == 'y'){
         $use_tcp = 0;
         $use_socket = 1;
         if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
      } else {
         $use_tcp = 1;
         $use_socket = 0;
      }
      $tpl->setVar('use_tcp', $use_tcp);
      $tpl->setVar('use_socket', $use_socket);
      $fpm_socket = $socket_dir.$pool_name.'.sock';
      $tpl->setVar('fpm_socket', $fpm_socket);
      $tpl->setVar('fpm_pool', $pool_name);
      $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
      $tpl->setVar('fpm_user', $data['new']['system_user']);
      $tpl->setVar('fpm_group', $data['new']['system_group']);
      $tpl->setVar('pm', $data['new']['pm']);
      $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
      $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
      $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
      $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
      $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
      $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
      $tpl->setVar('document_root', $data['new']['document_root']);
      $tpl->setVar('security_level',$web_config['security_level']);
      $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
      $tpl->setVar('php_open_basedir', $php_open_basedir);
      if($php_open_basedir != ''){
         $tpl->setVar('enable_php_open_basedir', '');
      } else {
         $tpl->setVar('enable_php_open_basedir', ';');
      }
      // Custom php.ini settings
      $final_php_ini_settings = array();
      $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
      if($custom_php_ini_settings != ''){
         // Make sure we only have Unix linebreaks
         $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
         $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
         $ini_settings = explode("\n", $custom_php_ini_settings);
         if(is_array($ini_settings) && !empty($ini_settings)){
            foreach($ini_settings as $ini_setting){
                  list($key, $value) = explode('=', $ini_setting);
                  if($value){
                     $value = escapeshellcmd(trim($value));
                     $key = escapeshellcmd(trim($key));
                     switch (strtolower($value)) {
                        case 'on':
                        case 'off':
                        case '1':
                        case '0':
                           // PHP-FPM might complain about invalid boolean value if you use 0
                           $value = 'off';
                        case 'true':
                        case 'false':
                        case 'yes':
                        case 'no':
                           $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
                           break;
                        default:
                           $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
                     }
                  }
            }
         }
      }
      $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
      file_put_contents($pool_dir.$pool_name.'.conf',$tpl->grab());
      $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
      unset($tpl);
      // delete pool in all other PHP versions
      $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
      if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/';
      if($default_pool_dir != $pool_dir){
         if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
               unlink($default_pool_dir.$pool_name.'.conf');
               $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
               $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
         }
      }
      $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]);
      if(is_array($php_versions) && !empty($php_versions)){
         foreach($php_versions as $php_version){
            if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
            if($php_version['php_fpm_pool_dir'] != $pool_dir){
               if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
                  unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
                  $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG);
                  $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']);
               }
            }
         }
      }
      // Reload current PHP-FPM after all others
      sleep(1);
      if(!$default_php_fpm){
         $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
      } else {
         $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
      }
      //$reload = true;
      //if($reload == true) $app->services->restartService('php-fpm','reload');
   }
   //* Delete the PHP-FPM pool configuration file
   private function php_fpm_pool_delete ($data,$web_config) {
      global $app, $conf;
      if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
         $default_php_fpm = false;
         list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
         if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
      } else {
         $default_php_fpm = true;
      }
      if($default_php_fpm){
         $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
      } else {
         $pool_dir = $custom_php_fpm_pool_dir;
      }
      if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
      $pool_name = 'web'.$data['old']['domain_id'];
      if ( @is_file($pool_dir.$pool_name.'.conf') ) {
         unlink($pool_dir.$pool_name.'.conf');
         $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
         //$app->services->restartService('php-fpm','reload');
      }
      // delete pool in all other PHP versions
      $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
      if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/';
      if($default_pool_dir != $pool_dir){
         if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
               unlink($default_pool_dir.$pool_name.'.conf');
               $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG);
               $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
         }
      }
      $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']);
      if(is_array($php_versions) && !empty($php_versions)){
         foreach($php_versions as $php_version){
            if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
            if($php_version['php_fpm_pool_dir'] != $pool_dir){
               if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
                  unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
                  $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG);
                  $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']);
               }
            }
         }
      }
      // Reload current PHP-FPM after all others
      sleep(1);
      if(!$default_php_fpm){
         $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
      } else {
         $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
      }
   }
   function client_delete($event_name,$data) {
      global $app, $conf;