From ac933eda98110a7b12e488f47ce493c56f1e04de Mon Sep 17 00:00:00 2001
From: vogelor <vogelor@ispconfig3>
Date: Tue, 8 Jun 2010 18:51:14 +0000
Subject: [PATCH] The server-side of the webdav - support

---
 docs/INSTALL_DEBIAN_5.0_courier_mydns.txt     |   4 +
 docs/INSTALL_DEBIAN_5.0_dovecot_bind.txt      |   4 +
 docs/INSTALL_DEBIAN_5.0_multiserver.txt       |   5 +
 docs/INSTALL_DEBIAN_6.0_courier_mydns.txt     |   4 +
 .../web/sites/form/webdav_user.tform.php      |   3 +-
 server/conf/vhost.conf.master                 |  14 +
 server/mods-available/web_module.inc.php      |  11 +-
 .../plugins-available/apache2_plugin.inc.php  | 733 +++++++++++-------
 8 files changed, 512 insertions(+), 266 deletions(-)

diff --git a/docs/INSTALL_DEBIAN_5.0_courier_mydns.txt b/docs/INSTALL_DEBIAN_5.0_courier_mydns.txt
index ef54f044cd..c3dae3bb9b 100644
--- a/docs/INSTALL_DEBIAN_5.0_courier_mydns.txt
+++ b/docs/INSTALL_DEBIAN_5.0_courier_mydns.txt
@@ -127,6 +127,10 @@ apt-get -y install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apac
 
 a2enmod suexec rewrite ssl actions include
 
+# If you want to use webdav then run the following to enable the Apache webdav modules:
+
+a2enmod dav_fs a2enmod dav auth_digest
+
 # restart apache before continuing
 
 /etc/init.d/apache2 restart
diff --git a/docs/INSTALL_DEBIAN_5.0_dovecot_bind.txt b/docs/INSTALL_DEBIAN_5.0_dovecot_bind.txt
index 8a8ccf6fa2..21ec3a0579 100644
--- a/docs/INSTALL_DEBIAN_5.0_dovecot_bind.txt
+++ b/docs/INSTALL_DEBIAN_5.0_dovecot_bind.txt
@@ -95,6 +95,10 @@ apt-get -y install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apac
 
 a2enmod suexec rewrite ssl actions include
 
+# If you want webdav then run the following to enable the Apache webdav modules:
+
+a2enmod dav_fs a2enmod dav auth_digest
+
 # restart apache before continuing
 
 /etc/init.d/apache2 restart
diff --git a/docs/INSTALL_DEBIAN_5.0_multiserver.txt b/docs/INSTALL_DEBIAN_5.0_multiserver.txt
index c6541e762c..ff1ecf399f 100644
--- a/docs/INSTALL_DEBIAN_5.0_multiserver.txt
+++ b/docs/INSTALL_DEBIAN_5.0_multiserver.txt
@@ -10,6 +10,11 @@ apt-get install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apache2
 
 a2enmod suexec rewrite ssl actions include
 
+# If you want webdav then run the following to enable the Apache webdav modules:
+
+a2enmod dav_fs a2enmod dav auth_digest
+
+
 apt-get install pure-ftpd-common pure-ftpd-mysql quota quotatool
 
 vi /etc/default/pure-ftpd-common
diff --git a/docs/INSTALL_DEBIAN_6.0_courier_mydns.txt b/docs/INSTALL_DEBIAN_6.0_courier_mydns.txt
index 63d7182256..258b50f241 100644
--- a/docs/INSTALL_DEBIAN_6.0_courier_mydns.txt
+++ b/docs/INSTALL_DEBIAN_6.0_courier_mydns.txt
@@ -122,6 +122,10 @@ apt-get install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apache2
 
 a2enmod suexec rewrite ssl actions include
 
+# If you want webdav then run the following to enable the Apache webdav modules:
+
+a2enmod dav_fs a2enmod dav auth_digest
+
 # restart apache before continuing
 
 /etc/init.d/apache2 restart
diff --git a/interface/web/sites/form/webdav_user.tform.php b/interface/web/sites/form/webdav_user.tform.php
index 35132feafc..92b00d648b 100644
--- a/interface/web/sites/form/webdav_user.tform.php
+++ b/interface/web/sites/form/webdav_user.tform.php
@@ -96,8 +96,7 @@ $form["tabs"]['webdav'] = array (
 		),
 		'password' => array (
 			'datatype'	=> 'VARCHAR',
-			'formtype'	=> 'PASSWORD',
-			'encryption' => 'CRYPT',
+			'formtype'	=> 'TEXT',
 			'default'	=> '',
 			'value'		=> '',
 			'width'		=> '30',
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index 4ca8161633..35520784ce 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -162,6 +162,13 @@
       AssignUserId <tmpl_var name='system_user'> <tmpl_var name='system_group'>
     </IfModule>
 
+    <IfModule dav>
+      # DO NOT REMOVE THE COMMENTS!
+      # IF YOU REMOVE THEM, WEBDAV WILL NOT WORK ANYMORE!
+      # WEBDAV BEGIN
+      # WEBDAV END
+    </IfModule>
+
 <tmpl_var name='apache_directives'>
 </VirtualHost>
 
@@ -339,6 +346,13 @@
       AssignUserId <tmpl_var name='system_user'> <tmpl_var name='system_group'>
     </IfModule>
 
+    <IfModule dav>
+      # DO NOT REMOVE THE COMMENTS!
+      # IF YOU REMOVE THEM, WEBDAV WILL NOT WORK ANYMORE!
+      # WEBDAV BEGIN
+      # WEBDAV END
+    </IfModule>
+
 <tmpl_var name='apache_directives'>
 </VirtualHost>
 </IfModule>
diff --git a/server/mods-available/web_module.inc.php b/server/mods-available/web_module.inc.php
index 1e7bde7f4b..eeae0920e2 100644
--- a/server/mods-available/web_module.inc.php
+++ b/server/mods-available/web_module.inc.php
@@ -40,7 +40,10 @@ class web_module {
 									'ftp_user_delete',
 									'shell_user_insert',
 									'shell_user_update',
-									'shell_user_delete');
+									'shell_user_delete',
+									'webdav_user_insert',
+									'webdav_user_update',
+									'webdav_user_delete');
 	
 	//* This function is called during ispconfig installation to determine
 	//  if a symlink shall be created for this plugin.
@@ -82,6 +85,7 @@ class web_module {
 		$app->modules->registerTableHook('web_domain','web_module','process');
         $app->modules->registerTableHook('ftp_user','web_module','process');
         $app->modules->registerTableHook('shell_user','web_module','process');
+		$app->modules->registerTableHook('webdav_user','web_module','process');
 		
 		// Register service
 		$app->services->registerService('httpd','web_module','restartHttpd');
@@ -112,6 +116,11 @@ class web_module {
 				if($action == 'u') $app->plugins->raiseEvent('shell_user_update',$data);
 				if($action == 'd') $app->plugins->raiseEvent('shell_user_delete',$data);
 			break;
+			case 'webdav_user':
+				if($action == 'i') $app->plugins->raiseEvent('webdav_user_insert',$data);
+				if($action == 'u') $app->plugins->raiseEvent('webdav_user_update',$data);
+				if($action == 'd') $app->plugins->raiseEvent('webdav_user_delete',$data);
+			break;
 		} // end switch
 	} // end function
 	
diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index 4445db3598..49b8109dfe 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -29,80 +29,80 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 class apache2_plugin {
-	
+
 	var $plugin_name = 'apache2_plugin';
 	var $class_name = 'apache2_plugin';
-	
+
 	// private variables
 	var $action = '';
-	
+
 	//* This function is called during ispconfig installation to determine
 	//  if a symlink shall be created for this plugin.
 	function onInstall() {
 		global $conf;
-		
+
 		if($conf['services']['web'] == true) {
 			return true;
 		} else {
 			return false;
 		}
-		
+
 	}
-	
-		
+
+
 	/*
 	 	This function is called when the plugin is loaded
 	*/
-	
+
 	function onLoad() {
 		global $app;
-		
+
 		/*
 		Register for the events
 		*/
-		
-		
-		
 		$app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl');
 		$app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl');
 		$app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl');
-		
+
 		$app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert');
 		$app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update');
 		$app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete');
-		
+
 		$app->plugins->registerEvent('server_ip_insert',$this->plugin_name,'server_ip');
 		$app->plugins->registerEvent('server_ip_update',$this->plugin_name,'server_ip');
 		$app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip');
-		
+
+		$app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav');
+		$app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav');
+		$app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav');
 	}
-	
+
 	// Handle the creation of SSL certificates
 	function ssl($event_name,$data) {
 		global $app, $conf;
-		
+
 		if(!is_dir($data["new"]["document_root"]."/ssl")) exec("mkdir -p ".$data["new"]["document_root"]."/ssl");
 		$ssl_dir = $data["new"]["document_root"]."/ssl";
 		$domain = $data["new"]["ssl_domain"];
 		$key_file = $ssl_dir.'/'.$domain.".key.org";
-  		$key_file2 = $ssl_dir.'/'.$domain.".key";
-  		$csr_file = $ssl_dir.'/'.$domain.".csr";
-  		$crt_file = $ssl_dir.'/'.$domain.".crt";
-		
+		$key_file2 = $ssl_dir.'/'.$domain.".key";
+		$csr_file = $ssl_dir.'/'.$domain.".csr";
+		$crt_file = $ssl_dir.'/'.$domain.".crt";
+
 		//* Create a SSL Certificate
 		if($data["new"]["ssl_action"] == 'create') {
 			$rand_file = $ssl_dir."/random_file";
-    		$rand_data = md5(uniqid(microtime(),1));
-    		for($i=0; $i<1000; $i++){
-    			$rand_data .= md5(uniqid(microtime(),1));
-    			$rand_data .= md5(uniqid(microtime(),1));
-    			$rand_data .= md5(uniqid(microtime(),1));
-    			$rand_data .= md5(uniqid(microtime(),1));
-    		}
-    		file_put_contents($rand_file, $rand_data);
-
-    		$ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15);
-			
+			$rand_data = md5(uniqid(microtime(),1));
+			for($i=0; $i<1000; $i++) {
+				$rand_data .= md5(uniqid(microtime(),1));
+				$rand_data .= md5(uniqid(microtime(),1));
+				$rand_data .= md5(uniqid(microtime(),1));
+				$rand_data .= md5(uniqid(microtime(),1));
+			}
+			file_put_contents($rand_file, $rand_data);
+
+			$ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15);
+
 			$ssl_cnf = "        RANDFILE               = $rand_file
 
         [ req ]
@@ -124,10 +124,10 @@ class apache2_plugin {
 
         [ req_attributes ]
         challengePassword              = A challenge password";
-			
+
 			$ssl_cnf_file = $ssl_dir."/openssl.conf";
 			file_put_contents($ssl_cnf_file,$ssl_cnf);
-			
+
 			$rand_file = escapeshellcmd($rand_file);
 			$key_file = escapeshellcmd($key_file);
 			$key_file2 = escapeshellcmd($key_file2);
@@ -136,30 +136,30 @@ class apache2_plugin {
 			$config_file = escapeshellcmd($ssl_cnf_file);
 			$crt_file = escapeshellcmd($crt_file);
 
-        	if(is_file($ssl_cnf_file)){
-          		exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048 && openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file && 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 && openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2");
+			if(is_file($ssl_cnf_file)) {
+				exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048 && openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file && 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 && openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2");
 				$app->log("Creating SSL Cert for: $domain",LOGLEVEL_DEBUG);
-        	}
+			}
 
-    		exec("chmod 400 $key_file2");
-    		@unlink($config_file);
-    		@unlink($rand_file);
-    		$ssl_request = $app->db->quote(file_get_contents($csr_file));
-    		$ssl_cert = $app->db->quote(file_get_contents($crt_file));
+			exec("chmod 400 $key_file2");
+			@unlink($config_file);
+			@unlink($rand_file);
+			$ssl_request = $app->db->quote(file_get_contents($csr_file));
+			$ssl_cert = $app->db->quote(file_get_contents($crt_file));
 			/* Update the DB of the (local) Server */
-    		$app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data["new"]["domain"]."'");
+			$app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data["new"]["domain"]."'");
 			/* Update also the master-DB of the Server-Farm */
-    		$app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data["new"]["domain"]."'");
+			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data["new"]["domain"]."'");
 		}
-		
+
 		//* Save a SSL certificate to disk
 		if($data["new"]["ssl_action"] == 'save') {
 			$ssl_dir = $data["new"]["document_root"]."/ssl";
 			$domain = $data["new"]["ssl_domain"];
-  			$csr_file = $ssl_dir.'/'.$domain.".csr";
-  			$crt_file = $ssl_dir.'/'.$domain.".crt";
+			$csr_file = $ssl_dir.'/'.$domain.".csr";
+			$crt_file = $ssl_dir.'/'.$domain.".crt";
 			$bundle_file = $ssl_dir.'/'.$domain.".bundle";
 			file_put_contents($csr_file,$data["new"]["ssl_request"]);
 			file_put_contents($crt_file,$data["new"]["ssl_cert"]);
@@ -170,51 +170,51 @@ class apache2_plugin {
 			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->log("Saving SSL Cert for: $domain",LOGLEVEL_DEBUG);
 		}
-		
+
 		//* Delete a SSL certificate
 		if($data["new"]["ssl_action"] == 'del') {
 			$ssl_dir = $data["new"]["document_root"]."/ssl";
 			$domain = $data["new"]["ssl_domain"];
-  			$csr_file = $ssl_dir.'/'.$domain.".csr";
-  			$crt_file = $ssl_dir.'/'.$domain.".crt";
+			$csr_file = $ssl_dir.'/'.$domain.".csr";
+			$crt_file = $ssl_dir.'/'.$domain.".crt";
 			$bundle_file = $ssl_dir.'/'.$domain.".bundle";
 			unlink($csr_file);
 			unlink($crt_file);
 			unlink($bundle_file);
 			/* Update the DB of the (local) Server */
-    		$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data["new"]["domain"]."'");
+			$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data["new"]["domain"]."'");
 			/* Update also the master-DB of the Server-Farm */
-    		$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data["new"]["domain"]."'");
+			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data["new"]["domain"]."'");
 			$app->log("Deleting SSL Cert for: $domain",LOGLEVEL_DEBUG);
 		}
-		
-		
+
+
 	}
-	
-	
+
+
 	function insert($event_name,$data) {
 		global $app, $conf;
-		
+
 		$this->action = 'insert';
 		// just run the update function
 		$this->update($event_name,$data);
-		
-		
+
+
 	}
-	
-	
+
+
 	function update($event_name,$data) {
 		global $app, $conf;
-		
+
 		if($this->action != 'insert') $this->action = 'update';
-		
+
 		if($data["new"]["type"] != "vhost" && $data["new"]["parent_domain_id"] > 0) {
-			
+
 			$old_parent_domain_id = intval($data["old"]["parent_domain_id"]);
 			$new_parent_domain_id = intval($data["new"]["parent_domain_id"]);
-			
+
 			// If the parent_domain_id has been chenged, we will have to update the old site as well.
 			if($this->action == 'update' && $data["new"]["parent_domain_id"] != $data["old"]["parent_domain_id"]) {
 				$tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$old_parent_domain_id." AND active = 'y'");
@@ -223,18 +223,18 @@ class apache2_plugin {
 				$this->action = 'update';
 				$this->update($event_name,$data);
 			}
-			
+
 			// This is not a vhost, so we need to update the parent record instead.
 			$tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$new_parent_domain_id." AND active = 'y'");
 			$data["new"] = $tmp;
 			$data["old"] = $tmp;
 			$this->action = 'update';
 		}
-		
+
 		// load the server configuration options
 		$app->uses("getconf");
 		$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
-		
+
 		//* Check if this is a chrooted setup
 		if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
 			$apache_chrooted = true;
@@ -242,7 +242,7 @@ class apache2_plugin {
 		} else {
 			$apache_chrooted = false;
 		}
-		
+
 		if($data["new"]["document_root"] == '') {
 			$app->log("document_root not set",LOGLEVEL_WARN);
 			return 0;
@@ -251,15 +251,15 @@ class apache2_plugin {
 			$app->log("Websites can not be owned by the root user or group.",LOGLEVEL_WARN);
 			return 0;
 		}
-		
+
 		//* 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"]) {
-			
+
 			//* Get the old client ID
 			$old_client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"]));
 			$old_client_id = intval($old_client["client_id"]);
 			unset($old_client);
-			
+
 			//* Remove the old symlinks
 			$tmp_symlinks_array = explode(':',$web_config["website_symlinks"]);
 			if(is_array($tmp_symlinks_array)) {
@@ -275,38 +275,38 @@ class apache2_plugin {
 					}
 				}
 			}
-			
+
 			//* Move the site data
 			$tmp_docroot = explode('/',$data["new"]["document_root"]);
 			unset($tmp_docroot[count($tmp_docroot)-1]);
 			$new_dir = implode('/',$tmp_docroot);
-			
+
 			$tmp_docroot = explode('/',$data["old"]["document_root"]);
 			unset($tmp_docroot[count($tmp_docroot)-1]);
 			$old_dir = implode('/',$tmp_docroot);
-			
+
 			exec('rm -rf '.$data["new"]["document_root"]);
 			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);
-			
+
 			//* Change the owner of the website files to the new website owner
 			exec('chown --recursive --from='.escapeshellcmd($data["old"]["system_user"]).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data["new"]["system_user"]).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir);
-			
+
 			//* Change the home directory and group of the website user
 			$command = 'usermod';
 			$command .= ' --home '.escapeshellcmd($data["new"]["document_root"]);
 			$command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
 			$command .= ' '.escapeshellcmd($data["new"]["system_user"]);
 			exec($command);
-			
+
 			if($apache_chrooted) $this->_exec("chroot ".escapeshellcmd($web_config['website_basedir'])." ".$command);
-			
-			
+
+
 		}
-		
+
 		//print_r($data);
-		
+
 		// Check if the directories are there and create them if nescessary.
 		if(!is_dir($data["new"]["document_root"]."/web")) exec("mkdir -p ".$data["new"]["document_root"]."/web");
 		if(!is_dir($data["new"]["document_root"]."/web/error") and $data["new"]["errordocs"]) exec("mkdir -p ".$data["new"]["document_root"]."/web/error");
@@ -314,13 +314,13 @@ class apache2_plugin {
 		if(!is_dir($data["new"]["document_root"]."/ssl")) exec("mkdir -p ".$data["new"]["document_root"]."/ssl");
 		if(!is_dir($data["new"]["document_root"]."/cgi-bin")) exec("mkdir -p ".$data["new"]["document_root"]."/cgi-bin");
 		if(!is_dir($data["new"]["document_root"]."/tmp")) exec("mkdir -p ".$data["new"]["document_root"]."/tmp");
-		
+
 		// Remove the symlink for the site, if site is renamed
 		if($this->action == 'update' && $data["old"]["domain"] != '' && $data["new"]["domain"] != $data["old"]["domain"]) {
 			if(is_dir('/var/log/ispconfig/httpd/'.$data["old"]["domain"])) exec('rm -rf /var/log/ispconfig/httpd/'.$data["old"]["domain"]);
 			if(is_link($data["old"]["document_root"]."/log")) unlink($data["old"]["document_root"]."/log");
 		}
-		
+
 		// Create the symlink for the logfiles
 		if(!is_dir('/var/log/ispconfig/httpd/'.$data["new"]["domain"])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data["new"]["domain"]);
 		if(!is_link($data["new"]["document_root"]."/log")) {
@@ -342,12 +342,12 @@ class apache2_plugin {
 			$app->log("Creating Symlink: ln -s ".$data["new"]["document_root"]."/log /var/log/ispconfig/httpd/".$data["new"]["domain"],LOGLEVEL_DEBUG);
 		}
 		*/
-	
+
 		// Get the client ID
 		$client = $app->dbmaster->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["new"]["sys_groupid"]));
 		$client_id = intval($client["client_id"]);
 		unset($client);
-		
+
 		// Remove old symlinks, if site is renamed
 		if($this->action == 'update' && $data["old"]["domain"] != '' && $data["new"]["domain"] != $data["old"]["domain"]) {
 			$tmp_symlinks_array = explode(':',$web_config["website_symlinks"]);
@@ -365,7 +365,7 @@ class apache2_plugin {
 				}
 			}
 		}
-		
+
 		// Create the symlinks for the sites
 		$tmp_symlinks_array = explode(':',$web_config["website_symlinks"]);
 		if(is_array($tmp_symlinks_array)) {
@@ -385,17 +385,17 @@ class apache2_plugin {
 				}
 			}
 		}
-		
-		
+
+
 		if($this->action == 'insert' && $data["new"]["type"] == 'vhost') {
 			// Copy the error pages
-			if($data["new"]["errordocs"]){
+			if($data["new"]["errordocs"]) {
 				$error_page_path = escapeshellcmd($data["new"]["document_root"])."/web/error/";
-				if (file_exists("/usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2))){
+				if (file_exists("/usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2))) {
 					exec("cp /usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2)."/* ".$error_page_path);
 				}
 				else {
-					if (file_exists("/usr/local/ispconfig/server/conf-custom/error/400.html")){
+					if (file_exists("/usr/local/ispconfig/server/conf-custom/error/400.html")) {
 						exec("cp /usr/local/ispconfig/server/conf-custom/error/*.html ".$error_page_path);
 					}
 					else {
@@ -406,11 +406,11 @@ class apache2_plugin {
 			}
 
 			// copy the standard index page
-			if (file_exists("/usr/local/ispconfig/server/conf-custom/index/standard_index.html_".substr(escapeshellcmd($conf["language"]),0,2))){
+			if (file_exists("/usr/local/ispconfig/server/conf-custom/index/standard_index.html_".substr(escapeshellcmd($conf["language"]),0,2))) {
 				exec("cp /usr/local/ispconfig/server/conf-custom/index/standard_index.html_".substr(escapeshellcmd($conf["language"]),0,2)." ".escapeshellcmd($data["new"]["document_root"])."/web/index.html");
 			}
 			else {
-				if (file_exists("/usr/local/ispconfig/server/conf-custom/index/standard_index.html")){
+				if (file_exists("/usr/local/ispconfig/server/conf-custom/index/standard_index.html")) {
 					exec("cp /usr/local/ispconfig/server/conf-custom/index/standard_index.html ".escapeshellcmd($data["new"]["document_root"])."/web/index.html");
 				}
 				else {
@@ -421,16 +421,16 @@ class apache2_plugin {
 				}
 			}
 			exec("chmod -R a+r ".escapeshellcmd($data["new"]["document_root"])."/web/");
-		
-		//** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
+
+			//** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
 		} elseif ($this->action == 'update' && $data["new"]["type"] == 'vhost' && $data["old"]["errordocs"] == 0 && $data["new"]["errordocs"] == 1) {
-			
+
 			$error_page_path = escapeshellcmd($data["new"]["document_root"])."/web/error/";
-			if (file_exists("/usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2))){
+			if (file_exists("/usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2))) {
 				exec("cp /usr/local/ispconfig/server/conf-custom/error/".substr(escapeshellcmd($conf["language"]),0,2)."/* ".$error_page_path);
 			}
 			else {
-				if (file_exists("/usr/local/ispconfig/server/conf-custom/error/400.html")){
+				if (file_exists("/usr/local/ispconfig/server/conf-custom/error/400.html")) {
 					exec("cp /usr/local/ispconfig/server/conf-custom/error/*.html ".$error_page_path);
 				}
 				else {
@@ -439,36 +439,36 @@ class apache2_plugin {
 			}
 			exec("chmod -R a+r ".$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){
-    			$blocks_soft = $data["new"]["hd_quota"] * 1024;
-    			$blocks_hard = $blocks_soft + 1024;
-  			} else {
-    			$blocks_soft = $blocks_hard = 0;
-  			}
+			if($data["new"]["hd_quota"] > 0) {
+				$blocks_soft = $data["new"]["hd_quota"] * 1024;
+				$blocks_hard = $blocks_soft + 1024;
+			} else {
+				$blocks_soft = $blocks_hard = 0;
+			}
 			exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
 			exec("setquota -T -u $username 604800 604800 -a &> /dev/null");
 		}
-		
+
 		if($this->action == 'insert') {
 			// Chown and chmod the directories below the document root
 			$this->_exec("chown -R $username:$groupname ".escapeshellcmd($data["new"]["document_root"]));
@@ -479,28 +479,28 @@ class apache2_plugin {
 				$this->_exec("chown root:root ".escapeshellcmd($data["new"]["document_root"]));
 			}
 		}
-		
-		
-		
+
+
+
 		//* If the security level is set to high
 		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"));
-			
+
 			// make temp direcory writable for the apache user and the website user
 			$this->_exec("chmod 777 ".escapeshellcmd($data["new"]["document_root"]."/tmp"));
-			
+
 			$command = 'usermod';
 			$command .= ' --groups sshusers';
 			$command .= ' '.escapeshellcmd($data["new"]["system_user"]);
 			$this->_exec($command);
-			
+
 			//* if we have a chrooted apache enviroment
 			if($apache_chrooted) {
 				$this->_exec("chroot ".escapeshellcmd($web_config['website_basedir'])." ".$command);
-				
+
 				//* add the apache user to the client group in the chroot enviroment
 				$tmp_groupfile = $app->system->server_conf["group_datei"];
 				$app->system->server_conf["group_datei"] = $web_config['website_basedir'].'/etc/group';
@@ -508,17 +508,17 @@ class apache2_plugin {
 				$app->system->server_conf["group_datei"] = $tmp_groupfile;
 				unset($tmp_groupfile);
 			}
-			
+
 			//* add the apache user to the client group
 			$app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
-			
+
 			$this->_exec("chown $username:$groupname ".escapeshellcmd($data["new"]["document_root"]));
-			
+
 			/*
 			* 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
 			*/
-			
+
 			//* 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) {
@@ -526,29 +526,29 @@ class apache2_plugin {
 				$this->_exec("chown root:root ".escapeshellcmd($data["new"]["document_root"]."/"));
 			}
 			unset($tmp);
-			
-		// If the security Level is set to medium
+
+			// 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 direcory writable for the apache user and the website user
 			$this->_exec("chmod 777 ".escapeshellcmd($data["new"]["document_root"]."/tmp"));
 		}
-		
+
 		// Change the owner of the error log to the owner of the website
 		if(!@is_file($data["new"]["document_root"]."/log/error.log")) exec('touch '.escapeshellcmd($data["new"]["document_root"])."/log/error.log");
 		$this->_exec("chown $username:$groupname ".escapeshellcmd($data["new"]["document_root"])."/log/error.log");
-		
-		
+
+
 		// Create the vhost config file
 		$app->load('tpl');
-		
+
 		$tpl = new tpl();
 		$tpl->newTemplate("vhost.conf.master");
-		
+
 		$vhost_data = $data["new"];
 		$vhost_data["web_document_root"] = $data["new"]["document_root"]."/web";
 		$vhost_data["web_document_root_www"] = $web_config["website_basedir"]."/".$data["new"]["domain"]."/web";
@@ -557,14 +557,14 @@ class apache2_plugin {
 		$vhost_data["allow_override"] = ($data["new"]["allow_override"] == '')?'All':$data["new"]["allow_override"];
 		$vhost_data["php_open_basedir"] = ($data["new"]["php_open_basedir"] == '')?$data["new"]["document_root"]:$data["new"]["php_open_basedir"];
 		$vhost_data["ssl_domain"] = $data["new"]["ssl_domain"];
-		
+
 		// Check if a SSL cert exists
 		$ssl_dir = $data["new"]["document_root"]."/ssl";
 		$domain = $data["new"]["ssl_domain"];
-  		$key_file = $ssl_dir.'/'.$domain.".key";
-  		$crt_file = $ssl_dir.'/'.$domain.".crt";
+		$key_file = $ssl_dir.'/'.$domain.".key";
+		$crt_file = $ssl_dir.'/'.$domain.".crt";
 		$bundle_file = $ssl_dir.'/'.$domain.".bundle";
-		
+
 		if($data["new"]["ssl"] == 'y' && @is_file($crt_file) && @is_file($key_file)) {
 			$vhost_data["ssl_enabled"] = 1;
 			$app->log("Enable SSL for: $domain",LOGLEVEL_DEBUG);
@@ -572,12 +572,12 @@ class apache2_plugin {
 			$vhost_data["ssl_enabled"] = 0;
 			$app->log("Disable SSL for: $domain",LOGLEVEL_DEBUG);
 		}
-		
+
 		if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
-		
+
 		//$vhost_data["document_root"] = $data["new"]["document_root"]."/web";
 		$tpl->setVar($vhost_data);
-		
+
 		// Rewrite rules
 		$rewrite_rules = array();
 		if($data["new"]["redirect_type"] != '') {
@@ -585,50 +585,50 @@ class apache2_plugin {
 			if($data["new"]["redirect_type"] == 'no' && substr($data["new"]["redirect_path"],0,4) != 'http') {
 				$data["new"]["redirect_path"] = $data["new"]["document_root"]."/web".realpath($data["new"]["redirect_path"]).'/';
 			}
-			
+
 			$rewrite_rules[] = array(	'rewrite_domain' 	=> $data["new"]["domain"],
-										'rewrite_type' 		=> ($data["new"]["redirect_type"] == 'no')?'':'['.$data["new"]["redirect_type"].']',
-										'rewrite_target' 	=> $data["new"]["redirect_path"]);
-            
-            switch($data["new"]["subdomain"]) {
-            case 'www':
-    			$rewrite_rules[] = array(	'rewrite_domain' 	=> 'www.'.$data["new"]["domain"],
-    										'rewrite_type' 		=> ($data["new"]["redirect_type"] == 'no')?'':'['.$data["new"]["redirect_type"].']',
-    										'rewrite_target' 	=> $data["new"]["redirect_path"]);
-                break;
-            case '*':
-                // TODO
-    			//$rewrite_rules[] = array(	'rewrite_domain' 	=> '*'.$alias["domain"],
-    			//							'rewrite_type' 		=> $alias["redirect_type"],
-    			//							'rewrite_target' 	=> $alias["redirect_path"]);
-                break;
-            }
+					'rewrite_type' 		=> ($data["new"]["redirect_type"] == 'no')?'':'['.$data["new"]["redirect_type"].']',
+					'rewrite_target' 	=> $data["new"]["redirect_path"]);
+
+			switch($data["new"]["subdomain"]) {
+				case 'www':
+					$rewrite_rules[] = array(	'rewrite_domain' 	=> 'www.'.$data["new"]["domain"],
+							'rewrite_type' 		=> ($data["new"]["redirect_type"] == 'no')?'':'['.$data["new"]["redirect_type"].']',
+							'rewrite_target' 	=> $data["new"]["redirect_path"]);
+					break;
+				case '*':
+				// TODO
+				//$rewrite_rules[] = array(	'rewrite_domain' 	=> '*'.$alias["domain"],
+				//							'rewrite_type' 		=> $alias["redirect_type"],
+				//							'rewrite_target' 	=> $alias["redirect_path"]);
+					break;
+			}
 		}
-		
+
 		// get alias domains (co-domains and subdomains)
 		$aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ".$data["new"]["domain_id"]." AND active = 'y'");
-        $server_alias = array();
+		$server_alias = array();
 		switch($data["new"]["subdomain"]) {
-        case 'www':
-            $server_alias[] .= 'www.'.$data["new"]["domain"].' ';
-            break;
-        case '*':
-            $server_alias[] .= '*.'.$data["new"]["domain"].' ';    
-            break;
-        }
+			case 'www':
+				$server_alias[] .= 'www.'.$data["new"]["domain"].' ';
+				break;
+			case '*':
+				$server_alias[] .= '*.'.$data["new"]["domain"].' ';
+				break;
+		}
 		if(is_array($aliases)) {
 			foreach($aliases as $alias) {
-                switch($alias["subdomain"]) {
-                case 'www':
-                    $server_alias[] .= 'www.'.$alias["domain"].' '.$alias["domain"].' ';
-                    break;
-                case '*':
-                    $server_alias[] .= '*.'.$alias["domain"].' '.$alias["domain"].' ';    
-                    break;
-                default:
-                    $server_alias[] .= $alias["domain"].' ';            
-                    break;
-                }
+				switch($alias["subdomain"]) {
+					case 'www':
+						$server_alias[] .= 'www.'.$alias["domain"].' '.$alias["domain"].' ';
+						break;
+					case '*':
+						$server_alias[] .= '*.'.$alias["domain"].' '.$alias["domain"].' ';
+						break;
+					default:
+						$server_alias[] .= $alias["domain"].' ';
+						break;
+				}
 				$app->log("Add server alias: $alias[domain]",LOGLEVEL_DEBUG);
 				// Rewriting
 				if($alias["redirect_type"] != '') {
@@ -637,103 +637,101 @@ class apache2_plugin {
 						$data["new"]["redirect_path"] = $data["new"]["document_root"]."/web".realpath($data["new"]["redirect_path"]).'/';
 					}
 					$rewrite_rules[] = array(	'rewrite_domain' 	=> $alias["domain"],
-												'rewrite_type' 		=> ($alias["redirect_type"] == 'no')?'':'['.$alias["redirect_type"].']',
-												'rewrite_target' 	=> $alias["redirect_path"]);
-                    switch($alias["subdomain"]) {
-                    case 'www':
-            			$rewrite_rules[] = array(	'rewrite_domain' 	=> 'www.'.$alias["domain"],
-            										'rewrite_type' 		=> ($alias["redirect_type"] == 'no')?'':'['.$alias["redirect_type"].']',
-            										'rewrite_target' 	=> $alias["redirect_path"]);
-                        break;
-                    case '*':
-                        // TODO
-            			//$rewrite_rules[] = array(	'rewrite_domain' 	=> '*'.$alias["domain"],
-            			//							'rewrite_type' 		=> $alias["redirect_type"],
-            			//							'rewrite_target' 	=> $alias["redirect_path"]);
-                        break;
-                    }
+							'rewrite_type' 		=> ($alias["redirect_type"] == 'no')?'':'['.$alias["redirect_type"].']',
+							'rewrite_target' 	=> $alias["redirect_path"]);
+					switch($alias["subdomain"]) {
+						case 'www':
+							$rewrite_rules[] = array(	'rewrite_domain' 	=> 'www.'.$alias["domain"],
+									'rewrite_type' 		=> ($alias["redirect_type"] == 'no')?'':'['.$alias["redirect_type"].']',
+									'rewrite_target' 	=> $alias["redirect_path"]);
+							break;
+						case '*':
+						// TODO
+						//$rewrite_rules[] = array(	'rewrite_domain' 	=> '*'.$alias["domain"],
+						//							'rewrite_type' 		=> $alias["redirect_type"],
+						//							'rewrite_target' 	=> $alias["redirect_path"]);
+							break;
+					}
 				}
 			}
 		}
-		
+
 		//* If we have some alias records
 		if(count($server_alias) > 0) {
 			$server_alias_str = '';
 			$n = 0;
-			
+
 			// begin a new ServerAlias line after 30 alias domains
 			foreach($server_alias as $tmp_alias) {
 				if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
 				$server_alias_str .= $tmp_alias;
 			}
 			unset($tmp_alias);
-			
+
 			$tpl->setVar('alias',trim($server_alias_str));
 		} else {
 			$tpl->setVar('alias','');
 		}
-		
+
 		if(count($rewrite_rules) > 0) {
 			$tpl->setVar('rewrite_enabled',1);
 		} else {
 			$tpl->setVar('rewrite_enabled',0);
 		}
 		$tpl->setLoop('redirects',$rewrite_rules);
-		
-		/** 
-		 * install fast-cgi starter script and add script aliasd config 
+
+		/**
+		 * install fast-cgi starter script and add script aliasd config
 		 * first we create the script directory if not already created, then copy over the starter script
 		 * settings are copied over from the server ini config for now
 		 * TODO: Create form for fastcgi configs per site.
 		 */
-		
-		if ($data["new"]["php"] == "fast-cgi")
-		{
+
+		if ($data["new"]["php"] == "fast-cgi") {
 			$fastcgi_config = $app->getconf->get_server_config($conf["server_id"], 'fastcgi');
-			
+
 			$fastcgi_starter_path = str_replace("[system_user]",$data["new"]["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))
-			{
+
+			if (!is_dir($fastcgi_starter_path)) {
 				exec("mkdir -p ".escapeshellcmd($fastcgi_starter_path));
 				//exec("chown ".$data["new"]["system_user"].":".$data["new"]["system_group"]." ".escapeshellcmd($fastcgi_starter_path));
-				
-				
+
+
 				$app->log("Creating fastcgi starter script directory: $fastcgi_starter_path",LOGLEVEL_DEBUG);
 			}
-			
+
 			exec("chown -R ".$data["new"]["system_user"].":".$data["new"]["system_group"]." ".escapeshellcmd($fastcgi_starter_path));
-			
+
 			$fcgi_tpl = new tpl();
 			$fcgi_tpl->newTemplate("php-fcgi-starter.master");
-				
+
 			$fcgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config["fastcgi_phpini_path"]));
 			$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"]));
 			$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"];
 			$fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
-				
+
 			$fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config["fastcgi_starter_script"]);
 			file_put_contents($fcgi_starter_script,$fcgi_tpl->grab());
 			unset($fcgi_tpl);
-			
+
 			$app->log("Creating fastcgi starter script: $fcgi_starter_script",LOGLEVEL_DEBUG);
-			
-			
+
+
 			exec("chmod 755 $fcgi_starter_script");
 			exec("chown ".$data["new"]["system_user"].":".$data["new"]["system_group"]." $fcgi_starter_script");
 
 			$tpl->setVar('fastcgi_alias',$fastcgi_config["fastcgi_alias"]);
 			$tpl->setVar('fastcgi_starter_path',$fastcgi_starter_path);
 			$tpl->setVar('fastcgi_starter_script',$fastcgi_config["fastcgi_starter_script"]);
-			
+
 		}
-		
+
 		/**
 		 * install cgi starter script and add script alias to config.
 		 * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
@@ -741,8 +739,7 @@ class apache2_plugin {
 		 * TODO: we have to fetch the data from the server-settings.
 		 */
 
-		if ($data["new"]["php"] == "cgi")
-		{
+		if ($data["new"]["php"] == "cgi") {
 			//$cgi_config = $app->getconf->get_server_config($conf["server_id"], 'cgi');
 
 			$cgi_config["cgi_starter_path"] = $web_config["website_basedir"]."/php-cgi-scripts/[system_user]/";
@@ -752,8 +749,7 @@ class apache2_plugin {
 			$cgi_starter_path = str_replace("[system_user]",$data["new"]["system_user"],$cgi_config["cgi_starter_path"]);
 			$cgi_starter_path = str_replace("[client_id]",$client_id,$cgi_starter_path);
 
-			if (!is_dir($cgi_starter_path))
-			{
+			if (!is_dir($cgi_starter_path)) {
 				exec("mkdir -p ".escapeshellcmd($cgi_starter_path));
 				exec("chown ".$data["new"]["system_user"].":".$data["new"]["system_group"]." ".escapeshellcmd($cgi_starter_path));
 
@@ -765,9 +761,9 @@ class apache2_plugin {
 
 			// This works, because php "rewrites" a symlink to the physical path
 			$php_open_basedir = ($data["new"]["php_open_basedir"] == '')?$data["new"]["document_root"]:$data["new"]["php_open_basedir"];
-			$cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); 
+			$cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
 			$cgi_tpl->setVar('document_root', escapeshellcmd($data["new"]["document_root"]));
-			
+
 			// This will NOT work!
 			//$cgi_tpl->setVar('open_basedir', "/var/www/" . $data["new"]["domain"]);
 			$cgi_tpl->setVar('php_cgi_bin',$cgi_config["cgi_bin"]);
@@ -792,20 +788,25 @@ class apache2_plugin {
 		file_put_contents($vhost_file,$tpl->grab());
 		$app->log("Writing the vhost file: $vhost_file",LOGLEVEL_DEBUG);
 		unset($tpl);
-		
+
+		/*
+		 * maybe we have some webdav - user. If so, add them...
+		*/
+		$this->_patchVhostWebdav($vhost_file, $data["new"]["document_root"] . '/webdav');
+
 		// Set the symlink to enable the vhost
 		$vhost_symlink = escapeshellcmd($web_config["vhost_conf_enabled_dir"].'/'.$data["new"]["domain"].'.vhost');
 		if($data["new"]["active"] == 'y' && !is_link($vhost_symlink)) {
 			symlink($vhost_file,$vhost_symlink);
 			$app->log("Creating the symlink: $vhost_symlink => $vhost_file",LOGLEVEL_DEBUG);
 		}
-		
+
 		// Remove the symlink, if site is inactive
 		if($data["new"]["active"] == 'n' && is_link($vhost_symlink)) {
 			unlink($vhost_symlink);
 			$app->log("Removing symlink: $vhost_symlink => $vhost_file",LOGLEVEL_DEBUG);
 		}
-		
+
 		// remove old symlink and vhost file, if domain name of the site has changed
 		if($this->action == 'update' && $data["old"]["domain"] != '' && $data["new"]["domain"] != $data["old"]["domain"]) {
 			$vhost_symlink = escapeshellcmd($web_config["vhost_conf_enabled_dir"].'/'.$data["old"]["domain"].'.vhost');
@@ -815,7 +816,7 @@ class apache2_plugin {
 			unlink($vhost_file);
 			$app->log("Removing File $vhost_file",LOGLEVEL_DEBUG);
 		}
-		
+
 		//* Create .htaccess and .htpasswd file for website statistics
 		if(!is_file($data["new"]["document_root"].'/web/stats/.htaccess') or $data["old"]["document_root"] != $data["new"]["document_root"]) {
 			if(!is_dir($data["new"]["document_root"].'/web/stats')) mkdir($data["new"]["document_root"].'/web/stats');
@@ -824,7 +825,7 @@ class apache2_plugin {
 			chmod($data["new"]["document_root"].'/web/stats/.htaccess',0755);
 			unset($ht_file);
 		}
-		
+
 		if(!is_file($data["new"]["document_root"].'/.htpasswd_stats') || $data["new"]["stats_password"] != $data["old"]["stats_password"]) {
 			if(trim($data["new"]["stats_password"]) != '') {
 				$htp_file = 'admin:'.trim($data["new"]["stats_password"]);
@@ -833,34 +834,34 @@ class apache2_plugin {
 				unset($htp_file);
 			}
 		}
-		
-		
+
+
 		if($apache_chrooted) {
 			$app->services->restartServiceDelayed('httpd','restart');
 		} else {
 			// request a httpd reload when all records have been processed
 			$app->services->restartServiceDelayed('httpd','reload');
 		}
-		
+
 		//* Unset action to clean it for next processed vhost.
 		$this->action = '';
-		
+
 	}
-	
+
 	function delete($event_name,$data) {
 		global $app, $conf;
-		
+
 		// load the server configuration options
 		$app->uses("getconf");
 		$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
-		
+
 		//* Check if this is a chrooted setup
 		if($web_config['website_basedir'] != '' && @is_file($web_config['/var/www'].'/etc/passwd')) {
 			$apache_chrooted = true;
 		} else {
 			$apache_chrooted = false;
 		}
-		
+
 		if($data["old"]["type"] != "vhost" && $data["old"]["parent_domain_id"] > 0) {
 			//* This is a alias domain or subdomain, so we have to update the website instead
 			$parent_domain_id = intval($data["old"]["parent_domain_id"]);
@@ -870,47 +871,43 @@ class apache2_plugin {
 			$this->action = 'update';
 			// just run the update function
 			$this->update($event_name,$data);
-			
+
 		} 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');
 			unlink($vhost_file);
 			$app->log("Removing vhost file: $vhost_file",LOGLEVEL_DEBUG);
-		
+
 			$docroot = escapeshellcmd($data["old"]["document_root"]);
 			if($docroot != '' && !stristr($docroot,'..')) exec("rm -rf $docroot");
-		
-		
+
+
 			//remove the php fastgi starter script if available
-			if ($data["old"]["php"] == "fast-cgi")
-			{
+			if ($data["old"]["php"] == "fast-cgi") {
 				$fastcgi_starter_path = str_replace("[system_user]",$data["old"]["system_user"],$web_config["fastcgi_starter_path"]);
-				if (is_dir($fastcgi_starter_path))
-				{
+				if (is_dir($fastcgi_starter_path)) {
 					exec("rm -rf $fastcgi_starter_path");
 				}
 			}
-		
+
 			//remove the php cgi starter script if available
-			if ($data["old"]["php"] == "cgi")
-			{
+			if ($data["old"]["php"] == "cgi") {
 				// TODO: fetch the date from the server-settings
 				$web_config["cgi_starter_path"] = $web_config["website_basedir"]."/php-cgi-scripts/[system_user]/";
 
 				$cgi_starter_path = str_replace("[system_user]",$data["old"]["system_user"],$web_config["cgi_starter_path"]);
-				if (is_dir($cgi_starter_path))
-				{
+				if (is_dir($cgi_starter_path)) {
 					exec("rm -rf $cgi_starter_path");
 				}
 			}
 
 			$app->log("Removing website: $docroot",LOGLEVEL_DEBUG);
-		
+
 			// Delete the symlinks for the sites
 			$client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"]));
 			$client_id = intval($client["client_id"]);
@@ -930,53 +927,263 @@ class apache2_plugin {
 				}
 			}
 			// end removing symlinks
-		
+
 			// Delete the log file directory
 			$vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data["old"]["domain"]);
 			if($data["old"]["domain"] != '' && !stristr($vhost_logfile_dir,'..')) exec("rm -rf $vhost_logfile_dir");
 			$app->log("Removing website logfile directory: $vhost_logfile_dir",LOGLEVEL_DEBUG);
-		
+
 			//delete the web user
 			$command = 'userdel';
-			$command .= ' '.$data["old"]["system_user"];			
+			$command .= ' '.$data["old"]["system_user"];
 			exec($command);
 			if($apache_chrooted) $this->_exec("chroot ".escapeshellcmd($web_config['website_basedir'])." ".$command);
-			
+
 		}
 	}
-	
+
 	//* This function is called when a IP on the server is inserted, updated or deleted
 	function server_ip($event_name,$data) {
 		global $app, $conf;
-		
+
 		// load the server configuration options
 		$app->uses("getconf");
 		$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
-		
+
 		$app->load('tpl');
-		
+
 		$tpl = new tpl();
 		$tpl->newTemplate("apache_ispconfig.conf.master");
 		$records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ".$conf["server_id"]." AND virtualhost = 'y'");
-		
+
 		if(count($records) > 0) {
 			$tpl->setLoop('ip_adresses',$records);
 		}
-		
+
 		$vhost_file = escapeshellcmd($web_config["vhost_conf_dir"].'/ispconfig.conf');
 		file_put_contents($vhost_file,$tpl->grab());
 		$app->log("Writing the conf file: ispconfig.conf",LOGLEVEL_DEBUG);
 		unset($tpl);
-		
+
 	}
-	
+
+	/**
+	 * This function is called when a Webdav-User is inserted, updated or deleted.
+	 *
+	 * @author Oliver Vogel
+	 * @param string $event_name
+	 * @param array $data
+	 */
+	public function webdav($event_name,$data) {
+		global $app, $conf;
+
+		if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
+			/*
+			 * load the server configuration options
+			*/
+			$app->uses("getconf");
+			$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
+
+			/*
+			 * Get additional informations
+			*/
+			$sitedata = $app->db->queryOneRecord("SELECT document_root, domain FROM web_domain WHERE domain_id = " . $data['new']['parent_domain_id']);
+			$documentRoot = $sitedata['document_root'];
+			$domain = $sitedata['domain'];
+
+			/* Check if this is a chrooted setup */
+			if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
+				$apache_chrooted = true;
+				$app->log("Info: Apache is chrooted.",LOGLEVEL_DEBUG);
+			} else {
+				$apache_chrooted = 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']));
+			}
+
+			/*
+			 *  The webdav folder (not the root!) has to be owned by the apache-user
+			*/
+			exec('chown ' . escapeshellcmd($web_config['user']) . ':' . escapeshellcmd($web_config['group']) . ' ' . $documentRoot . '/webdav/' . $data['new']['dir'] . ' -R');
+
+			/*
+			 * Next step is to update the password - file
+			*/
+			$this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['new']['dir'] . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
+
+			/*
+			 * Next step, patch the vhost - file
+			*/
+			$vhost_file = escapeshellcmd($web_config["vhost_conf_dir"] . '/' . $domain . '.vhost');
+			$this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
+			
+			/*
+			 * Last, restart apache
+			*/
+			if($apache_chrooted) {
+				$app->services->restartServiceDelayed('httpd','restart');
+			} else {
+				// request a httpd reload when all records have been processed
+				$app->services->restartServiceDelayed('httpd','reload');
+			}
+
+		}
+
+		if ($event_name == 'webdav_user_delete') {
+			/*
+			 * Get additional informations
+			*/
+			$sitedata = $app->db->queryOneRecord("SELECT document_root, domain FROM web_domain WHERE domain_id = " . $data['old']['parent_domain_id']);
+			$documentRoot = $sitedata['document_root'];
+
+			/*
+			 * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
+			 * So the only thing, we have to do, is to delete the user from the password-file
+			 */
+			$this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
+		}
+	}
+
+
+	/**
+	 * This function writes the htdigest - files used by webdav and digest
+	 * @author Oliver Vogel
+	 * @param string $filename The name of the digest-file
+	 * @param string $username The name of the webdav-user
+	 * @param string $authname The name of the realm
+	 * @param string $pwd      The password of the user
+	 */
+	private function _writeHtDigestFile($filename, $username, $authname, $pwd ) {
+		$changed = false;
+		$in = fopen($filename, 'r');
+		$output = '';
+
+		/*
+		 * read line by line and search for the username and authname
+		*/
+		while (preg_match("/:/", $line = fgets($in))) {
+			$line = rtrim($line);
+			$tmp = explode(':', $line);
+			if ($tmp[0] == $username && $tmp[1] == $authname) {
+				/*
+				 * found the user. delete or change it?
+				*/
+				if ($pwd != '') {
+					$tmp[2] = md5($username . ':' . $authname . ':' .$pwd);
+					$output .= $tmp[0] . ':' . $tmp[1] . ':' . $tmp[2] . "\n";
+				}
+				$changed = true;
+			}
+			else {
+				$output .= $line . "\n";
+			}
+		}
+		/*
+		 * if we didn't change anything, we have to add the new user at the end of the file
+		*/
+		if (!$changed) {
+			$output .= $username . ':' . $authname . ':' . md5($username . ':' . $authname . ':' . $pwd) . "\n";
+		}
+		fclose($in);
+
+		/*
+		 * Now lets write the new file
+		*/
+		file_put_contents($filename, $output);
+	}
+
+	/**
+	 * This function patches the vhost-file and adds all webdav - user.
+	 * This function is written, because the creation of the vhost - file is sophisticated and
+	 * i don't want to make it more "heavy" by also adding this code too...
+	 * @author Oliver Vogel
+	 * @param string $fileName The Name of the .vhost-File (path included)
+	 * @param string $webdavRoot The root of the webdav-folder
+	 */
+	private function _patchVhostWebdav($fileName, $webdavRoot) {
+		$in = fopen($fileName, 'r');
+		$output = '';
+		$inWebdavSection = false;
+
+		/*
+		 * read line by line and search for the username and authname
+		*/
+		while ($line = fgets($in)) {
+			/*
+			 *  is the "replace-comment" found...
+			*/
+			if (trim($line) == '# WEBDAV BEGIN') {
+				/*
+				 * The begin of the webdav - section is found, so ignore all lines til the end  is found
+				*/
+				$inWebdavSection = true;
+
+				$output .= "      # WEBDAV BEGIN\n";
+
+				/*
+				 * add all the webdav-dirs to the webdav-section
+				*/
+				$files = scandir($webdavRoot);
+				foreach($files as $file) {
+					if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest') {
+						/*
+						 * found a htdigest - file, so add it to webdav
+						*/
+						$fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
+						$output .= "\n";
+						$output .= "      Alias /" . $fn . " " . $webdavRoot . "/" . $fn . "\n";
+						$output .= "      <Location /" . $fn . ">\n";
+						$output .= "        DAV On\n";
+						$output .= "        AuthType Digest\n";
+						$output .= "        AuthName \"" . $fn . "\"\n";
+						$output .= "        AuthUserFile " . $webdavRoot . "/" . $file . "\n";
+						$output .= "        Require valid-user \n";
+						$output .= "        Options +Indexes \n";
+						$output .= "        Order allow,deny \n";
+						$output .= "        Allow from all \n";
+						$output .= "      </Location> \n";
+					}
+				}
+			}
+			/*
+			 *  is the "replace-comment-end" found...
+			*/
+			if (trim($line) == '# WEBDAV END') {
+				/*
+				 * The end of the webdav - section is found, so stop ignoring
+				*/
+				$inWebdavSection = false;
+			}
+
+			/*
+			 * Write the line to the output, if it is not in the section
+			*/
+			if (!$inWebdavSection) {
+				$output .= $line;
+			}
+		}
+		fclose($in);
+
+		/*
+		 * Now lets write the new file
+		*/
+		file_put_contents($fileName, $output);
+
+	}
+
 	//* Wrapper for exec function for easier debugging
 	private function _exec($command) {
 		global $app;
 		$app->log("exec: ".$command,LOGLEVEL_DEBUG);
 		exec($command);
 	}
-	
+
 
 } // end class
 
-- 
GitLab