tbrehm
2012-06-05 fa2806bddf4ce838d30d7fab1b5300e8632c586d
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);
            };
@@ -190,7 +197,7 @@
      //* Save a SSL certificate to disk
      if($data["new"]["ssl_action"] == 'save') {
         $ssl_dir = $data["new"]["document_root"]."/ssl";
         $domain = $data["new"]["ssl_domain"];
         $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
         $csr_file = $ssl_dir.'/'.$domain.".csr";
         $crt_file = $ssl_dir.'/'.$domain.".crt";
         $bundle_file = $ssl_dir.'/'.$domain.".bundle";
@@ -207,7 +214,7 @@
      //* Delete a SSL certificate
      if($data['new']['ssl_action'] == 'del') {
         $ssl_dir = $data['new']['document_root'].'/ssl';
         $domain = $data['new']['ssl_domain'];
         $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
         $csr_file = $ssl_dir.'/'.$domain.'.csr';
         $crt_file = $ssl_dir.'/'.$domain.'.crt';
         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
@@ -227,7 +234,6 @@
         $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
         $app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG);
      }
   }
@@ -289,6 +295,51 @@
         $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 '.$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'])) {
         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);
      }
      //* If the client of the site has been changed, we have a change of the document root
      if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
@@ -323,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);
@@ -511,23 +568,6 @@
         exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
      }  // end copy error docs
      // Create group and user, if not exist
      $app->uses('system');
      $groupname = escapeshellcmd($data['new']['system_group']);
      if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
         exec('groupadd '.$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");
         $app->log('Adding the user: '.$username,LOGLEVEL_DEBUG);
      }
      // Set the quota for the user
      if($username != '' && $app->system->is_user($username)) {
         if($data['new']['hd_quota'] > 0) {
@@ -542,74 +582,94 @@
      if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
         // Chown and chmod the directories below the document root
         $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
         $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/web');
         // The document root itself has to be owned by root in normal level and by the web owner in security level 20
         if($web_config['security_level'] == 20) {
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/web');
         } else {
            $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/web');
         }
      }
      //* If the security level is set to high
      if($web_config['security_level'] == 20) {
      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']));
         $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']).'/*');
         $this->_exec('chmod 710 '.escapeshellcmd($data['new']['document_root'].'/web'));
            $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']));
            $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']).'/*');
            $this->_exec('chmod 710 '.escapeshellcmd($data['new']['document_root'].'/web'));
         // make tmp directory writable for Apache and the website users
         $this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
            // make tmp directory writable for Apache and the website users
            $this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
         
         // Set Log symlink to 755 to make the logs accessible by the FTP user
         $this->_exec("chmod 755 ".escapeshellcmd($data["new"]["document_root"])."/log");
            // Set Log symlink to 755 to make the logs accessible by the FTP user
            $this->_exec("chmod 755 ".escapeshellcmd($data["new"]["document_root"])."/log");
            if($web_config['add_web_users_to_sshusers_group'] == 'y') {
               $command = 'usermod';
               $command .= ' --groups sshusers';
               $command .= ' '.escapeshellcmd($data['new']['system_user']);
               $this->_exec($command);
            }
         $command = 'usermod';
         $command .= ' --groups sshusers';
         $command .= ' '.escapeshellcmd($data['new']['system_user']);
         $this->_exec($command);
            //* if we have a chrooted Apache environment
            if($apache_chrooted) {
               $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
         //* if we have a chrooted Apache environment
         if($apache_chrooted) {
            $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
               //* add the apache user to the client group in the chroot environment
               $tmp_groupfile = $app->system->server_conf['group_datei'];
               $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
               $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
               $app->system->server_conf['group_datei'] = $tmp_groupfile;
               unset($tmp_groupfile);
            }
            //* add the apache user to the client group in the chroot environment
            $tmp_groupfile = $app->system->server_conf['group_datei'];
            $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
            //* add the Apache user to the client group
            $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
            $app->system->server_conf['group_datei'] = $tmp_groupfile;
            unset($tmp_groupfile);
         }
            //* 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'));
         //* add the Apache user to the client group
         $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
            /*
            * Workaround for jailkit: If jailkit is enabled for the site, the
            * website root has to be owned by the root user and we have to chmod it to 755 then
            */
         $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
            //* Check if there is a jailkit user or cronjob for this site
            $tmp = $app->db->queryOneRecord('SELECT count(shell_user_id) as number FROM shell_user WHERE parent_domain_id = '.$data['new']['domain_id']." AND chroot = 'jailkit'");
            $tmp2 = $app->db->queryOneRecord('SELECT count(id) as number FROM cron WHERE parent_domain_id = '.$data['new']['domain_id']." AND `type` = 'chrooted'");
            if($tmp['number'] > 0 || $tmp2['number'] > 0) {
               $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root']));
               $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
            }
            unset($tmp);
         /*
         * Workaround for jailkit: If jailkit is enabled for the site, the
         * website root has to be owned by the root user and we have to chmod it to 755 then
         */
            // If the security Level is set to medium
         } else {
         //* Check if there is a jailkit user for this site
         $tmp = $app->db->queryOneRecord('SELECT count(shell_user_id) as number FROM shell_user WHERE parent_domain_id = '.$data['new']['domain_id']." AND chroot = 'jailkit'");
         if($tmp['number'] > 0) {
            $this->_exec('chmod 755 '.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'));
         }
         unset($tmp);
         // If the security Level is set to medium
      } 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']));
         // make temp directory writable for Apache and the website users
         $this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
      }
      // Change the ownership of the error log to the owner of the website
@@ -617,9 +677,15 @@
      $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
      //* Write the custom php.ini file, if custom_php_ini filed is not empty
      //* Write the custom php.ini file, if custom_php_ini fieled is not empty
      $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
      if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf');
      //* add open_basedir restriction to custom php.ini content, required for suphp only
      if(!stristr($data['new']['custom_php_ini'],'open_basedir') && $data['new']['php'] == 'suphp') {
         $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n";
      }
      //* Create custom php.ini
      if(trim($data['new']['custom_php_ini']) != '') {
         $has_custom_php_ini = true;
         if(!is_dir($custom_php_ini_dir)) mkdir($custom_php_ini_dir);
@@ -636,7 +702,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;
@@ -651,6 +717,7 @@
      $tpl->newTemplate('vhost.conf.master');
      $vhost_data = $data['new'];
      //unset($vhost_data['ip_address']);
      $vhost_data['web_document_root'] = $data['new']['document_root'].'/web';
      $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/web';
      $vhost_data['web_basedir'] = $web_config['website_basedir'];
@@ -660,6 +727,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';
@@ -668,6 +740,7 @@
      $crt_file = $ssl_dir.'/'.$domain.'.crt';
      $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
      /*
      if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
         $vhost_data['ssl_enabled'] = 1;
         $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
@@ -675,6 +748,7 @@
         $vhost_data['ssl_enabled'] = 0;
         $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
      }
      */
      if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
@@ -699,7 +773,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);
@@ -726,7 +800,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);
@@ -765,7 +839,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);
@@ -792,7 +866,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);
@@ -824,12 +898,13 @@
         $tpl->setVar('alias','');
      }
      if(count($rewrite_rules) > 0) {
      if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0) {
         $tpl->setVar('rewrite_enabled',1);
      } else {
         $tpl->setVar('rewrite_enabled',0);
      }
      $tpl->setLoop('redirects',$rewrite_rules);
      //$tpl->setLoop('redirects',$rewrite_rules);
      /**
       * install fast-cgi starter script and add script aliasd config
@@ -951,6 +1026,49 @@
      //* Make a backup copy of vhost file
      if(file_exists($vhost_file)) copy($vhost_file,$vhost_file.'~');
      
      //* create empty vhost array
      $vhosts = array();
      //* Add vhost for ipv4 IP
      if(count($rewrite_rules) > 0){
         $vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
      } else {
         $vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
      }
      //* Add vhost for ipv4 IP with SSL
      if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
         if(count($rewrite_rules) > 0){
            $vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
         } else {
            $vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
         }
         $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
      }
      //* Add vhost for IPv6 IP
      if($data['new']['ipv6_address'] != '') {
         if(count($rewrite_rules) > 0){
            $vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
         } else {
            $vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
         }
         //* Add vhost for ipv6 IP with SSL
         if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
            if(count($rewrite_rules) > 0){
               $vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
            } else {
               $vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
            }
            $app->log('Enable SSL for IPv6: '.$domain,LOGLEVEL_DEBUG);
         }
      }
      //* Set the vhost loop
      $tpl->setLoop('vhosts',$vhosts);
      //* Write vhost file
      file_put_contents($vhost_file,$tpl->grab());
      $app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
@@ -1003,6 +1121,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);
@@ -1047,7 +1170,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 {
@@ -1096,11 +1225,24 @@
      } else {
         //* This is a website
         // Deleting the vhost file, symlink and the data directory
         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
         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');
         $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_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
         if(is_link($vhost_symlink)){
            unlink($vhost_symlink);
            $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
         }
         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
         if(is_link($vhost_symlink)){
            unlink($vhost_symlink);
            $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
         }
         unlink($vhost_file);
         $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
@@ -1163,6 +1305,13 @@
         //* Remove the awstats configuration file
         if($data['old']['stats_type'] == 'awstats') {
            $this->awstats_delete($data,$web_config);
         }
         if($apache_chrooted) {
            $app->services->restartServiceDelayed('httpd','restart');
         } else {
            // request a httpd reload when all records have been processed
            $app->services->restartServiceDelayed('httpd','reload');
         }
      }
@@ -1238,7 +1387,7 @@
      if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
      if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
      $folder_path = escapeshellcmd($website['document_root'].'/web/'.$folder['path']);
      if(substr($folder_path,-1 != '/')) $folder_path .= '/';
      if(substr($folder_path,-1) != '/') $folder_path .= '/';
      
      //* Check if the resulting path is inside the docroot
      if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) {
@@ -1247,16 +1396,35 @@
      }
      
      //* 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);
         $app->log('Created file'.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
         chown($folder_path.'.htpasswd',$website['system_user']);
         chgrp($folder_path.'.htpasswd',$website['system_group']);
         $app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
      }
      
      if($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') {
      /*
      $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
      $htpasswd_content = '';
      if(is_array($auth_users) && !empty($auth_users)){
         foreach($auth_users as $auth_user){
            $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
         }
      }
      $htpasswd_content = trim($htpasswd_content);
      @file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
      $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
      */
      if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
         $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
         $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
      }
@@ -1272,13 +1440,16 @@
         }
      }
      
      //* Create the .htaccess file
      if(!is_file($folder_path.'.htaccess')) {
      //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);
         $app->log('Created file'.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
      }
         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);
      //}
      
   }
   
@@ -1288,7 +1459,7 @@
      
      $folder_id = $data['old']['web_folder_id'];
      
      $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
      $folder = $data['old'];
      $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
      
      if(!is_array($folder) or !is_array($website)) {
@@ -1297,8 +1468,10 @@
      }
      
      //* Get the folder path.
      if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
      if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
      $folder_path = realpath($website['document_root'].'/web/'.$folder['path']);
      if(substr($folder_path,-1 != '/')) $folder_path .= '/';
      if(substr($folder_path,-1) != '/') $folder_path .= '/';
      
      //* Check if the resulting path is inside the docroot
      if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
@@ -1309,13 +1482,13 @@
      //* Remove .htpasswd file
      if(is_file($folder_path.'.htpasswd')) {
         unlink($folder_path.'.htpasswd');
         $app->log('Removed file'.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
         $app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
      }
      
      //* Remove .htaccess file
      if(is_file($folder_path.'.htaccess')) {
         unlink($folder_path.'.htaccess');
         $app->log('Removed file'.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
         $app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
      }
   }
   
@@ -1331,11 +1504,15 @@
      }
      
      //* Get the folder path.
      if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1);
      if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1);
      $old_folder_path = realpath($website['document_root'].'/web/'.$data['old']['path']);
      if(substr($old_folder_path,-1 != '/')) $old_folder_path .= '/';
      if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/';
         
      if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1);
      if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1);
      $new_folder_path = escapeshellcmd($website['document_root'].'/web/'.$data['new']['path']);
      if(substr($new_folder_path,-1 != '/')) $new_folder_path .= '/';
      if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/';
      
      //* Check if the resulting path is inside the docroot
      if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) {
@@ -1366,29 +1543,31 @@
         //* move .htpasswd file
         if(is_file($old_folder_path.'.htpasswd')) {
            rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd');
            $app->log('Moved file'.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
            $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
         }
         
         //* move .htpasswd file
         //* delete old .htaccess file
         if(is_file($old_folder_path.'.htaccess')) {
            rename($old_folder_path.'.htaccess',$new_folder_path.'.htaccess');
            $app->log('Moved file'.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
            unlink($old_folder_path.'.htaccess');
            $app->log('Deleted file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
         }
      
      }
      
      //* Create the .htaccess file
      if($data['new']['active'] == 'y' && !is_file($new_folder_path.'.htaccess')) {
         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user";
      if($data['new']['active'] == 'y') {
         $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
      if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
         unlink($new_folder_path.'.htaccess');
         $app->log('Removed file'.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
         $app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
      }
      
      
@@ -1420,6 +1599,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')) {
@@ -1428,13 +1608,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));
         }
         /*
@@ -1447,19 +1639,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'], '');
         }
         /*
@@ -1611,6 +1803,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";
@@ -1655,6 +1848,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');
@@ -1669,6 +1863,9 @@
         file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',$content);
         $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',LOGLEVEL_DEBUG);
      }
      if(is_file($data['new']['document_root']."/web/stats/index.html")) unlink($data['new']['document_root']."/web/stats/index.html");
      copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$data['new']['document_root']."/web/stats/index.php");
   }
   
   //* Delete the awstats configuration file