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