From ac933eda98110a7b12e488f47ce493c56f1e04de Mon Sep 17 00:00:00 2001 From: vogelor 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 ef54f044c..c3dae3bb9 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 8a8ccf6fa..21ec3a057 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 c6541e762..ff1ecf399 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 63d718225..258b50f24 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 35132feaf..92b00d648 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 4ca816163..35520784c 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -162,6 +162,13 @@ AssignUserId + + # DO NOT REMOVE THE COMMENTS! + # IF YOU REMOVE THEM, WEBDAV WILL NOT WORK ANYMORE! + # WEBDAV BEGIN + # WEBDAV END + + @@ -339,6 +346,13 @@ AssignUserId + + # DO NOT REMOVE THE COMMENTS! + # IF YOU REMOVE THEM, WEBDAV WILL NOT WORK ANYMORE! + # WEBDAV BEGIN + # WEBDAV END + + diff --git a/server/mods-available/web_module.inc.php b/server/mods-available/web_module.inc.php index 1e7bde7f4..eeae0920e 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 4445db359..49b8109df 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 .= " \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 .= " \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