Till Brehm
2014-10-17 074a578110cefcd658b1c491491757478bf7907e
commit | author | age
46c683 1 <?php
T 2
3 /*
cea1e5 4 Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
46c683 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class apache2_plugin {
ac933e 32
46c683 33     var $plugin_name = 'apache2_plugin';
T 34     var $class_name = 'apache2_plugin';
ac933e 35
46c683 36     // private variables
T 37     var $action = '';
481c00 38     var $ssl_certificate_changed = false;
ac933e 39
46c683 40     //* This function is called during ispconfig installation to determine
T 41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
ac933e 44
46c683 45         if($conf['services']['web'] == true) {
T 46             return true;
47         } else {
48             return false;
49         }
ac933e 50
46c683 51     }
ac933e 52
V 53
46c683 54     /*
T 55          This function is called when the plugin is loaded
56     */
ac933e 57
46c683 58     function onLoad() {
T 59         global $app;
ac933e 60
46c683 61         /*
T 62         Register for the events
63         */
7fe908 64         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl');
MC 65         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl');
66         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl');
ac933e 67
7fe908 68         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert');
MC 69         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update');
70         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete');
ac933e 71
7fe908 72         $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip');
MC 73         $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip');
74         $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip');
ac933e 75
7fe908 76         $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav');
MC 77         $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav');
78         $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav');
79
80         $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');
81
82         $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user');
83         $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user');
84         $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user');
85
86         $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update');
87         $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete');
88
89         $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete');
90
46c683 91     }
ac933e 92
46c683 93     // Handle the creation of SSL certificates
7fe908 94     function ssl($event_name, $data) {
46c683 95         global $app, $conf;
7fe908 96
c77103 97         $app->uses('system');
1a2310 98
L 99         // load the server configuration options
100         $app->uses('getconf');
101         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
102         if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
7fe908 103             $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);
MC 104
1ca823 105         //* Only vhosts can have a ssl cert
6fb93d 106         if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return;
ac933e 107
c77103 108         // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
T 109         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
7fe908 110
fb3339 111         $ssl_dir = $data['new']['document_root'].'/ssl';
J 112         $domain = $data['new']['ssl_domain'];
113         $key_file = $ssl_dir.'/'.$domain.'.key.org';
114         $key_file2 = $ssl_dir.'/'.$domain.'.key';
115         $csr_file = $ssl_dir.'/'.$domain.'.csr';
116         $crt_file = $ssl_dir.'/'.$domain.'.crt';
ac933e 117
4bd960 118         //* Create a SSL Certificate, but only if this is not a mirror server.
T 119         if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
7fe908 120
481c00 121             $this->ssl_certificate_changed = true;
7fe908 122
e94a9f 123             //* Rename files if they exist
43b345 124             if(file_exists($key_file)){
7fe908 125                 $app->system->rename($key_file, $key_file.'.bak');
MC 126                 $app->system->chmod($key_file.'.bak', 0400);
43b345 127             }
T 128             if(file_exists($key_file2)){
7fe908 129                 $app->system->rename($key_file2, $key_file2.'.bak');
MC 130                 $app->system->chmod($key_file2.'.bak', 0400);
43b345 131             }
7fe908 132             if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
MC 133             if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
134
fb3339 135             $rand_file = $ssl_dir.'/random_file';
7fe908 136             $rand_data = md5(uniqid(microtime(), 1));
ac933e 137             for($i=0; $i<1000; $i++) {
7fe908 138                 $rand_data .= md5(uniqid(microtime(), 1));
MC 139                 $rand_data .= md5(uniqid(microtime(), 1));
140                 $rand_data .= md5(uniqid(microtime(), 1));
141                 $rand_data .= md5(uniqid(microtime(), 1));
ac933e 142             }
c77103 143             $app->system->file_put_contents($rand_file, $rand_data);
46c683 144
7fe908 145             $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15);
ac933e 146
46c683 147             $ssl_cnf = "        RANDFILE               = $rand_file
T 148
149         [ req ]
6d80f5 150         default_bits           = 2048
6068b7 151         default_md             = sha256
46c683 152         default_keyfile        = keyfile.pem
T 153         distinguished_name     = req_distinguished_name
154         attributes             = req_attributes
155         prompt                 = no
156         output_password        = $ssl_password
157
158         [ req_distinguished_name ]
e94a9f 159         C                      = ".trim($data['new']['ssl_country'])."
T 160         ST                     = ".trim($data['new']['ssl_state'])."
161         L                      = ".trim($data['new']['ssl_locality'])."
162         O                      = ".trim($data['new']['ssl_organisation'])."
163         OU                     = ".trim($data['new']['ssl_organisation_unit'])."
46c683 164         CN                     = $domain
T 165         emailAddress           = webmaster@".$data['new']['domain']."
166
167         [ req_attributes ]
168         challengePassword              = A challenge password";
ac933e 169
fb3339 170             $ssl_cnf_file = $ssl_dir.'/openssl.conf';
7fe908 171             $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
ac933e 172
46c683 173             $rand_file = escapeshellcmd($rand_file);
T 174             $key_file = escapeshellcmd($key_file);
8c82ef 175             $openssl_cmd_key_file = $key_file;
992797 176             if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
46c683 177             $key_file2 = escapeshellcmd($key_file2);
8c82ef 178             $openssl_cmd_key_file2 = $key_file2;
992797 179             if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
46c683 180             $ssl_days = 3650;
T 181             $csr_file = escapeshellcmd($csr_file);
8c82ef 182             $openssl_cmd_csr_file = $csr_file;
992797 183             if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
46c683 184             $config_file = escapeshellcmd($ssl_cnf_file);
T 185             $crt_file = escapeshellcmd($crt_file);
8c82ef 186             $openssl_cmd_crt_file = $crt_file;
992797 187             if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
46c683 188
c77103 189             if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
7fe908 190
8c82ef 191                 exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
6068b7 192                 exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -out $openssl_cmd_csr_file -days $ssl_days -config $config_file");
8c82ef 193                 exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
1a2310 194
L 195                 if(file_exists($web_config['CA_path'].'/openssl.cnf'))
5c4d55 196                 {
8c82ef 197                     exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file");
7fe908 198                     $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
8c82ef 199                     if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR);
1a2310 200                 };
723662 201                 if (@filesize($crt_file)==0 || !file_exists($crt_file)){
8c82ef 202                     exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file ");
7fe908 203                     $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
5c4d55 204                 };
7fe908 205
ac933e 206             }
46c683 207
7fe908 208             $app->system->chmod($key_file, 0400);
MC 209             $app->system->chmod($key_file2, 0400);
c77103 210             @$app->system->unlink($config_file);
T 211             @$app->system->unlink($rand_file);
212             $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file));
213             $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file));
0d20af 214             $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
d1086f 215             /* Update the DB of the (local) Server */
0d20af 216             $app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 217             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 218             /* Update also the master-DB of the Server-Farm */
0d20af 219             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 220             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
46c683 221         }
ac933e 222
46c683 223         //* Save a SSL certificate to disk
9f56bd 224         if($data["new"]["ssl_action"] == 'save') {
481c00 225             $this->ssl_certificate_changed = true;
9f56bd 226             $ssl_dir = $data["new"]["document_root"]."/ssl";
edf806 227             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
481c00 228             $key_file = $ssl_dir.'/'.$domain.'.key.org';
0d20af 229             $key_file2 = $ssl_dir.'/'.$domain.'.key';
9f56bd 230             $csr_file = $ssl_dir.'/'.$domain.".csr";
T 231             $crt_file = $ssl_dir.'/'.$domain.".crt";
232             $bundle_file = $ssl_dir.'/'.$domain.".bundle";
7fe908 233
481c00 234             //* Backup files
43b345 235             if(file_exists($key_file)){
7fe908 236                 $app->system->copy($key_file, $key_file.'~');
MC 237                 $app->system->chmod($key_file.'~', 0400);
43b345 238             }
T 239             if(file_exists($key_file2)){
7fe908 240                 $app->system->copy($key_file2, $key_file2.'~');
MC 241                 $app->system->chmod($key_file2.'~', 0400);
43b345 242             }
7fe908 243             if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~');
MC 244             if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~');
245             if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~');
246
481c00 247             //* Write new ssl files
7fe908 248             if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
MC 249             if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
250             if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
251
72695f 252             //* Write the key file, if field is empty then import the key into the db
T 253             if(trim($data["new"]["ssl_key"]) != '') {
7fe908 254                 $app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
MC 255                 $app->system->chmod($key_file2, 0400);
72695f 256             } else {
T 257                 $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
258                 /* Update the DB of the (local) Server */
259                 $app->db->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
260                 /* Update also the master-DB of the Server-Farm */
261                 $app->dbmaster->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
262             }
7fe908 263
d1086f 264             /* Update the DB of the (local) Server */
fb3339 265             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 266
d1086f 267             /* Update also the master-DB of the Server-Farm */
fb3339 268             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 269             $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 270         }
ac933e 271
46c683 272         //* Delete a SSL certificate
fb3339 273         if($data['new']['ssl_action'] == 'del') {
J 274             $ssl_dir = $data['new']['document_root'].'/ssl';
edf806 275             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
fb3339 276             $csr_file = $ssl_dir.'/'.$domain.'.csr';
J 277             $crt_file = $ssl_dir.'/'.$domain.'.crt';
278             $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
c77103 279             if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
7fe908 280             {
8c82ef 281                 exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
7fe908 282                 $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
MC 283             };
c77103 284             $app->system->unlink($csr_file);
T 285             $app->system->unlink($crt_file);
286             $app->system->unlink($bundle_file);
d1086f 287             /* Update the DB of the (local) Server */
fb3339 288             $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 289             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 290             /* Update also the master-DB of the Server-Farm */
fb3339 291             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 292             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 293             $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 294         }
ac933e 295
46c683 296     }
ac933e 297
V 298
7fe908 299     function insert($event_name, $data) {
46c683 300         global $app, $conf;
ac933e 301
46c683 302         $this->action = 'insert';
T 303         // just run the update function
7fe908 304         $this->update($event_name, $data);
ac933e 305
V 306
46c683 307     }
ac933e 308
V 309
7fe908 310     function update($event_name, $data) {
46c683 311         global $app, $conf;
ac933e 312
46c683 313         if($this->action != 'insert') $this->action = 'update';
ac933e 314
6fb93d 315         if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) {
ac933e 316
fb3339 317             $old_parent_domain_id = intval($data['old']['parent_domain_id']);
J 318             $new_parent_domain_id = intval($data['new']['parent_domain_id']);
ac933e 319
1ca823 320             // If the parent_domain_id has been changed, we will have to update the old site as well.
fb3339 321             if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
J 322                 $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'");
323                 $data['new'] = $tmp;
324                 $data['old'] = $tmp;
46c683 325                 $this->action = 'update';
7fe908 326                 $this->update($event_name, $data);
46c683 327             }
ac933e 328
46c683 329             // This is not a vhost, so we need to update the parent record instead.
fb3339 330             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'");
J 331             $data['new'] = $tmp;
332             $data['old'] = $tmp;
46c683 333             $this->action = 'update';
T 334         }
ac933e 335
46c683 336         // load the server configuration options
fb3339 337         $app->uses('getconf');
J 338         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 339
2bbc4c 340         //* Check if this is a chrooted setup
155cc0 341         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 342             $apache_chrooted = true;
7fe908 343             $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
2bbc4c 344         } else {
T 345             $apache_chrooted = false;
346         }
ac933e 347
fb3339 348         if($data['new']['document_root'] == '') {
7fe908 349             if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set', LOGLEVEL_WARN);
46c683 350             return 0;
T 351         }
15687e 352         if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
TB 353             || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
354             $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
46c683 355             return 0;
T 356         }
e94a9f 357         if(trim($data['new']['domain']) == '') {
7fe908 358             $app->log('domain is empty', LOGLEVEL_WARN);
e94a9f 359             return 0;
T 360         }
7fe908 361
MC 362         $web_folder = 'web';
363         $log_folder = 'log';
79d955 364         $old_web_folder = 'web';
MC 365         $old_log_folder = 'log';
7fe908 366         if($data['new']['type'] == 'vhostsubdomain') {
79d955 367             // new one
7fe908 368             $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id']));
MC 369             $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
370             if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
371             $web_folder = $data['new']['web_folder'];
372             $log_folder .= '/' . $subdomain_host;
373             unset($tmp);
79d955 374             
MC 375             if(isset($data['old']['parent_domain_id'])) {
376                 // old one
377                 $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
378                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
379                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
380                 $old_web_folder = $data['old']['web_folder'];
381                 $old_log_folder .= '/' . $subdomain_host;
382                 unset($tmp);
383             }
7fe908 384         }
6fb93d 385
dba68f 386         // Create group and user, if not exist
T 387         $app->uses('system');
7fe908 388
8cf78b 389         if($web_config['connect_userid_to_webid'] == 'y') {
T 390             //* Calculate the uid and gid
391             $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
392             $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
393             $fixed_uid_param = '--uid '.$fixed_uid_gid;
394             $fixed_gid_param = '--gid '.$fixed_uid_gid;
7fe908 395
8cf78b 396             //* Check if a ispconfigend user and group exists and create them
T 397             if(!$app->system->is_group('ispconfigend')) {
398                 exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
399             }
400             if(!$app->system->is_user('ispconfigend')) {
401                 exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
402             }
403         } else {
404             $fixed_uid_param = '';
405             $fixed_gid_param = '';
406         }
dba68f 407
T 408         $groupname = escapeshellcmd($data['new']['system_group']);
409         if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
8cf78b 410             exec('groupadd '.$fixed_gid_param.' '.$groupname);
dba68f 411             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
7fe908 412             $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG);
dba68f 413         }
T 414
415         $username = escapeshellcmd($data['new']['system_user']);
416         if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
8cf78b 417             if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 418                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
419                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
420             } else {
421                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
422                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
423             }
7fe908 424             $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG);
dba68f 425         }
ac933e 426
46c683 427         //* If the client of the site has been changed, we have a change of the document root
fb3339 428         if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
ac933e 429
46c683 430             //* Get the old client ID
fb3339 431             $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
J 432             $old_client_id = intval($old_client['client_id']);
46c683 433             unset($old_client);
ac933e 434
46c683 435             //* Remove the old symlinks
7fe908 436             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 437             if(is_array($tmp_symlinks_array)) {
T 438                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 439                     $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink);
MC 440                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 441                     // Remove trailing slash
T 442                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
443                     // create the symlinks, if not exist
436975 444                     if(is_link($tmp_symlink)) {
fb3339 445                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 446                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 447                     }
T 448                 }
449             }
7fe908 450
4b9329 451             //* Remove protection of old folders
7fe908 452             $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 453
7fe908 454             if($data["new"]["type"] != "vhostsubdomain") {
MC 455                 //* Move the site data
456                 $tmp_docroot = explode('/', $data['new']['document_root']);
457                 unset($tmp_docroot[count($tmp_docroot)-1]);
458                 $new_dir = implode('/', $tmp_docroot);
ac933e 459
7fe908 460                 $tmp_docroot = explode('/', $data['old']['document_root']);
MC 461                 unset($tmp_docroot[count($tmp_docroot)-1]);
462                 $old_dir = implode('/', $tmp_docroot);
ac933e 463
7fe908 464                 //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path
MC 465                 if(@is_dir($data['new']['document_root'])) {
466                     $app->system->web_folder_protection($data['new']['document_root'], false);
467                     $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
468                     $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG);
469                 }
3fb802 470                 
TB 471                 //* Unmount the old log directory bfore we move the log dir
472                 exec('umount '.escapeshellcmd($old_dir.'/log'));
ac933e 473
7fe908 474                 //* Create new base directory, if it does not exist yet
MC 475                 if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
476                 $app->system->web_folder_protection($data['old']['document_root'], false);
477                 exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
478                 //$app->system->rename($data['old']['document_root'],$new_dir);
479                 $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG);
0930f5 480
7fe908 481                 // Handle the change in php_open_basedir
MC 482                 $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']);
483
484                 //* Change the owner of the website files to the new website owner
485                 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);
486
487                 //* Change the home directory and group of the website user
488                 $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod';
489                 $command .= ' --home '.escapeshellcmd($data['new']['document_root']);
490                 $command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
491                 $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
492                 exec($command);
493             }
494
fb3339 495             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
7fe908 496
10b4c8 497             //* Change the log mount
074a57 498             /*
79d955 499             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 500             $app->system->removeLine('/etc/fstab', $fstab_line);
79d955 501             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
ff5b86 502             $app->system->removeLine('/etc/fstab', $fstab_line);
074a57 503             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
TB 504             $app->system->removeLine('/etc/fstab', $fstab_line);
505             */
506             
507             $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
508             
509             if($web_config['network_filesystem'] == 'y') {
510                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
511                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
512             } else {
513                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
514                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
515             }
3fb802 516             
TB 517             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
074a57 518             
46c683 519         }
ac933e 520
46c683 521         //print_r($data);
ac933e 522
fb3339 523         // Check if the directories are there and create them if necessary.
7fe908 524         $app->system->web_folder_protection($data['new']['document_root'], false);
MC 525
6fb93d 526         if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
M 527         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
528         //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
c77103 529         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
T 530         if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
531         if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
532         if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
7fe908 533
d87f76 534         //* Create the new private directory
T 535         if(!is_dir($data['new']['document_root'].'/private')) {
536             $app->system->mkdirpath($data['new']['document_root'].'/private');
7fe908 537             $app->system->chmod($data['new']['document_root'].'/private', 0710);
MC 538             $app->system->chown($data['new']['document_root'].'/private', $username);
539             $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
d87f76 540         }
7fe908 541
MC 542
46c683 543         // Remove the symlink for the site, if site is renamed
fb3339 544         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
J 545             if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
79d955 546             if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
7fe908 547
10b4c8 548             //* remove old log mount
79d955 549             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 550             $app->system->removeLine('/etc/fstab', $fstab_line);
MC 551
10b4c8 552             //* Unmount log directory
79d955 553             exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
46c683 554         }
7fe908 555
d5a517 556         //* Create the log dir if nescessary and mount it
10b4c8 557         if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) {
6fb93d 558             if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
10b4c8 559             if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
c3bf39 560             $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
7fe908 561             $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root');
MC 562             $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root');
563             $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 564             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
d5a517 565             //* add mountpoint to fstab
ff5b86 566             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
7fe908 567             $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
d5a517 568         }
7fe908 569
MC 570         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 571
46c683 572         // Get the client ID
fb3339 573         $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
J 574         $client_id = intval($client['client_id']);
46c683 575         unset($client);
ac933e 576
46c683 577         // Remove old symlinks, if site is renamed
fb3339 578         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
7fe908 579             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 580             if(is_array($tmp_symlinks_array)) {
T 581                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 582                     $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 583                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 584                     // Remove trailing slash
T 585                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
586                     // remove the symlinks, if not exist
587                     if(is_link($tmp_symlink)) {
fb3339 588                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 589                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 590                     }
T 591                 }
592             }
593         }
ac933e 594
46c683 595         // Create the symlinks for the sites
7fe908 596         $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 597         if(is_array($tmp_symlinks_array)) {
T 598             foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 599                 $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 600                 $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink);
46c683 601                 // Remove trailing slash
T 602                 if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
603                 //* Remove symlink if target folder has been changed.
fb3339 604                 if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
c77103 605                     $app->system->unlink($tmp_symlink);
46c683 606                 }
T 607                 // create the symlinks, if not exist
608                 if(!is_link($tmp_symlink)) {
7fe908 609                     //     exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
552178 610                     if ($web_config["website_symlinks_rel"] == 'y') {
M 611                         $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
612                     } else {
613                         exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
614                     }
615
7fe908 616                     $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 617                 }
T 618             }
619         }
ac933e 620
V 621
3e41e8 622
7fe908 623         // Install the Standard or Custom Error, Index and other related files
MC 624         // /usr/local/ispconfig/server/conf is for the standard files
625         // /usr/local/ispconfig/server/conf-custom is for the custom files
626         // setting a local var here
627
628         // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
6fb93d 629         if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
7fe908 630
MC 631             // Copy the error pages
fb3339 632             if($data['new']['errordocs']) {
6fb93d 633                 $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 634                 if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 635                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 636                 }
T 637                 else {
4ffb51 638                     if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 639                         exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 640                     }
T 641                     else {
7fe908 642                         exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 643                     }
T 644                 }
fb3339 645                 exec('chmod -R a+r '.$error_page_path);
46c683 646             }
T 647
7fe908 648             if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 649                 exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
650
651                 if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
652                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
653                 }
654                 if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
655                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
656                 }
657                 if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
658                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
659                 }
660             }
46c683 661             else {
4ffb51 662                 if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
6fb93d 663                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
46c683 664                 }
T 665                 else {
7fe908 666                     exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
6fb93d 667                     if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
M 668                     if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
669                     if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
46c683 670                 }
T 671             }
6fb93d 672             exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
ac933e 673
V 674             //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
6fb93d 675         } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
7fe908 676
6fb93d 677             $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 678             if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 679                 exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 680             }
T 681             else {
4ffb51 682                 if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 683                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 684                 }
T 685                 else {
7fe908 686                     exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 687                 }
T 688             }
fb3339 689             exec('chmod -R a+r '.$error_page_path);
5d5d88 690             exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
46c683 691         }  // end copy error docs
ac933e 692
cc6568 693         // Set the quota for the user, but only for vhosts, not vhostsubdomains
H 694         if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
fb3339 695             if($data['new']['hd_quota'] > 0) {
J 696                 $blocks_soft = $data['new']['hd_quota'] * 1024;
ac933e 697                 $blocks_hard = $blocks_soft + 1024;
V 698             } else {
699                 $blocks_soft = $blocks_hard = 0;
700             }
46c683 701             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
fb3339 702             exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
46c683 703         }
ac933e 704
1ca823 705         if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
46c683 706             // Chown and chmod the directories below the document root
6fb93d 707             $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 708             // The document root itself has to be owned by root in normal level and by the web owner in security level 20
T 709             if($web_config['security_level'] == 20) {
6fb93d 710                 $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 711             } else {
6fb93d 712                 $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 713             }
46c683 714         }
7fe908 715
615a0a 716         //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update
T 717         if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
ac933e 718
8db8f3 719         //* If the security level is set to high
8cf78b 720         if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
7fe908 721
MC 722             $app->system->web_folder_protection($data['new']['document_root'], false);
723
d87f76 724             //* Check if we have the new private folder and create it if nescessary
T 725             if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
7fe908 726
edf806 727             if($web_config['security_level'] == 20) {
7fe908 728
MC 729                 $app->system->chmod($data['new']['document_root'], 0755);
7c37ed 730                 $app->system->chmod($data['new']['document_root'].'/web', 0711);
7fe908 731                 $app->system->chmod($data['new']['document_root'].'/webdav', 0710);
MC 732                 $app->system->chmod($data['new']['document_root'].'/private', 0710);
733                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
ac933e 734
edf806 735                 // make tmp directory writable for Apache and the website users
5aedfd 736                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 737
cea1e5 738                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 739                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 740                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
c77103 741                 }
7fe908 742
8cf78b 743                 if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 744                     $command = 'usermod';
745                     $command .= ' --groups sshusers';
526b99 746                     $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
8cf78b 747                     $this->_exec($command);
T 748                 }
ac933e 749
edf806 750                 //* if we have a chrooted Apache environment
T 751                 if($apache_chrooted) {
752                     $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
ac933e 753
edf806 754                     //* add the apache user to the client group in the chroot environment
T 755                     $tmp_groupfile = $app->system->server_conf['group_datei'];
756                     $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
757                     $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
758                     $app->system->server_conf['group_datei'] = $tmp_groupfile;
759                     unset($tmp_groupfile);
760                 }
7fe908 761
8cf78b 762                 //* Chown all default directories
7fe908 763                 $app->system->chown($data['new']['document_root'], 'root');
MC 764                 $app->system->chgrp($data['new']['document_root'], 'root');
765                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
766                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 767                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 768                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 769                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 770                 }
7fe908 771                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
MC 772                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
773                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
774                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
775                 $app->system->chown($data['new']['document_root'].'/web', $username);
776                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
777                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
778                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
779                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
780                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
781                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
782                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
783                 $app->system->chown($data['new']['document_root'].'/private', $username);
784                 $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
ac933e 785
edf806 786                 // If the security Level is set to medium
T 787             } else {
788
7fe908 789                 $app->system->chmod($data['new']['document_root'], 0755);
MC 790                 $app->system->chmod($data['new']['document_root'].'/web', 0755);
791                 $app->system->chmod($data['new']['document_root'].'/webdav', 0755);
792                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
793                 $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
794
edf806 795                 // make temp directory writable for Apache and the website users
5aedfd 796                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 797
6fb93d 798                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 799                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 800                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 801                 }
7fe908 802
MC 803                 $app->system->chown($data['new']['document_root'], 'root');
804                 $app->system->chgrp($data['new']['document_root'], 'root');
805                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
806                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 807                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 808                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 809                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 810                 }
7fe908 811
MC 812                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
813                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
814                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
815                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
816                 $app->system->chown($data['new']['document_root'].'/web', $username);
817                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
818                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
819                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
820                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
821                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
822                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
823                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
8db8f3 824             }
6fb93d 825         } elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) {
M 826             if($web_config['security_level'] == 20) {
7fe908 827                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710);
MC 828                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
829                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
830                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
831                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
832                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
833                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
834             } else {
835                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755);
836                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
837                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
838                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
839                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
840                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
841                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
842             }
843         }
844
4b9329 845         //* Protect web folders
7fe908 846         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 847
6fb93d 848         if($data['new']['type'] == 'vhost') {
7fe908 849             // Change the ownership of the error log to the root user
MC 850             if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
851             $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
852             $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
853         }
ac933e 854
26c0fc 855         //* Write the custom php.ini file, if custom_php_ini fieled is not empty
fb3339 856         $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
7fe908 857         if($data['new']['type'] == 'vhostsubdomain') $custom_php_ini_dir .= '_' . $web_folder;
c77103 858         if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
7fe908 859
26c0fc 860         //* add open_basedir restriction to custom php.ini content, required for suphp only
7fe908 861         if(!stristr($data['new']['custom_php_ini'], 'open_basedir') && $data['new']['php'] == 'suphp') {
26c0fc 862             $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n";
T 863         }
7fe908 864
cc6568 865         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
7fe908 866
cc6568 867         if(trim($data['new']['fastcgi_php_version']) != ''){
H 868             list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
869             if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir);
7fe908 870             if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1);
cc6568 871         }
H 872
26c0fc 873         //* Create custom php.ini
fb3339 874         if(trim($data['new']['custom_php_ini']) != '') {
7fddfe 875             $has_custom_php_ini = true;
3f478f 876             if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
7fddfe 877             $php_ini_content = '';
fb3339 878             if($data['new']['php'] == 'mod') {
7fddfe 879                 $master_php_ini_path = $web_config['php_ini_path_apache'];
T 880             } else {
cc6568 881                 if($data["new"]['php'] == 'fast-cgi') {
H 882                     if(trim($data['new']['fastcgi_php_version']) != '' && file_exists($custom_fastcgi_php_ini_dir)){
883                         $master_php_ini_path = $custom_fastcgi_php_ini_dir;
884                     } elseif(file_exists($fastcgi_config["fastcgi_phpini_path"])){
885                         $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
886                     } else {
887                         $master_php_ini_path = $web_config['php_ini_path_cgi'];
888                     }
9f56bd 889                 } else {
T 890                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
891                 }
7fddfe 892             }
7fe908 893
72695f 894             //* Add php.ini to the path in case that the master_php_ini_path is a directory
T 895             if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) {
7fe908 896                 if(substr($master_php_ini_path, -1) == '/') $master_php_ini_path = substr($master_php_ini_path, 0, -1);
72695f 897                 $master_php_ini_path .= '/php.ini';
T 898             }
7fe908 899
MC 900             if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
c77103 901                 $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
7fddfe 902             }
7fe908 903             $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini']));
MC 904             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
7fddfe 905         } else {
T 906             $has_custom_php_ini = false;
c77103 907             if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
7fddfe 908         }
T 909
910
911         //* Create the vhost config file
46c683 912         $app->load('tpl');
ac933e 913
46c683 914         $tpl = new tpl();
fb3339 915         $tpl->newTemplate('vhost.conf.master');
ac933e 916
fb3339 917         $vhost_data = $data['new'];
a7bdf8 918         //unset($vhost_data['ip_address']);
6fb93d 919         $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder;
M 920         $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder;
fb3339 921         $vhost_data['web_basedir'] = $web_config['website_basedir'];
J 922         $vhost_data['security_level'] = $web_config['security_level'];
923         $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override'];
924         $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
925         $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
926         $vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
927         $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
7fe908 928
02bf99 929         // Custom Apache directives
T 930         // Make sure we only have Unix linebreaks
931         $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
932         $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
018955 933         $trans = array('{DOCROOT}' => $vhost_data['web_document_root_www']);
FT 934         $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans);
ac933e 935
46c683 936         // Check if a SSL cert exists
fb3339 937         $ssl_dir = $data['new']['document_root'].'/ssl';
J 938         $domain = $data['new']['ssl_domain'];
939         $key_file = $ssl_dir.'/'.$domain.'.key';
940         $crt_file = $ssl_dir.'/'.$domain.'.crt';
941         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
ac933e 942
a7bdf8 943         /*
1a2310 944         if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
fb3339 945             $vhost_data['ssl_enabled'] = 1;
J 946             $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
46c683 947         } else {
fb3339 948             $vhost_data['ssl_enabled'] = 0;
1a2310 949             $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
46c683 950         }
a7bdf8 951         */
ac933e 952
46c683 953         if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
ac933e 954
6fb93d 955         //$vhost_data['document_root'] = $data['new']['document_root'].'/' . $web_folder;
7fe908 956
e64fbb 957         // Set SEO Redirect
bfcdef 958         if($data['new']['seo_redirect'] != ''){
e64fbb 959             $vhost_data['seo_redirect_enabled'] = 1;
bfcdef 960             $tmp_seo_redirects = $this->get_seo_redirects($data['new']);
T 961             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
962                 foreach($tmp_seo_redirects as $key => $val){
963                     $vhost_data[$key] = $val;
964                 }
965             } else {
966                 $vhost_data['seo_redirect_enabled'] = 0;
e64fbb 967             }
F 968         } else {
969             $vhost_data['seo_redirect_enabled'] = 0;
970         }
7fe908 971
46c683 972         $tpl->setVar($vhost_data);
8133de 973         $tpl->setVar('apache_version', $app->system->getapacheversion());
ac933e 974
46c683 975         // Rewrite rules
T 976         $rewrite_rules = array();
02bf99 977         if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
7fe908 978             if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/';
MC 979             if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){
980                 $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8);
981                 $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8);
45ee67 982             } else {
F 983                 $rewrite_target = $data['new']['redirect_path'];
984                 $rewrite_target_ssl = $data['new']['redirect_path'];
985             }
bc2c3e 986             /* Disabled path extension
fb3339 987             if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 988                 $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 989             }
bc2c3e 990             */
ac933e 991
fb3339 992             switch($data['new']['subdomain']) {
7fe908 993             case 'www':
MC 994                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
995                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
996                     'rewrite_target'  => $rewrite_target,
997                     'rewrite_target_ssl' => $rewrite_target_ssl,
998                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
999                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1000                 $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
1001                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1002                     'rewrite_target'  => $rewrite_target,
1003                     'rewrite_target_ssl' => $rewrite_target_ssl,
1004                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1005                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1006                 break;
1007             case '*':
1008                 $rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
1009                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1010                     'rewrite_target'  => $rewrite_target,
1011                     'rewrite_target_ssl' => $rewrite_target_ssl,
1012                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1013                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1014                 break;
1015             default:
1016                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1017                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1018                     'rewrite_target'  => $rewrite_target,
1019                     'rewrite_target_ssl' => $rewrite_target_ssl,
1020                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1021                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1022             }
46c683 1023         }
7fe908 1024
3501f9 1025         $server_alias = array();
7fe908 1026
3501f9 1027         // get autoalias
M 1028         $auto_alias = $web_config['website_autoalias'];
1029         if($auto_alias != '') {
1030             // get the client username
1031             $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'");
1032             $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
1033             $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
1034             $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
1035             unset($client);
1036             unset($aa_search);
1037             unset($aa_replace);
cece69 1038             $server_alias[] .= $auto_alias.' ';
3501f9 1039         }
7fe908 1040
46c683 1041         // get alias domains (co-domains and subdomains)
6fb93d 1042         $aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'");
bfcdef 1043         $alias_seo_redirects = array();
fb3339 1044         switch($data['new']['subdomain']) {
7fe908 1045         case 'www':
MC 1046             $server_alias[] .= 'www.'.$data['new']['domain'].' ';
1047             break;
1048         case '*':
1049             $server_alias[] .= '*.'.$data['new']['domain'].' ';
1050             break;
ac933e 1051         }
46c683 1052         if(is_array($aliases)) {
T 1053             foreach($aliases as $alias) {
fb3339 1054                 switch($alias['subdomain']) {
7fe908 1055                 case 'www':
MC 1056                     $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' ';
1057                     break;
1058                 case '*':
1059                     $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' ';
1060                     break;
1061                 default:
1062                     $server_alias[] .= $alias['domain'].' ';
1063                     break;
ac933e 1064                 }
7fe908 1065                 $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG);
MC 1066
bfcdef 1067                 // Add SEO redirects for alias domains
T 1068                 if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){
1069                     $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1070                     if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1071                         $alias_seo_redirects[] = $tmp_seo_redirects;
1072                     }
1073                 }
7fe908 1074
46c683 1075                 // Rewriting
02bf99 1076                 if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') {
7fe908 1077                     if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/';
MC 1078                     if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){
1079                         $rewrite_target = 'http'.substr($alias['redirect_path'], 8);
1080                         $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8);
e64fbb 1081                     } else {
F 1082                         $rewrite_target = $alias['redirect_path'];
1083                         $rewrite_target_ssl = $alias['redirect_path'];
1084                     }
bc2c3e 1085                     /* Disabled the path extension
fb3339 1086                     if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1087                         $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1088                     }
bc2c3e 1089                     */
7fe908 1090
fb3339 1091                     switch($alias['subdomain']) {
7fe908 1092                     case 'www':
MC 1093                         $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($alias['domain']),
1094                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1095                             'rewrite_target'  => $rewrite_target,
1096                             'rewrite_target_ssl' => $rewrite_target_ssl,
1097                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1098                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1099                         $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$alias['domain']),
1100                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1101                             'rewrite_target'  => $rewrite_target,
1102                             'rewrite_target_ssl' => $rewrite_target_ssl,
1103                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1104                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1105                         break;
1106                     case '*':
1107                         $rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
1108                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1109                             'rewrite_target'  => $rewrite_target,
1110                             'rewrite_target_ssl' => $rewrite_target_ssl,
1111                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1112                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1113                         break;
1114                     default:
1115                         if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2));
1116                         else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']);
1117                         $rewrite_rules[] = array( 'rewrite_domain'  => $domain_rule,
1118                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1119                             'rewrite_target'  => $rewrite_target,
1120                             'rewrite_target_ssl' => $rewrite_target_ssl,
1121                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1122                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1123                     }
46c683 1124                 }
T 1125             }
1126         }
ac933e 1127
47cca9 1128         //* If we have some alias records
T 1129         if(count($server_alias) > 0) {
1130             $server_alias_str = '';
1131             $n = 0;
ac933e 1132
47cca9 1133             // begin a new ServerAlias line after 30 alias domains
T 1134             foreach($server_alias as $tmp_alias) {
1135                 if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
1136                 $server_alias_str .= $tmp_alias;
1137             }
1138             unset($tmp_alias);
ac933e 1139
7fe908 1140             $tpl->setVar('alias', trim($server_alias_str));
47cca9 1141         } else {
7fe908 1142             $tpl->setVar('alias', '');
47cca9 1143         }
ac933e 1144
bfcdef 1145         if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0) {
7fe908 1146             $tpl->setVar('rewrite_enabled', 1);
46c683 1147         } else {
7fe908 1148             $tpl->setVar('rewrite_enabled', 0);
bfcdef 1149         }
8ab3cd 1150
T 1151         //$tpl->setLoop('redirects',$rewrite_rules);
ac933e 1152
V 1153         /**
1154          * install fast-cgi starter script and add script aliasd config
46c683 1155          * first we create the script directory if not already created, then copy over the starter script
T 1156          * settings are copied over from the server ini config for now
1157          * TODO: Create form for fastcgi configs per site.
1158          */
ac933e 1159
7fe908 1160
fb3339 1161         if ($data['new']['php'] == 'fast-cgi') {
ac933e 1162
7fe908 1163             $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1164             $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
ac933e 1165
V 1166             if (!is_dir($fastcgi_starter_path)) {
c77103 1167                 $app->system->mkdirpath($fastcgi_starter_path);
fb3339 1168                 //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
ac933e 1169
V 1170
7fe908 1171                 $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG);
46c683 1172             }
ac933e 1173
c77103 1174             //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
7fe908 1175             $app->system->chown($fastcgi_starter_path, $data['new']['system_user']);
MC 1176             $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']);
1177
46c683 1178             $fcgi_tpl = new tpl();
fb3339 1179             $fcgi_tpl->newTemplate('php-fcgi-starter.master');
8133de 1180             $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion());
7fe908 1181
62b385 1182             // Support for multiple PHP versions (FastCGI)
F 1183             if(trim($data['new']['fastcgi_php_version']) != ''){
1184                 $default_fastcgi_php = false;
7fe908 1185                 if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/';
62b385 1186             } else {
F 1187                 $default_fastcgi_php = true;
1188             }
7fe908 1189
7fddfe 1190             if($has_custom_php_ini) {
7fe908 1191                 $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1192             } else {
62b385 1193                 if($default_fastcgi_php){
7fe908 1194                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
62b385 1195                 } else {
7fe908 1196                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir));
62b385 1197                 }
7fddfe 1198             }
7fe908 1199             $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
MC 1200             $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children']));
1201             $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests']));
62b385 1202             if($default_fastcgi_php){
7fe908 1203                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin']));
62b385 1204             } else {
7fe908 1205                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable));
62b385 1206             }
7fe908 1207             $fcgi_tpl->setVar('security_level', intval($web_config['security_level']));
f63910 1208             $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain']));
ac933e 1209
fb3339 1210             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ff7075 1211             $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
ac933e 1212
6fb93d 1213             $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
7fe908 1214             $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab());
46c683 1215             unset($fcgi_tpl);
ac933e 1216
7fe908 1217             $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG);
ac933e 1218
7fe908 1219             $app->system->chmod($fcgi_starter_script, 0755);
MC 1220             $app->system->chown($fcgi_starter_script, $data['new']['system_user']);
1221             $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']);
1222
1223             $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']);
1224             $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path);
1225             $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
1226             $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']);
1227             $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']);
ac933e 1228
62e4b3 1229         } else {
F 1230             //remove the php fastgi starter script if available
b5b862 1231             $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : '');
62e4b3 1232             if ($data['old']['php'] == 'fast-cgi') {
7fe908 1233                 $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1234                 $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
1235                 if($data['old']['type'] == 'vhost') {
b5b862 1236                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
TB 1237                     if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path);
7fe908 1238                 } else {
b5b862 1239                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
7fe908 1240                 }
62e4b3 1241             }
46c683 1242         }
7fe908 1243
MC 1244
1245
274362 1246         /**
7fe908 1247          * PHP-FPM
MC 1248          */
274362 1249         // Support for multiple PHP versions
62e4b3 1250         if($data['new']['php'] == 'php-fpm'){
F 1251             if(trim($data['new']['fastcgi_php_version']) != ''){
1252                 $default_php_fpm = false;
1253                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
7fe908 1254                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1255             } else {
F 1256                 $default_php_fpm = true;
1257             }
274362 1258         } else {
62e4b3 1259             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 1260                 $default_php_fpm = false;
1261                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 1262                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1263             } else {
F 1264                 $default_php_fpm = true;
1265             }
274362 1266         }
7fe908 1267
274362 1268         if($default_php_fpm){
F 1269             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
1270         } else {
1271             $pool_dir = $custom_php_fpm_pool_dir;
1272         }
7fe908 1273         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 1274         $pool_name = 'web'.$data['new']['domain_id'];
F 1275         $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
7fe908 1276         if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
9b021b 1277         
TB 1278         // User sockets, but not with apache 2.4 as socket support is buggy in that version
1279         if($data['new']['php_fpm_use_socket'] == 'y' && $app->system->getapacheversion() < 2.4){
274362 1280             $use_tcp = 0;
F 1281             $use_socket = 1;
1282         } else {
1283             $use_tcp = 1;
1284             $use_socket = 0;
1285         }
1286         $tpl->setVar('use_tcp', $use_tcp);
1287         $tpl->setVar('use_socket', $use_socket);
1288         $fpm_socket = $socket_dir.$pool_name.'.sock';
1289         $tpl->setVar('fpm_socket', $fpm_socket);
1290         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
ac933e 1291
46c683 1292         /**
T 1293          * install cgi starter script and add script alias to config.
1294          * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
1295          * first we create the script directory if not already created, then copy over the starter script.
1296          * TODO: we have to fetch the data from the server-settings.
1297          */
fb3339 1298         if ($data['new']['php'] == 'cgi') {
J 1299             //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
46c683 1300
fb3339 1301             $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
6fb93d 1302             $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : '');
fb3339 1303             $cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
46c683 1304
7fe908 1305             $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']);
MC 1306             $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path);
46c683 1307
ac933e 1308             if (!is_dir($cgi_starter_path)) {
c77103 1309                 $app->system->mkdirpath($cgi_starter_path);
7fe908 1310                 $app->system->chown($cgi_starter_path, $data['new']['system_user']);
MC 1311                 $app->system->chgrp($cgi_starter_path, $data['new']['system_group']);
1312                 $app->system->chmod($cgi_starter_path, 0755);
46c683 1313
7fe908 1314                 $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG);
46c683 1315             }
T 1316
1317             $cgi_tpl = new tpl();
fb3339 1318             $cgi_tpl->newTemplate('php-cgi-starter.master');
8133de 1319             $cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
46c683 1320
fb3339 1321             // This works because PHP "rewrites" a symlink to the physical path
J 1322             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ac933e 1323             $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
fb3339 1324             $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
ac933e 1325
46c683 1326             // This will NOT work!
fb3339 1327             //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
7fe908 1328             $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']);
MC 1329             $cgi_tpl->setVar('security_level', $web_config['security_level']);
1330
1331             $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini);
7fddfe 1332             if($has_custom_php_ini) {
7fe908 1333                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1334             } else {
7fe908 1335                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
7fddfe 1336             }
46c683 1337
6fb93d 1338             $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
7fe908 1339             $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab());
46c683 1340             unset($cgi_tpl);
T 1341
7fe908 1342             $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG);
46c683 1343
T 1344
7fe908 1345             $app->system->chmod($cgi_starter_script, 0755);
MC 1346             $app->system->chown($cgi_starter_script, $data['new']['system_user']);
1347             $app->system->chgrp($cgi_starter_script, $data['new']['system_group']);
46c683 1348
7fe908 1349             $tpl->setVar('cgi_starter_path', $cgi_starter_path);
MC 1350             $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
46c683 1351
T 1352         }
1353
fb3339 1354         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
7ed741 1355         //* Make a backup copy of vhost file
7fe908 1356         if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~');
MC 1357
a7bdf8 1358         //* create empty vhost array
T 1359         $vhosts = array();
7fe908 1360
526b99 1361         //* Add vhost for ipv4 IP
T 1362         $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
1363         if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1364         if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1365         $vhosts[] = $tmp_vhost_arr;
1366         unset($tmp_vhost_arr);
7fe908 1367
a7bdf8 1368         //* Add vhost for ipv4 IP with SSL
481c00 1369         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1370         $domain = $data['new']['ssl_domain'];
1371         $key_file = $ssl_dir.'/'.$domain.'.key';
1372         $crt_file = $ssl_dir.'/'.$domain.'.crt';
7fe908 1373
a7bdf8 1374         if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1375             $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
T 1376             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1377             $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1378             if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){
1379                 for($i=0;$i<count($ipv4_ssl_alias_seo_redirects);$i++){
1380                     $ipv4_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1381                 }
1382             }
1383             if(count($ipv4_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects);
526b99 1384             $vhosts[] = $tmp_vhost_arr;
cc6568 1385             unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects);
7fe908 1386             $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG);
146783 1387         }
MC 1388
7fe908 1389         //* Add vhost for IPv6 IP
MC 1390         if($data['new']['ipv6_address'] != '') {
1391             if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
1392                 if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') {
1393                     $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']);
1394                     $explode_v6=explode(':', $data['new']['ipv6_address']);
1395
1396                     for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
1397                         $explode_v6[$i] = $explode_v6prefix[$i];
1398                     }
1399                     $data['new']['ipv6_address'] = implode(':', $explode_v6);
146783 1400                 }
MC 1401             }
7fe908 1402
526b99 1403             $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
T 1404             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1405             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1406             $vhosts[] = $tmp_vhost_arr;
1407             unset($tmp_vhost_arr);
7fe908 1408
a7bdf8 1409             //* Add vhost for ipv6 IP with SSL
T 1410             if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1411                 $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
T 1412                 if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1413                 $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1414                 if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){
1415                     for($i=0;$i<count($ipv6_ssl_alias_seo_redirects);$i++){
1416                         $ipv6_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1417                     }
1418                 }
1419                 if(count($ipv6_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects);
526b99 1420                 $vhosts[] = $tmp_vhost_arr;
cc6568 1421                 unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects);
7fe908 1422                 $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG);
a7bdf8 1423             }
T 1424         }
7fe908 1425
a7bdf8 1426         //* Set the vhost loop
7fe908 1427         $tpl->setLoop('vhosts', $vhosts);
MC 1428
7ed741 1429         //* Write vhost file
7fe908 1430         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1431         $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1432         unset($tpl);
ac933e 1433
V 1434         /*
1435          * maybe we have some webdav - user. If so, add them...
1436         */
fb3339 1437         $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
ac933e 1438
c6a89c 1439         //* Set the symlink to enable the vhost
T 1440         //* First we check if there is a old type of symlink and remove it
fb3339 1441         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
c77103 1442         if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink);
7fe908 1443
c6a89c 1444         //* Remove old or changed symlinks
T 1445         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1446             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1447             if(is_link($vhost_symlink)) {
c77103 1448                 $app->system->unlink($vhost_symlink);
7fe908 1449                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1450             }
T 1451             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1452             if(is_link($vhost_symlink)) {
c77103 1453                 $app->system->unlink($vhost_symlink);
7fe908 1454                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1455             }
T 1456         }
7fe908 1457
c6a89c 1458         //* New symlink
T 1459         if($data['new']['subdomain'] == '*') {
1460             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1461         } else {
1462             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1463         }
fb3339 1464         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
7fe908 1465             symlink($vhost_file, $vhost_symlink);
MC 1466             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
46c683 1467         }
ac933e 1468
46c683 1469         // remove old symlink and vhost file, if domain name of the site has changed
fb3339 1470         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
c6a89c 1471             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
T 1472             if(is_link($vhost_symlink)) {
c77103 1473                 $app->system->unlink($vhost_symlink);
7fe908 1474                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1475             }
T 1476             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1477             if(is_link($vhost_symlink)) {
c77103 1478                 $app->system->unlink($vhost_symlink);
7fe908 1479                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1480             }
8cf78b 1481             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1482             if(is_link($vhost_symlink)) {
c77103 1483                 $app->system->unlink($vhost_symlink);
7fe908 1484                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8cf78b 1485             }
fb3339 1486             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
c77103 1487             $app->system->unlink($vhost_file);
7fe908 1488             $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1489         }
ac933e 1490
46c683 1491         //* Create .htaccess and .htpasswd file for website statistics
cc6568 1492         //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
H 1493         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats');
1494         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user";
7fe908 1495         $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file);
746bf0 1496         $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755);
cc6568 1497         unset($ht_file);
H 1498         //}
ac933e 1499
bfcdef 1500         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
fb3339 1501             if(trim($data['new']['stats_password']) != '') {
J 1502                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
7fe908 1503                 $app->system->web_folder_protection($data['new']['document_root'], false);
MC 1504                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file);
1505                 $app->system->web_folder_protection($data['new']['document_root'], true);
746bf0 1506                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755);
46c683 1507                 unset($htp_file);
T 1508             }
1509         }
7fe908 1510
58c210 1511         //* Create awstats configuration
6fb93d 1512         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
7fe908 1513             $this->awstats_update($data, $web_config);
58c210 1514         }
7fe908 1515
MC 1516         $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
1517
7ed741 1518         if($web_config['check_apache_config'] == 'y') {
T 1519             //* Test if apache starts with the new configuration file
7fe908 1520             $apache_online_status_before_restart = $this->_checkTcp('localhost', 80);
MC 1521             $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
ac933e 1522
7fe908 1523             $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure
MC 1524             $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG);
1525
9f56bd 1526             // wait a few seconds, before we test the apache status again
bfcdef 1527             $apache_online_status_after_restart = false;
9f56bd 1528             sleep(2);
bfcdef 1529             for($i = 0; $i < 5; $i++) {
7fe908 1530                 $apache_online_status_after_restart = $this->_checkTcp('localhost', 80);
bfcdef 1531                 if($apache_online_status_after_restart) break;
T 1532                 sleep(1);
1533             }
7ed741 1534             //* Check if apache restarted successfully if it was online before
7fe908 1535             $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
615a0a 1536             if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) {
7fe908 1537                 $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN);
615a0a 1538                 if(is_array($retval['output']) && !empty($retval['output'])){
7fe908 1539                     $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN);
7b47c0 1540                     $app->dbmaster->datalogError(implode("\n", $retval['output']));
615a0a 1541                 } else {
T 1542                     // if no output is given, check again
1543                     $webserver_binary = '';
7b47c0 1544                     exec('which apache2ctl', $webserver_check_output, $webserver_check_retval);
615a0a 1545                     if($webserver_check_retval == 0){
7b47c0 1546                         $webserver_binary = 'apache2ctl';
615a0a 1547                     } else {
T 1548                         unset($webserver_check_output, $webserver_check_retval);
7b47c0 1549                         exec('which apache2', $webserver_check_output, $webserver_check_retval);
615a0a 1550                         if($webserver_check_retval == 0){
7b47c0 1551                             $webserver_binary = 'apache2';
615a0a 1552                         } else {
T 1553                             unset($webserver_check_output, $webserver_check_retval);
7b47c0 1554                             exec('which httpd2', $webserver_check_output, $webserver_check_retval);
615a0a 1555                             if($webserver_check_retval == 0){
7b47c0 1556                                 $webserver_binary = 'httpd2';
615a0a 1557                             } else {
T 1558                                 unset($webserver_check_output, $webserver_check_retval);
7b47c0 1559                                 exec('which httpd', $webserver_check_output, $webserver_check_retval);
615a0a 1560                                 if($webserver_check_retval == 0){
7b47c0 1561                                     $webserver_binary = 'httpd';
T 1562                                 } else {
1563                                     unset($webserver_check_output, $webserver_check_retval);
1564                                     exec('which apache', $webserver_check_output, $webserver_check_retval);
1565                                     if($webserver_check_retval == 0){
1566                                         $webserver_binary = 'apache';
1567                                     }
615a0a 1568                                 }
T 1569                             }
1570                         }
1571                     }
1572                     if($webserver_binary != ''){
1573                         exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval);
7b47c0 1574                         if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){
7fe908 1575                             $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN);
7b47c0 1576                             $app->dbmaster->datalogError(implode("\n", $tmp_output));
T 1577                         }
615a0a 1578                         unset($tmp_output, $tmp_retval);
T 1579                     }
1580                 }
7fe908 1581                 $app->system->copy($vhost_file, $vhost_file.'.err');
8cf78b 1582                 if(is_file($vhost_file.'~')) {
T 1583                     //* Copy back the last backup file
7fe908 1584                     $app->system->copy($vhost_file.'~', $vhost_file);
8cf78b 1585                 } else {
T 1586                     //* There is no backup file, so we create a empty vhost file with a warning message inside
7fe908 1587                     $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
8cf78b 1588                 }
481c00 1589                 if($this->ssl_certificate_changed === true) {
T 1590
1591                     $ssl_dir = $data['new']['document_root'].'/ssl';
1592                     $domain = $data['new']['ssl_domain'];
1593                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1594                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1595                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1596                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1597                     $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1598
481c00 1599                     //* Backup the files that might have caused the error
43b345 1600                     if(is_file($key_file)){
7fe908 1601                         $app->system->copy($key_file, $key_file.'.err');
MC 1602                         $app->system->chmod($key_file.'.err', 0400);
43b345 1603                     }
T 1604                     if(is_file($key_file2)){
7fe908 1605                         $app->system->copy($key_file2, $key_file2.'.err');
MC 1606                         $app->system->chmod($key_file2.'.err', 0400);
43b345 1607                     }
7fe908 1608                     if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err');
MC 1609                     if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err');
1610                     if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err');
1611
481c00 1612                     //* Restore the ~ backup files
7fe908 1613                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file);
MC 1614                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2);
1615                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file);
1616                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file);
1617                     if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file);
1618
1619                     $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN);
481c00 1620                 }
7fe908 1621
MC 1622                 $app->services->restartService('httpd', 'restart');
7ed741 1623             }
c82dc7 1624         } else {
7ed741 1625             //* We do not check the apache config after changes (is faster)
T 1626             if($apache_chrooted) {
7fe908 1627                 $app->services->restartServiceDelayed('httpd', 'restart');
7ed741 1628             } else {
T 1629                 // request a httpd reload when all records have been processed
7fe908 1630                 $app->services->restartServiceDelayed('httpd', 'reload');
7ed741 1631             }
c82dc7 1632         }
7fe908 1633
MC 1634         //* The vhost is written and apache has been restarted, so we
481c00 1635         // can reset the ssl changed var to false and cleanup some files
T 1636         $this->ssl_certificate_changed = false;
7fe908 1637
481c00 1638         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1639         $domain = $data['new']['ssl_domain'];
1640         $key_file = $ssl_dir.'/'.$domain.'.key.org';
1641         $key_file2 = $ssl_dir.'/'.$domain.'.key';
1642         $csr_file = $ssl_dir.'/'.$domain.'.csr';
1643         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1644         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1645
c77103 1646         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
T 1647         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
1648         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
1649         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
1650         if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
7fe908 1651
7ed741 1652         // Remove the backup copy of the config file.
c77103 1653         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
ac933e 1654
da1a7c 1655         //* Unset action to clean it for next processed vhost.
T 1656         $this->action = '';
46c683 1657     }
ac933e 1658
7fe908 1659     function delete($event_name, $data) {
46c683 1660         global $app, $conf;
ac933e 1661
46c683 1662         // load the server configuration options
fb3339 1663         $app->uses('getconf');
c09f04 1664         $app->uses('system');
fb3339 1665         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
cc6568 1666         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
7fe908 1667
MC 1668         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 1669
2bbc4c 1670         //* Check if this is a chrooted setup
4b72c5 1671         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 1672             $apache_chrooted = true;
T 1673         } else {
1674             $apache_chrooted = false;
1675         }
7fe908 1676
fea5e7 1677         //* Remove the mounts
T 1678         $log_folder = 'log';
7fe908 1679         $web_folder = '';
MC 1680         if($data['old']['type'] == 'vhostsubdomain') {
1681             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
526b99 1682             if($tmp['domain'] != ''){
T 1683                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
1684             } else {
1685                 // get log folder from /etc/fstab
1686                 /*
1687                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
1688                 $bind_mount_lines = explode("\n", $bind_mounts);
1689                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
1690                     foreach($bind_mount_lines as $bind_mount_line){
1691                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
1692                         $bind_mount_parts = explode(' ', $bind_mount_line);
1693                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
1694                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
1695                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
1696                             }
1697                         }
1698                     }
1699                 }
1700                 */
1701                 // we are deleting the parent domain, so we can delete everything in the log directory
1702                 $subdomain_hosts = array();
7fe908 1703                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..'));
526b99 1704                 if(is_array($files) && !empty($files)){
T 1705                     foreach($files as $file){
1706                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
1707                             $subdomain_hosts[] = $file;
1708                         }
1709                     }
1710                 }
1711             }
7fe908 1712             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
526b99 1713                 $log_folders = array();
T 1714                 foreach($subdomain_hosts as $subdomain_host){
1715                     $log_folders[] = $log_folder.'/'.$subdomain_host;
1716                 }
1717             } else {
1718                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
1719                 $log_folder .= '/' . $subdomain_host;
1720             }
1721             $web_folder = $data['old']['web_folder'];
7fe908 1722             unset($tmp);
526b99 1723             unset($subdomain_hosts);
3cde19 1724         }
7fe908 1725
526b99 1726         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){
T 1727             if(is_array($log_folders) && !empty($log_folders)){
1728                 foreach($log_folders as $log_folder){
cc6568 1729                     //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1730                     exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1731                 }
T 1732             } else {
cc6568 1733                 //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1734                 exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1735             }
T 1736         }
7fe908 1737
fea5e7 1738         //* remove mountpoint from fstab
526b99 1739         if(is_array($log_folders) && !empty($log_folders)){
T 1740             foreach($log_folders as $log_folder){
1741                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1742                 $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1743             }
T 1744         } else {
1745             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1746             $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1747         }
T 1748         unset($log_folders);
ac933e 1749
6fb93d 1750         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) {
46c683 1751             //* This is a alias domain or subdomain, so we have to update the website instead
fb3339 1752             $parent_domain_id = intval($data['old']['parent_domain_id']);
J 1753             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
1754             $data['new'] = $tmp;
1755             $data['old'] = $tmp;
46c683 1756             $this->action = 'update';
T 1757             // just run the update function
7fe908 1758             $this->update($event_name, $data);
ac933e 1759
46c683 1760         } else {
T 1761             //* This is a website
1762             // Deleting the vhost file, symlink and the data directory
fb3339 1763             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
7fe908 1764
8ab3cd 1765             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1766             if(is_link($vhost_symlink)){
c77103 1767                 $app->system->unlink($vhost_symlink);
7fe908 1768                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1769             }
T 1770             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1771             if(is_link($vhost_symlink)){
c77103 1772                 $app->system->unlink($vhost_symlink);
7fe908 1773                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1774             }
T 1775             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1776             if(is_link($vhost_symlink)){
c77103 1777                 $app->system->unlink($vhost_symlink);
7fe908 1778                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1779             }
7fe908 1780
c77103 1781             $app->system->unlink($vhost_file);
7fe908 1782             $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
ac933e 1783
7fe908 1784             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
MC 1785                 $docroot = escapeshellcmd($data['old']['document_root']);
1786                 if($docroot != '' && !stristr($docroot, '..')) {
1787                     if($data['old']['type'] == 'vhost') {
1788                         // this is a vhost - we delete everything in here.
1789                         exec('rm -rf '.$docroot);
1790                     } elseif(!stristr($data['old']['web_folder'], '..')) {
1791                         // this is a vhost subdomain
1792                         // IMPORTANT: do some folder checks before we delete this!
1793                         $do_delete = true;
1794                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
1795                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
1796                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
46c683 1797
7fe908 1798                         $path_elements = explode('/', $delete_folder);
46c683 1799
7fe908 1800                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
MC 1801                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
1802                             // we use strict check as otherwise directories named '0' may not be deleted
1803                             $do_delete = false;
1804                         } else {
1805                             // read all vhost subdomains with same parent domain
1806                             $used_paths = array();
1807                             $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id']));
1808                             foreach($tmp as $tmprec) {
1809                                 // we normalize the folder entries because we need to compare them
1810                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
1811                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
1812                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
ac933e 1813
7fe908 1814                                 // add this path and it's parent paths to used_paths array
MC 1815                                 while(strpos($tmp_folder, '/') !== false) {
1816                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1817                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
1818                                 }
1819                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1820                             }
1821                             unset($tmp);
1822
1823                             // loop and check if the path is still used and stop at first used one
1824                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
1825                             $do_delete = false;
1826                             while(count($path_elements) > 0) {
1827                                 $tmp_folder = implode('/', $path_elements);
1828                                 if(in_array($tmp_folder, $used_paths) == true) break;
1829
1830                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
1831                                 $delete_folder = $tmp_folder;
1832                                 $do_delete = true;
1833                                 array_pop($path_elements);
1834                             }
1835                             unset($tmp_folder);
1836                             unset($used_paths);
1837                         }
1838
1839                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
1840
1841                         unset($delete_folder);
1842                         unset($path_elements);
1843                     }
1844                 }
1845
1846                 //remove the php fastgi starter script if available
1847                 if ($data['old']['php'] == 'fast-cgi') {
1848                     $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
1849                     if($data['old']['type'] == 'vhost') {
1850                         if (is_dir($fastcgi_starter_path)) {
1851                             exec('rm -rf '.$fastcgi_starter_path);
1852                         }
1853                     } else {
1854                         $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
1855                         if (file_exists($fcgi_starter_script)) {
1856                             exec('rm -f '.$fcgi_starter_script);
1857                         }
1858                     }
1859                 }
1860
1861                 // remove PHP-FPM pool
1862                 if ($data['old']['php'] == 'php-fpm') {
1863                     $this->php_fpm_pool_delete($data, $web_config);
1864                 }
1865
1866                 //remove the php cgi starter script if available
1867                 if ($data['old']['php'] == 'cgi') {
1868                     // TODO: fetch the date from the server-settings
1869                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
1870
1871                     $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']);
1872                     if($data['old']['type'] == 'vhost') {
1873                         if (is_dir($cgi_starter_path)) {
1874                             exec('rm -rf '.$cgi_starter_path);
1875                         }
1876                     } else {
1877                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
1878                         if (file_exists($cgi_starter_script)) {
1879                             exec('rm -f '.$cgi_starter_script);
1880                         }
1881                     }
1882                 }
1883
1884                 $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
1885
1886                 // Delete the symlinks for the sites
1887                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
1888                 $client_id = intval($client['client_id']);
1889                 unset($client);
1890                 $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
1891                 if(is_array($tmp_symlinks_array)) {
1892                     foreach($tmp_symlinks_array as $tmp_symlink) {
1893                         $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
1894                         $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
1895                         // Remove trailing slash
1896                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
1897                         // delete the symlink
1898                         if(is_link($tmp_symlink)) {
1899                             $app->system->unlink($tmp_symlink);
1900                             $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG);
1901                         }
1902                     }
1903                 }
1904                 // end removing symlinks
3cde19 1905             }
7fe908 1906
MC 1907             // Delete the log file directory
1908             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
1909             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir);
1910             $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG);
1911
1912             if($data['old']['type'] == 'vhost') {
1913                 //delete the web user
1914                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel';
1915                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
1916                 exec($command);
1917                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
1918
1919             }
1920
1921             //* Remove the awstats configuration file
1922             if($data['old']['stats_type'] == 'awstats') {
1923                 $this->awstats_delete($data, $web_config);
1924             }
1925
1926             if($data['old']['type'] == 'vhostsubdomain') {
1927                 $app->system->web_folder_protection($parent_web_document_root, true);
1928             }
1929
8ab3cd 1930             if($apache_chrooted) {
7fe908 1931                 $app->services->restartServiceDelayed('httpd', 'restart');
8ab3cd 1932             } else {
T 1933                 // request a httpd reload when all records have been processed
7fe908 1934                 $app->services->restartServiceDelayed('httpd', 'reload');
58c210 1935             }
ac933e 1936
46c683 1937         }
7fe908 1938         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true);
46c683 1939     }
ac933e 1940
46c683 1941     //* This function is called when a IP on the server is inserted, updated or deleted
7fe908 1942     function server_ip($event_name, $data) {
46c683 1943         global $app, $conf;
ac933e 1944
46c683 1945         // load the server configuration options
fb3339 1946         $app->uses('getconf');
J 1947         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 1948
46c683 1949         $app->load('tpl');
ac933e 1950
46c683 1951         $tpl = new tpl();
fb3339 1952         $tpl->newTemplate('apache_ispconfig.conf.master');
8133de 1953         $tpl->setVar('apache_version', $app->system->getapacheversion());
fb3339 1954         $records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
7fe908 1955
a2156e 1956         $records_out= array();
T 1957         if(is_array($records)) {
1958             foreach($records as $rec) {
1959                 if($rec['ip_type'] == 'IPv6') {
1960                     $ip_address = '['.$rec['ip_address'].']';
1961                 } else {
1962                     $ip_address = $rec['ip_address'];
1963                 }
7fe908 1964                 $ports = explode(',', $rec['virtualhost_port']);
a2156e 1965                 if(is_array($ports)) {
T 1966                     foreach($ports as $port) {
1967                         $port = intval($port);
1968                         if($port > 0 && $port < 65536 && $ip_address != '') {
1969                             $records_out[] = array('ip_address' => $ip_address, 'port' => $port);
1970                         }
1971                     }
1972                 }
1973             }
1974         }
7fe908 1975
MC 1976
a2156e 1977         if(count($records_out) > 0) {
7fe908 1978             $tpl->setLoop('ip_adresses', $records_out);
46c683 1979         }
ac933e 1980
fb3339 1981         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
7fe908 1982         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1983         $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1984         unset($tpl);
ac933e 1985
46c683 1986     }
7fe908 1987
524077 1988     //* Create or update the .htaccess folder protection
7fe908 1989     function web_folder_user($event_name, $data) {
524077 1990         global $app, $conf;
c69439 1991
524077 1992         $app->uses('system');
7fe908 1993
524077 1994         if($event_name == 'web_folder_user_delete') {
T 1995             $folder_id = $data['old']['web_folder_id'];
1996         } else {
1997             $folder_id = $data['new']['web_folder_id'];
1998         }
7fe908 1999
524077 2000         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
T 2001         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 2002
524077 2003         if(!is_array($folder) or !is_array($website)) {
7fe908 2004             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2005             return false;
T 2006         }
7fe908 2007
MC 2008         $web_folder = 'web';
2009         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2010
524077 2011         //* Get the folder path.
7fe908 2012         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2013         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2014         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2015         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2016
524077 2017         //* Check if the resulting path is inside the docroot
7fe908 2018         if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) {
MC 2019             $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
524077 2020             return false;
T 2021         }
7fe908 2022
524077 2023         //* Create the folder path, if it does not exist
8cf78b 2024         if(!is_dir($folder_path)) {
c77103 2025             $app->system->mkdirpath($folder_path);
7fe908 2026             $app->system->chown($folder_path, $website['system_user']);
MC 2027             $app->system->chgrp($folder_path, $website['system_group']);
8cf78b 2028         }
7fe908 2029
524077 2030         //* Create empty .htpasswd file, if it does not exist
T 2031         if(!is_file($folder_path.'.htpasswd')) {
4bd960 2032             $app->system->touch($folder_path.'.htpasswd');
51910d 2033             $app->system->chmod($folder_path.'.htpasswd', 0751);
7fe908 2034             $app->system->chown($folder_path.'.htpasswd', $website['system_user']);
MC 2035             $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
2036             $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2037         }
7fe908 2038
8ab3cd 2039         /*
T 2040         $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
2041         $htpasswd_content = '';
2042         if(is_array($auth_users) && !empty($auth_users)){
2043             foreach($auth_users as $auth_user){
2044                 $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
2045             }
2046         }
2047         $htpasswd_content = trim($htpasswd_content);
2048         @file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
2049         $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
2050         */
7fe908 2051
8ab3cd 2052         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
7fe908 2053             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2054             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
c69439 2055         }
7fe908 2056
524077 2057         //* Add or remove the user from .htpasswd file
T 2058         if($event_name == 'web_folder_user_delete') {
7fe908 2059             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2060             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
524077 2061         } else {
c69439 2062             if($data['new']['active'] == 'y') {
7fe908 2063                 $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1);
MC 2064                 $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG);
c69439 2065             }
524077 2066         }
7fe908 2067
MC 2068
524077 2069         //* Create the .htaccess file
8ab3cd 2070         //if(!is_file($folder_path.'.htaccess')) {
7fe908 2071         $begin_marker = '### ISPConfig folder protection begin ###';
MC 2072         $end_marker = "### ISPConfig folder protection end ###\n\n";
2073         $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2074
2075         if(file_exists($folder_path.'.htaccess')) {
2076             $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
2077
2078             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2079                 $ht_file = str_replace($matches[0], $ht_file, $old_content);
2080             } else {
2081                 $ht_file .= $old_content;
2082             }
2083         }
2084         unset($old_content);
2085
2086         $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
51910d 2087         $app->system->chmod($folder_path.'.htaccess', 0751);
7fe908 2088         $app->system->chown($folder_path.'.htaccess', $website['system_user']);
MC 2089         $app->system->chgrp($folder_path.'.htaccess', $website['system_group']);
2090         $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
8ab3cd 2091         //}
7fe908 2092
524077 2093     }
7fe908 2094
524077 2095     //* Remove .htaccess and .htpasswd file, when folder protection is removed
7fe908 2096     function web_folder_delete($event_name, $data) {
524077 2097         global $app, $conf;
7fe908 2098
524077 2099         $folder_id = $data['old']['web_folder_id'];
7fe908 2100
8ab3cd 2101         $folder = $data['old'];
524077 2102         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 2103
524077 2104         if(!is_array($folder) or !is_array($website)) {
7fe908 2105             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2106             return false;
T 2107         }
7fe908 2108
MC 2109         $web_folder = 'web';
2110         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2111
524077 2112         //* Get the folder path.
7fe908 2113         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2114         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2115         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2116         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2117
524077 2118         //* Check if the resulting path is inside the docroot
7fe908 2119         if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2120             $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG);
524077 2121             return false;
T 2122         }
7fe908 2123
524077 2124         //* Remove .htpasswd file
T 2125         if(is_file($folder_path.'.htpasswd')) {
c77103 2126             $app->system->unlink($folder_path.'.htpasswd');
7fe908 2127             $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2128         }
7fe908 2129
524077 2130         //* Remove .htaccess file
T 2131         if(is_file($folder_path.'.htaccess')) {
7fe908 2132             $begin_marker = '### ISPConfig folder protection begin ###';
MC 2133             $end_marker = "### ISPConfig folder protection end ###\n\n";
2134
2135             $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
2136
2137             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2138                 $ht_file = str_replace($matches[0], '', $ht_file);
2139             } else {
2140                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2141             }
2142
2143             if(trim($ht_file) == '') {
2144                 $app->system->unlink($folder_path.'.htaccess');
2145                 $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2146             } else {
2147                 $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
2148                 $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2149             }
524077 2150         }
2023a7 2151     }
7fe908 2152
2023a7 2153     //* Update folder protection, when path has been changed
7fe908 2154     function web_folder_update($event_name, $data) {
2023a7 2155         global $app, $conf;
7fe908 2156
2023a7 2157         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
7fe908 2158
2023a7 2159         if(!is_array($website)) {
7fe908 2160             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
2023a7 2161             return false;
T 2162         }
7fe908 2163
MC 2164         $web_folder = 'web';
2165         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2166
2023a7 2167         //* Get the folder path.
7fe908 2168         if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
MC 2169         if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1);
6fb93d 2170         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
7fe908 2171         if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/';
MC 2172
2173         if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1);
2174         if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1);
6fb93d 2175         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
7fe908 2176         if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/';
MC 2177
2023a7 2178         //* Check if the resulting path is inside the docroot
7fe908 2179         if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) {
MC 2180             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2181             return false;
T 2182         }
7fe908 2183         if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) {
MC 2184             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2185             return false;
T 2186         }
7fe908 2187
2023a7 2188         //* Check if the resulting path is inside the docroot
7fe908 2189         if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2190             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2191             return false;
T 2192         }
7fe908 2193         if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2194             $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2195             return false;
T 2196         }
7fe908 2197
2023a7 2198         //* Create the folder path, if it does not exist
c77103 2199         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
7fe908 2200
MC 2201         $begin_marker = '### ISPConfig folder protection begin ###';
2202         $end_marker = "### ISPConfig folder protection end ###\n\n";
2203
2023a7 2204         if($data['old']['path'] != $data['new']['path']) {
T 2205
7fe908 2206
2023a7 2207             //* move .htpasswd file
T 2208             if(is_file($old_folder_path.'.htpasswd')) {
7fe908 2209                 $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd');
MC 2210                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2023a7 2211             }
7fe908 2212
8ab3cd 2213             //* delete old .htaccess file
2023a7 2214             if(is_file($old_folder_path.'.htaccess')) {
7fe908 2215                 $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
MC 2216
2217                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2218                     $ht_file = str_replace($matches[0], '', $ht_file);
2219                 } else {
2220                     $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2221                 }
2222
2223                 if(trim($ht_file) == '') {
2224                     $app->system->unlink($old_folder_path.'.htaccess');
2225                     $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2226                 } else {
2227                     $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
2228                     $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2229                 }
2023a7 2230             }
7fe908 2231
2023a7 2232         }
7fe908 2233
2023a7 2234         //* Create the .htaccess file
8ab3cd 2235         if($data['new']['active'] == 'y') {
7fe908 2236             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
MC 2237
2238             if(file_exists($new_folder_path.'.htaccess')) {
2239                 $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
2240
2241                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2242                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2243                 } else {
2244                     $ht_file .= $old_content;
2245                 }
2246             }
2247
2248             $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
51910d 2249             $app->system->chmod($new_folder_path.'.htaccess', 0751);
7fe908 2250             $app->system->chown($new_folder_path.'.htaccess', $website['system_user']);
MC 2251             $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']);
2252             $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
8433d0 2253             
TB 2254             //* Create empty .htpasswd file, if it does not exist
2255             if(!is_file($folder_path.'.htpasswd')) {
2256                 $app->system->touch($new_folder_path.'.htpasswd');
51910d 2257                 $app->system->chmod($new_folder_path.'.htpasswd', 0751);
8433d0 2258                 $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']);
TB 2259                 $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']);
2260                 $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2261             }
2023a7 2262         }
7fe908 2263
2023a7 2264         //* Remove .htaccess file
T 2265         if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
7fe908 2266             $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
MC 2267
2268             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2269                 $ht_file = str_replace($matches[0], '', $ht_file);
2270             } else {
2271                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2272             }
2273
2274             if(trim($ht_file) == '') {
2275                 $app->system->unlink($new_folder_path.'.htaccess');
2276                 $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2277             } else {
2278                 $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
2279                 $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2280             }
2023a7 2281         }
7fe908 2282
MC 2283
524077 2284     }
7fe908 2285
MC 2286     public function ftp_user_delete($event_name, $data) {
26c0fc 2287         global $app, $conf;
7fe908 2288
26c0fc 2289         $ftpquota_file = $data['old']['dir'].'/.ftpquota';
c77103 2290         if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file);
7fe908 2291
26c0fc 2292     }
7fe908 2293
MC 2294
ac933e 2295
V 2296     /**
2297      * This function is called when a Webdav-User is inserted, updated or deleted.
2298      *
2299      * @author Oliver Vogel
2300      * @param string $event_name
2301      * @param array $data
2302      */
7fe908 2303     public function webdav($event_name, $data) {
ac933e 2304         global $app, $conf;
7fe908 2305
52a04e 2306         /*
T 2307          * load the server configuration options
2308         */
fb3339 2309         $app->uses('getconf');
J 2310         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2311
V 2312         if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
2313
2314             /*
2315              * Get additional informations
2316             */
fb3339 2317             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
ac933e 2318             $documentRoot = $sitedata['document_root'];
V 2319             $domain = $sitedata['domain'];
ca14fe 2320             $user = $sitedata['system_user'];
V 2321             $group = $sitedata['system_group'];
b67344 2322             $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
ac933e 2323
V 2324             /* Check if this is a chrooted setup */
2325             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2326                 $apache_chrooted = true;
7fe908 2327                 $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
ac933e 2328             } else {
V 2329                 $apache_chrooted = false;
2330             }
7fe908 2331
b67344 2332             //* We dont want to have relative paths here
7fe908 2333             if(stristr($webdav_user_dir, '..')  || stristr($webdav_user_dir, './')) {
MC 2334                 $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot, LOGLEVEL_WARN);
b67344 2335                 return false;
T 2336             }
7fe908 2337
b67344 2338             //* Check if the resulting path exists if yes, if it is inside the docroot
7fe908 2339             if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir), 0, strlen($documentRoot)) != $documentRoot) {
MC 2340                 $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot, LOGLEVEL_WARN);
b67344 2341                 return false;
T 2342             }
ac933e 2343
V 2344             /*
2345              * First the webdav-root - folder has to exist
2346             */
b67344 2347             if(!is_dir($webdav_user_dir)) {
7fe908 2348                 $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.', LOGLEVEL_DEBUG);
c77103 2349                 $app->system->mkdirpath($webdav_user_dir);
ac933e 2350             }
V 2351
2352             /*
ca14fe 2353              * The webdav - Root needs the group/user as owner and the apache as read and write
ac933e 2354             */
c77103 2355             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
T 2356             //$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
7fe908 2357             $app->system->chown($documentRoot . '/webdav', $user);
MC 2358             $app->system->chgrp($documentRoot . '/webdav', $group);
2359             $app->system->chmod($documentRoot . '/webdav', 0770);
ac933e 2360
V 2361             /*
ca14fe 2362              * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
V 2363              * pwd-files are owned by root)
ac933e 2364             */
c77103 2365             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
T 2366             //$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
7fe908 2367             $app->system->chown($webdav_user_dir, $user);
MC 2368             $app->system->chgrp($webdav_user_dir, $group);
2369             $app->system->chmod($webdav_user_dir, 0770);
ca14fe 2370
V 2371             /*
2372              * if the user is active, we have to write/update the password - file
2373              * if the user is inactive, we have to inactivate the user by removing the user from the file
2374             */
2375             if ($data['new']['active'] == 'y') {
b67344 2376                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
ca14fe 2377             }
V 2378             else {
2379                 /* empty pwd removes the user! */
b67344 2380                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
ca14fe 2381             }
ac933e 2382
V 2383             /*
2384              * Next step, patch the vhost - file
2385             */
fb3339 2386             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
ac933e 2387             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
ca14fe 2388
ac933e 2389             /*
V 2390              * Last, restart apache
2391             */
2392             if($apache_chrooted) {
7fe908 2393                 $app->services->restartServiceDelayed('httpd', 'restart');
ac933e 2394             } else {
V 2395                 // request a httpd reload when all records have been processed
7fe908 2396                 $app->services->restartServiceDelayed('httpd', 'reload');
ac933e 2397             }
V 2398
2399         }
2400
2401         if ($event_name == 'webdav_user_delete') {
2402             /*
2403              * Get additional informations
2404             */
fb3339 2405             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
ac933e 2406             $documentRoot = $sitedata['document_root'];
52a04e 2407             $domain = $sitedata['domain'];
ac933e 2408
V 2409             /*
2410              * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
2411              * So the only thing, we have to do, is to delete the user from the password-file
ca14fe 2412             */
ac933e 2413             $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
7fe908 2414
52a04e 2415             /*
T 2416              * Next step, patch the vhost - file
2417             */
fb3339 2418             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
52a04e 2419             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
7fe908 2420
52a04e 2421             /*
T 2422              * Last, restart apache
2423             */
2424             if($apache_chrooted) {
7fe908 2425                 $app->services->restartServiceDelayed('httpd', 'restart');
52a04e 2426             } else {
T 2427                 // request a httpd reload when all records have been processed
7fe908 2428                 $app->services->restartServiceDelayed('httpd', 'reload');
52a04e 2429             }
ac933e 2430         }
V 2431     }
2432
2433
2434     /**
2435      * This function writes the htdigest - files used by webdav and digest
ca14fe 2436      * more info: see http://riceball.com/d/node/424
ac933e 2437      * @author Oliver Vogel
V 2438      * @param string $filename The name of the digest-file
2439      * @param string $username The name of the webdav-user
2440      * @param string $authname The name of the realm
ca14fe 2441      * @param string $pwd      The password-hash of the user
ac933e 2442      */
ca14fe 2443     private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
4bd960 2444         global $app;
7fe908 2445
ac933e 2446         $changed = false;
c77103 2447         if(is_file($filename) && !is_link($filename)) {
0ff3f1 2448             $in = fopen($filename, 'r');
T 2449             $output = '';
2450             /*
2451             * read line by line and search for the username and authname
2452             */
2453             while (preg_match("/:/", $line = fgets($in))) {
2454                 $line = rtrim($line);
2455                 $tmp = explode(':', $line);
2456                 if ($tmp[0] == $username && $tmp[1] == $authname) {
2457                     /*
2458                     * found the user. delete or change it?
2459                     */
2460                     if ($pwdhash != '') {
2461                         $output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
7fe908 2462                     }
0ff3f1 2463                     $changed = true;
T 2464                 }
2465                 else {
2466                     $output .= $line . "\n";
2467                 }
ac933e 2468             }
0ff3f1 2469             fclose($in);
ac933e 2470         }
V 2471         /*
2472          * if we didn't change anything, we have to add the new user at the end of the file
2473         */
2474         if (!$changed) {
f17dab 2475             $output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
ac933e 2476         }
7fe908 2477
ac933e 2478
V 2479         /*
2480          * Now lets write the new file
2481         */
52a04e 2482         if(trim($output) == '') {
c77103 2483             $app->system->unlink($filename);
52a04e 2484         } else {
c77103 2485             $app->system->file_put_contents($filename, $output);
52a04e 2486         }
ac933e 2487     }
V 2488
2489     /**
2490      * This function patches the vhost-file and adds all webdav - user.
2491      * This function is written, because the creation of the vhost - file is sophisticated and
2492      * i don't want to make it more "heavy" by also adding this code too...
2493      * @author Oliver Vogel
2494      * @param string $fileName The Name of the .vhost-File (path included)
2495      * @param string $webdavRoot The root of the webdav-folder
2496      */
2497     private function _patchVhostWebdav($fileName, $webdavRoot) {
c77103 2498         global $app;
ac933e 2499         $in = fopen($fileName, 'r');
V 2500         $output = '';
2501         $inWebdavSection = false;
2502
2503         /*
2504          * read line by line and search for the username and authname
2505         */
2506         while ($line = fgets($in)) {
2507             /*
2508              *  is the "replace-comment" found...
2509             */
2510             if (trim($line) == '# WEBDAV BEGIN') {
2511                 /*
2512                  * The begin of the webdav - section is found, so ignore all lines til the end  is found
2513                 */
2514                 $inWebdavSection = true;
2515
2516                 $output .= "      # WEBDAV BEGIN\n";
2517
2518                 /*
2519                  * add all the webdav-dirs to the webdav-section
2520                 */
fb3a98 2521                 $files = @scandir($webdavRoot);
T 2522                 if(is_array($files)) {
7fe908 2523                     foreach($files as $file) {
MC 2524                         if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) {
2525                             /*
ac933e 2526                          * found a htdigest - file, so add it to webdav
V 2527                         */
7fe908 2528                             $fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
MC 2529                             $output .= "\n";
2530                             // $output .= "      Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2531                             // $output .= "      <Location /" . $fn . ">\n";
2532                             $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2533                             $output .= "      <Location /webdav/" . $fn . ">\n";
2534                             $output .= "        DAV On\n";
2535                             $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
2536                             $output .= "        AuthType Digest\n";
2537                             $output .= "        AuthName \"" . $fn . "\"\n";
2538                             $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
2539                             $output .= "        Require valid-user \n";
2540                             $output .= "        Options +Indexes \n";
2541                             $output .= "        Order allow,deny \n";
2542                             $output .= "        Allow from all \n";
2543                             $output .= "      </Location> \n";
2544                         }
ac933e 2545                     }
fb3a98 2546                 }
ac933e 2547             }
V 2548             /*
2549              *  is the "replace-comment-end" found...
2550             */
2551             if (trim($line) == '# WEBDAV END') {
2552                 /*
2553                  * The end of the webdav - section is found, so stop ignoring
2554                 */
2555                 $inWebdavSection = false;
2556             }
2557
2558             /*
2559              * Write the line to the output, if it is not in the section
2560             */
2561             if (!$inWebdavSection) {
2562                 $output .= $line;
2563             }
2564         }
2565         fclose($in);
2566
2567         /*
2568          * Now lets write the new file
2569         */
c77103 2570         $app->system->file_put_contents($fileName, $output);
ac933e 2571
V 2572     }
7fe908 2573
58c210 2574     //* Update the awstats configuration file
7fe908 2575     private function awstats_update ($data, $web_config) {
58c210 2576         global $app;
7fe908 2577
MC 2578         $web_folder = $data['new']['web_folder'];
2579         if($data['new']['type'] == 'vhost') $web_folder = 'web';
2a6eac 2580         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2581
6fb93d 2582         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
fb3339 2583         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
J 2584             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2585                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
58c210 2586             }
7fe908 2587
58c210 2588             $content = '';
2a6eac 2589             $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n";
fb3339 2590             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
J 2591             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2592             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
7fe908 2593
MC 2594             $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content);
2595             $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2596         }
7fe908 2597
6fb93d 2598         if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html");
a464e1 2599         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
7fe908 2600             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2601         } else {
7fe908 2602             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2603         }
58c210 2604     }
7fe908 2605
58c210 2606     //* Delete the awstats configuration file
7fe908 2607     private function awstats_delete ($data, $web_config) {
58c210 2608         global $app;
7fe908 2609
58c210 2610         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2611
fb3339 2612         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2613             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
7fe908 2614             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2615         }
T 2616     }
7fe908 2617
274362 2618     //* Update the PHP-FPM pool configuration file
7fe908 2619     private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
274362 2620         global $app, $conf;
F 2621         //$reload = false;
7fe908 2622
62e4b3 2623         if($data['new']['php'] == 'php-fpm'){
F 2624             if(trim($data['new']['fastcgi_php_version']) != ''){
2625                 $default_php_fpm = false;
2626                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
7fe908 2627                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2628             } else {
F 2629                 $default_php_fpm = true;
2630             }
274362 2631         } else {
62e4b3 2632             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 2633                 $default_php_fpm = false;
2634                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 2635                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2636             } else {
F 2637                 $default_php_fpm = true;
2638             }
274362 2639         }
7fe908 2640
274362 2641         $app->uses("getconf");
F 2642         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2643
274362 2644         if($data['new']['php'] != 'php-fpm'){
F 2645             if(@is_file($pool_dir.$pool_name.'.conf')){
c77103 2646                 $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 2647                 //$reload = true;
F 2648             }
2649             if($data['old']['php'] == 'php-fpm'){
2650                 if(!$default_php_fpm){
7fe908 2651                     $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2652                 } else {
7fe908 2653                     $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2654                 }
F 2655             }
2656             //if($reload == true) $app->services->restartService('php-fpm','reload');
2657             return;
2658         }
7fe908 2659
274362 2660         $app->load('tpl');
F 2661         $tpl = new tpl();
2662         $tpl->newTemplate('php_fpm_pool.conf.master');
8133de 2663         $tpl->setVar('apache_version', $app->system->getapacheversion());
MC 2664         
274362 2665         if($data['new']['php_fpm_use_socket'] == 'y'){
F 2666             $use_tcp = 0;
2667             $use_socket = 1;
c77103 2668             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
274362 2669         } else {
F 2670             $use_tcp = 1;
2671             $use_socket = 0;
2672         }
2673         $tpl->setVar('use_tcp', $use_tcp);
2674         $tpl->setVar('use_socket', $use_socket);
7fe908 2675
274362 2676         $fpm_socket = $socket_dir.$pool_name.'.sock';
F 2677         $tpl->setVar('fpm_socket', $fpm_socket);
b491ad 2678         $tpl->setVar('fpm_listen_mode', '0660');
7fe908 2679
274362 2680         $tpl->setVar('fpm_pool', $pool_name);
F 2681         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
2682         $tpl->setVar('fpm_user', $data['new']['system_user']);
2683         $tpl->setVar('fpm_group', $data['new']['system_group']);
dd7ce4 2684         $tpl->setVar('pm', $data['new']['pm']);
274362 2685         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
F 2686         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
2687         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
2688         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
dd7ce4 2689         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
F 2690         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
274362 2691         $tpl->setVar('document_root', $data['new']['document_root']);
7fe908 2692         $tpl->setVar('security_level', $web_config['security_level']);
f63910 2693         $tpl->setVar('domain', $data['new']['domain']);
274362 2694         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
F 2695         $tpl->setVar('php_open_basedir', $php_open_basedir);
2696         if($php_open_basedir != ''){
2697             $tpl->setVar('enable_php_open_basedir', '');
2698         } else {
2699             $tpl->setVar('enable_php_open_basedir', ';');
2700         }
7fe908 2701
274362 2702         // Custom php.ini settings
F 2703         $final_php_ini_settings = array();
2704         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
2705         if($custom_php_ini_settings != ''){
2706             // Make sure we only have Unix linebreaks
2707             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2708             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2709             $ini_settings = explode("\n", $custom_php_ini_settings);
2710             if(is_array($ini_settings) && !empty($ini_settings)){
2711                 foreach($ini_settings as $ini_setting){
254a4a 2712                     $ini_setting = trim($ini_setting);
7fe908 2713                     if(substr($ini_setting, 0, 1) == ';') continue;
MC 2714                     if(substr($ini_setting, 0, 1) == '#') continue;
2715                     if(substr($ini_setting, 0, 2) == '//') continue;
03cc01 2716                     list($key, $value) = explode('=', $ini_setting, 2);
1d6097 2717                     $value = trim($value);
FT 2718                     if($value != ''){
254a4a 2719                         $key = trim($key);
F 2720                         switch (strtolower($value)) {
7fe908 2721                         case '0':
MC 2722                             // PHP-FPM might complain about invalid boolean value if you use 0
2723                             $value = 'off';
2724                         case '1':
2725                         case 'on':
2726                         case 'off':
2727                         case 'true':
2728                         case 'false':
2729                         case 'yes':
2730                         case 'no':
2731                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
2732                             break;
2733                         default:
2734                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
274362 2735                         }
254a4a 2736                     }
274362 2737                 }
F 2738             }
2739         }
7fe908 2740
274362 2741         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
7fe908 2742
MC 2743         $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
2744         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
274362 2745         unset($tpl);
7fe908 2746
274362 2747         // delete pool in all other PHP versions
F 2748         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2749         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2750         if($default_pool_dir != $pool_dir){
F 2751             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2752                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2753                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2754                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2755             }
F 2756         }
2757         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]);
2758         if(is_array($php_versions) && !empty($php_versions)){
2759             foreach($php_versions as $php_version){
7fe908 2760                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2761                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2762                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2763                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2764                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2765                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2766                     }
F 2767                 }
2768             }
2769         }
2770         // Reload current PHP-FPM after all others
2771         sleep(1);
2772         if(!$default_php_fpm){
7fe908 2773             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2774         } else {
7fe908 2775             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2776         }
7fe908 2777
274362 2778         //$reload = true;
F 2779
2780         //if($reload == true) $app->services->restartService('php-fpm','reload');
2781     }
7fe908 2782
274362 2783     //* Delete the PHP-FPM pool configuration file
7fe908 2784     private function php_fpm_pool_delete ($data, $web_config) {
274362 2785         global $app, $conf;
7fe908 2786
62e4b3 2787         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
274362 2788             $default_php_fpm = false;
F 2789             list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 2790             if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
274362 2791         } else {
F 2792             $default_php_fpm = true;
2793         }
7fe908 2794
274362 2795         if($default_php_fpm){
F 2796             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2797         } else {
2798             $pool_dir = $custom_php_fpm_pool_dir;
2799         }
7fe908 2800
MC 2801         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 2802         $pool_name = 'web'.$data['old']['domain_id'];
7fe908 2803
274362 2804         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
c77103 2805             $app->system->unlink($pool_dir.$pool_name.'.conf');
7fe908 2806             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2807
274362 2808             //$app->services->restartService('php-fpm','reload');
F 2809         }
7fe908 2810
274362 2811         // delete pool in all other PHP versions
F 2812         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2813         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2814         if($default_pool_dir != $pool_dir){
F 2815             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2816                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2817                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2818                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2819             }
7fe908 2820         }
274362 2821         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']);
F 2822         if(is_array($php_versions) && !empty($php_versions)){
2823             foreach($php_versions as $php_version){
7fe908 2824                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2825                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2826                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2827                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2828                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2829                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2830                     }
F 2831                 }
2832             }
2833         }
7fe908 2834
274362 2835         // Reload current PHP-FPM after all others
F 2836         sleep(1);
2837         if(!$default_php_fpm){
7fe908 2838             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2839         } else {
7fe908 2840             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2841         }
F 2842     }
7fe908 2843
MC 2844     function client_delete($event_name, $data) {
1ca823 2845         global $app, $conf;
7fe908 2846
1ca823 2847         $app->uses("getconf");
T 2848         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2849
1ca823 2850         $client_id = intval($data['old']['client_id']);
T 2851         if($client_id > 0) {
7fe908 2852
1ca823 2853             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
7fe908 2854             if(is_dir($client_dir) && !stristr($client_dir, '..')) {
72695f 2855                 // remove symlinks from $client_dir
7fe908 2856                 $files = array_diff(scandir($client_dir), array('.', '..'));
72695f 2857                 if(is_array($files) && !empty($files)){
T 2858                     foreach($files as $file){
2859                         if(is_link($client_dir.'/'.$file)){
2860                             unlink($client_dir.'/'.$file);
7fe908 2861                             $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG);
72695f 2862                         }
T 2863                     }
2864                 }
7fe908 2865
1ca823 2866                 @rmdir($client_dir);
7fe908 2867                 $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG);
1ca823 2868             }
7fe908 2869
615a0a 2870             if($app->system->is_group('client'.$client_id)){
T 2871                 $this->_exec('groupdel client'.$client_id);
7fe908 2872                 $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG);
615a0a 2873             }
1ca823 2874         }
7fe908 2875
1ca823 2876     }
ac933e 2877
1c40af 2878     //* Wrapper for exec function for easier debugging
T 2879     private function _exec($command) {
2880         global $app;
7fe908 2881         $app->log('exec: '.$command, LOGLEVEL_DEBUG);
1c40af 2882         exec($command);
T 2883     }
7ed741 2884
7fe908 2885     private function _checkTcp ($host, $port) {
MC 2886
2887         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
7ed741 2888
T 2889         if ($fp) {
2890             fclose($fp);
2891             return true;
2892         } else {
2893             return false;
2894         }
2895     }
ac933e 2896
552178 2897     public function create_relative_link($f, $t) {
bfcdef 2898         global $app;
7fe908 2899
552178 2900         // $from already exists
M 2901         $from = realpath($f);
2902
2903         // realpath requires the traced file to exist - so, lets touch it first, then remove
c77103 2904         @$app->system->unlink($t); touch($t);
552178 2905         $to = realpath($t);
c77103 2906         @$app->system->unlink($t);
552178 2907
M 2908         // Remove from the left side matching path elements from $from and $to
2909         // and get path elements counts
2910         $a1 = explode('/', $from); $a2 = explode('/', $to);
2911         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
2912             unset($a1[$c]); unset($a2[$c]);
2913         }
2914         $cfrom = implode('/', $a1);
2915
2916         // Check if a path is fully a subpath of another - no way to create symlink in the case
2917         if (count($a1) == 0 || count($a2) == 0) return false;
2918
2919         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
2920         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
2921
2922         return symlink($cfrom, $to);
2923     }
46c683 2924
7fe908 2925     private function _rewrite_quote($string) {
MC 2926         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
2927     }
2928
2929     private function _is_url($string) {
2930         return preg_match('/^(f|ht)tp(s)?:\/\//i', $string);
2931     }
2932
bfcdef 2933     private function get_seo_redirects($web, $prefix = ''){
T 2934         $seo_redirects = array();
7fe908 2935
bfcdef 2936         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
7fe908 2937
bfcdef 2938         if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){
T 2939             if($web['seo_redirect'] == 'non_www_to_www'){
2940                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2941                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2942                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2943             }
2944             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
2945                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
2946                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
2947                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))';
2948                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2949                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2950             }
2951             if($web['seo_redirect'] == '*_to_www_domain_tld'){
2952                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2953                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2954                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2955             }
2956         }
2957         if($web['seo_redirect'] == 'www_to_non_www'){
2958             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2959             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2960             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2961         }
2962         if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
2963             // ^(.+)\.example\.com$
2964             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '(.+)\.'.str_replace('.', '\.', $web['domain']);
2965             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2966             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2967         }
2968         if($web['seo_redirect'] == '*_to_domain_tld'){
2969             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2970             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2971             $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2972         }
2973         return $seo_redirects;
2974     }
7fe908 2975
46c683 2976 } // end class
T 2977
c09f04 2978 ?>