Till Brehm
2014-09-16 6068b7afc0371506be54e0596ecabf10e43ddbb4
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 .= '/';
MC 1265
274362 1266         if($data['new']['php_fpm_use_socket'] == 'y'){
F 1267             $use_tcp = 0;
1268             $use_socket = 1;
1269         } else {
1270             $use_tcp = 1;
1271             $use_socket = 0;
1272         }
1273         $tpl->setVar('use_tcp', $use_tcp);
1274         $tpl->setVar('use_socket', $use_socket);
1275         $fpm_socket = $socket_dir.$pool_name.'.sock';
1276         $tpl->setVar('fpm_socket', $fpm_socket);
1277         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
ac933e 1278
46c683 1279         /**
T 1280          * install cgi starter script and add script alias to config.
1281          * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
1282          * first we create the script directory if not already created, then copy over the starter script.
1283          * TODO: we have to fetch the data from the server-settings.
1284          */
fb3339 1285         if ($data['new']['php'] == 'cgi') {
J 1286             //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
46c683 1287
fb3339 1288             $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
6fb93d 1289             $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : '');
fb3339 1290             $cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
46c683 1291
7fe908 1292             $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']);
MC 1293             $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path);
46c683 1294
ac933e 1295             if (!is_dir($cgi_starter_path)) {
c77103 1296                 $app->system->mkdirpath($cgi_starter_path);
7fe908 1297                 $app->system->chown($cgi_starter_path, $data['new']['system_user']);
MC 1298                 $app->system->chgrp($cgi_starter_path, $data['new']['system_group']);
1299                 $app->system->chmod($cgi_starter_path, 0755);
46c683 1300
7fe908 1301                 $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG);
46c683 1302             }
T 1303
1304             $cgi_tpl = new tpl();
fb3339 1305             $cgi_tpl->newTemplate('php-cgi-starter.master');
8133de 1306             $cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
46c683 1307
fb3339 1308             // This works because PHP "rewrites" a symlink to the physical path
J 1309             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ac933e 1310             $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
fb3339 1311             $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
ac933e 1312
46c683 1313             // This will NOT work!
fb3339 1314             //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
7fe908 1315             $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']);
MC 1316             $cgi_tpl->setVar('security_level', $web_config['security_level']);
1317
1318             $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini);
7fddfe 1319             if($has_custom_php_ini) {
7fe908 1320                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1321             } else {
7fe908 1322                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
7fddfe 1323             }
46c683 1324
6fb93d 1325             $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
7fe908 1326             $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab());
46c683 1327             unset($cgi_tpl);
T 1328
7fe908 1329             $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG);
46c683 1330
T 1331
7fe908 1332             $app->system->chmod($cgi_starter_script, 0755);
MC 1333             $app->system->chown($cgi_starter_script, $data['new']['system_user']);
1334             $app->system->chgrp($cgi_starter_script, $data['new']['system_group']);
46c683 1335
7fe908 1336             $tpl->setVar('cgi_starter_path', $cgi_starter_path);
MC 1337             $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
46c683 1338
T 1339         }
1340
fb3339 1341         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
7ed741 1342         //* Make a backup copy of vhost file
7fe908 1343         if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~');
MC 1344
a7bdf8 1345         //* create empty vhost array
T 1346         $vhosts = array();
7fe908 1347
526b99 1348         //* Add vhost for ipv4 IP
T 1349         $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
1350         if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1351         if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1352         $vhosts[] = $tmp_vhost_arr;
1353         unset($tmp_vhost_arr);
7fe908 1354
a7bdf8 1355         //* Add vhost for ipv4 IP with SSL
481c00 1356         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1357         $domain = $data['new']['ssl_domain'];
1358         $key_file = $ssl_dir.'/'.$domain.'.key';
1359         $crt_file = $ssl_dir.'/'.$domain.'.crt';
7fe908 1360
a7bdf8 1361         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 1362             $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
T 1363             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1364             $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1365             if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){
1366                 for($i=0;$i<count($ipv4_ssl_alias_seo_redirects);$i++){
1367                     $ipv4_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1368                 }
1369             }
1370             if(count($ipv4_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects);
526b99 1371             $vhosts[] = $tmp_vhost_arr;
cc6568 1372             unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects);
7fe908 1373             $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG);
146783 1374         }
MC 1375
7fe908 1376         //* Add vhost for IPv6 IP
MC 1377         if($data['new']['ipv6_address'] != '') {
1378             if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
1379                 if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') {
1380                     $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']);
1381                     $explode_v6=explode(':', $data['new']['ipv6_address']);
1382
1383                     for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
1384                         $explode_v6[$i] = $explode_v6prefix[$i];
1385                     }
1386                     $data['new']['ipv6_address'] = implode(':', $explode_v6);
146783 1387                 }
MC 1388             }
7fe908 1389
526b99 1390             $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
T 1391             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1392             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1393             $vhosts[] = $tmp_vhost_arr;
1394             unset($tmp_vhost_arr);
7fe908 1395
a7bdf8 1396             //* Add vhost for ipv6 IP with SSL
T 1397             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 1398                 $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
T 1399                 if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1400                 $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1401                 if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){
1402                     for($i=0;$i<count($ipv6_ssl_alias_seo_redirects);$i++){
1403                         $ipv6_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1404                     }
1405                 }
1406                 if(count($ipv6_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects);
526b99 1407                 $vhosts[] = $tmp_vhost_arr;
cc6568 1408                 unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects);
7fe908 1409                 $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG);
a7bdf8 1410             }
T 1411         }
7fe908 1412
a7bdf8 1413         //* Set the vhost loop
7fe908 1414         $tpl->setLoop('vhosts', $vhosts);
MC 1415
7ed741 1416         //* Write vhost file
7fe908 1417         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1418         $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1419         unset($tpl);
ac933e 1420
V 1421         /*
1422          * maybe we have some webdav - user. If so, add them...
1423         */
fb3339 1424         $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
ac933e 1425
c6a89c 1426         //* Set the symlink to enable the vhost
T 1427         //* First we check if there is a old type of symlink and remove it
fb3339 1428         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
c77103 1429         if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink);
7fe908 1430
c6a89c 1431         //* Remove old or changed symlinks
T 1432         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1433             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1434             if(is_link($vhost_symlink)) {
c77103 1435                 $app->system->unlink($vhost_symlink);
7fe908 1436                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1437             }
T 1438             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1439             if(is_link($vhost_symlink)) {
c77103 1440                 $app->system->unlink($vhost_symlink);
7fe908 1441                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1442             }
T 1443         }
7fe908 1444
c6a89c 1445         //* New symlink
T 1446         if($data['new']['subdomain'] == '*') {
1447             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1448         } else {
1449             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1450         }
fb3339 1451         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
7fe908 1452             symlink($vhost_file, $vhost_symlink);
MC 1453             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
46c683 1454         }
ac933e 1455
46c683 1456         // remove old symlink and vhost file, if domain name of the site has changed
fb3339 1457         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
c6a89c 1458             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
T 1459             if(is_link($vhost_symlink)) {
c77103 1460                 $app->system->unlink($vhost_symlink);
7fe908 1461                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1462             }
T 1463             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1464             if(is_link($vhost_symlink)) {
c77103 1465                 $app->system->unlink($vhost_symlink);
7fe908 1466                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1467             }
8cf78b 1468             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1469             if(is_link($vhost_symlink)) {
c77103 1470                 $app->system->unlink($vhost_symlink);
7fe908 1471                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8cf78b 1472             }
fb3339 1473             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
c77103 1474             $app->system->unlink($vhost_file);
7fe908 1475             $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1476         }
ac933e 1477
46c683 1478         //* Create .htaccess and .htpasswd file for website statistics
cc6568 1479         //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
H 1480         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats');
1481         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user";
7fe908 1482         $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file);
746bf0 1483         $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755);
cc6568 1484         unset($ht_file);
H 1485         //}
ac933e 1486
bfcdef 1487         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
fb3339 1488             if(trim($data['new']['stats_password']) != '') {
J 1489                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
7fe908 1490                 $app->system->web_folder_protection($data['new']['document_root'], false);
MC 1491                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file);
1492                 $app->system->web_folder_protection($data['new']['document_root'], true);
746bf0 1493                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755);
46c683 1494                 unset($htp_file);
T 1495             }
1496         }
7fe908 1497
58c210 1498         //* Create awstats configuration
6fb93d 1499         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
7fe908 1500             $this->awstats_update($data, $web_config);
58c210 1501         }
7fe908 1502
MC 1503         $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
1504
7ed741 1505         if($web_config['check_apache_config'] == 'y') {
T 1506             //* Test if apache starts with the new configuration file
7fe908 1507             $apache_online_status_before_restart = $this->_checkTcp('localhost', 80);
MC 1508             $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
ac933e 1509
7fe908 1510             $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure
MC 1511             $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG);
1512
9f56bd 1513             // wait a few seconds, before we test the apache status again
bfcdef 1514             $apache_online_status_after_restart = false;
9f56bd 1515             sleep(2);
bfcdef 1516             for($i = 0; $i < 5; $i++) {
7fe908 1517                 $apache_online_status_after_restart = $this->_checkTcp('localhost', 80);
bfcdef 1518                 if($apache_online_status_after_restart) break;
T 1519                 sleep(1);
1520             }
7ed741 1521             //* Check if apache restarted successfully if it was online before
7fe908 1522             $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
615a0a 1523             if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) {
7fe908 1524                 $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 1525                 if(is_array($retval['output']) && !empty($retval['output'])){
7fe908 1526                     $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN);
7b47c0 1527                     $app->dbmaster->datalogError(implode("\n", $retval['output']));
615a0a 1528                 } else {
T 1529                     // if no output is given, check again
1530                     $webserver_binary = '';
7b47c0 1531                     exec('which apache2ctl', $webserver_check_output, $webserver_check_retval);
615a0a 1532                     if($webserver_check_retval == 0){
7b47c0 1533                         $webserver_binary = 'apache2ctl';
615a0a 1534                     } else {
T 1535                         unset($webserver_check_output, $webserver_check_retval);
7b47c0 1536                         exec('which apache2', $webserver_check_output, $webserver_check_retval);
615a0a 1537                         if($webserver_check_retval == 0){
7b47c0 1538                             $webserver_binary = 'apache2';
615a0a 1539                         } else {
T 1540                             unset($webserver_check_output, $webserver_check_retval);
7b47c0 1541                             exec('which httpd2', $webserver_check_output, $webserver_check_retval);
615a0a 1542                             if($webserver_check_retval == 0){
7b47c0 1543                                 $webserver_binary = 'httpd2';
615a0a 1544                             } else {
T 1545                                 unset($webserver_check_output, $webserver_check_retval);
7b47c0 1546                                 exec('which httpd', $webserver_check_output, $webserver_check_retval);
615a0a 1547                                 if($webserver_check_retval == 0){
7b47c0 1548                                     $webserver_binary = 'httpd';
T 1549                                 } else {
1550                                     unset($webserver_check_output, $webserver_check_retval);
1551                                     exec('which apache', $webserver_check_output, $webserver_check_retval);
1552                                     if($webserver_check_retval == 0){
1553                                         $webserver_binary = 'apache';
1554                                     }
615a0a 1555                                 }
T 1556                             }
1557                         }
1558                     }
1559                     if($webserver_binary != ''){
1560                         exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval);
7b47c0 1561                         if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){
7fe908 1562                             $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN);
7b47c0 1563                             $app->dbmaster->datalogError(implode("\n", $tmp_output));
T 1564                         }
615a0a 1565                         unset($tmp_output, $tmp_retval);
T 1566                     }
1567                 }
7fe908 1568                 $app->system->copy($vhost_file, $vhost_file.'.err');
8cf78b 1569                 if(is_file($vhost_file.'~')) {
T 1570                     //* Copy back the last backup file
7fe908 1571                     $app->system->copy($vhost_file.'~', $vhost_file);
8cf78b 1572                 } else {
T 1573                     //* There is no backup file, so we create a empty vhost file with a warning message inside
7fe908 1574                     $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 1575                 }
481c00 1576                 if($this->ssl_certificate_changed === true) {
T 1577
1578                     $ssl_dir = $data['new']['document_root'].'/ssl';
1579                     $domain = $data['new']['ssl_domain'];
1580                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1581                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1582                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1583                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1584                     $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1585
481c00 1586                     //* Backup the files that might have caused the error
43b345 1587                     if(is_file($key_file)){
7fe908 1588                         $app->system->copy($key_file, $key_file.'.err');
MC 1589                         $app->system->chmod($key_file.'.err', 0400);
43b345 1590                     }
T 1591                     if(is_file($key_file2)){
7fe908 1592                         $app->system->copy($key_file2, $key_file2.'.err');
MC 1593                         $app->system->chmod($key_file2.'.err', 0400);
43b345 1594                     }
7fe908 1595                     if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err');
MC 1596                     if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err');
1597                     if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err');
1598
481c00 1599                     //* Restore the ~ backup files
7fe908 1600                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file);
MC 1601                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2);
1602                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file);
1603                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file);
1604                     if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file);
1605
1606                     $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 1607                 }
7fe908 1608
MC 1609                 $app->services->restartService('httpd', 'restart');
7ed741 1610             }
c82dc7 1611         } else {
7ed741 1612             //* We do not check the apache config after changes (is faster)
T 1613             if($apache_chrooted) {
7fe908 1614                 $app->services->restartServiceDelayed('httpd', 'restart');
7ed741 1615             } else {
T 1616                 // request a httpd reload when all records have been processed
7fe908 1617                 $app->services->restartServiceDelayed('httpd', 'reload');
7ed741 1618             }
c82dc7 1619         }
7fe908 1620
MC 1621         //* The vhost is written and apache has been restarted, so we
481c00 1622         // can reset the ssl changed var to false and cleanup some files
T 1623         $this->ssl_certificate_changed = false;
7fe908 1624
481c00 1625         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1626         $domain = $data['new']['ssl_domain'];
1627         $key_file = $ssl_dir.'/'.$domain.'.key.org';
1628         $key_file2 = $ssl_dir.'/'.$domain.'.key';
1629         $csr_file = $ssl_dir.'/'.$domain.'.csr';
1630         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1631         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1632
c77103 1633         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
T 1634         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
1635         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
1636         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
1637         if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
7fe908 1638
7ed741 1639         // Remove the backup copy of the config file.
c77103 1640         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
ac933e 1641
da1a7c 1642         //* Unset action to clean it for next processed vhost.
T 1643         $this->action = '';
46c683 1644     }
ac933e 1645
7fe908 1646     function delete($event_name, $data) {
46c683 1647         global $app, $conf;
ac933e 1648
46c683 1649         // load the server configuration options
fb3339 1650         $app->uses('getconf');
c09f04 1651         $app->uses('system');
fb3339 1652         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
cc6568 1653         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
7fe908 1654
MC 1655         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 1656
2bbc4c 1657         //* Check if this is a chrooted setup
4b72c5 1658         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 1659             $apache_chrooted = true;
T 1660         } else {
1661             $apache_chrooted = false;
1662         }
7fe908 1663
fea5e7 1664         //* Remove the mounts
T 1665         $log_folder = 'log';
7fe908 1666         $web_folder = '';
MC 1667         if($data['old']['type'] == 'vhostsubdomain') {
1668             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
526b99 1669             if($tmp['domain'] != ''){
T 1670                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
1671             } else {
1672                 // get log folder from /etc/fstab
1673                 /*
1674                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
1675                 $bind_mount_lines = explode("\n", $bind_mounts);
1676                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
1677                     foreach($bind_mount_lines as $bind_mount_line){
1678                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
1679                         $bind_mount_parts = explode(' ', $bind_mount_line);
1680                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
1681                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
1682                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
1683                             }
1684                         }
1685                     }
1686                 }
1687                 */
1688                 // we are deleting the parent domain, so we can delete everything in the log directory
1689                 $subdomain_hosts = array();
7fe908 1690                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..'));
526b99 1691                 if(is_array($files) && !empty($files)){
T 1692                     foreach($files as $file){
1693                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
1694                             $subdomain_hosts[] = $file;
1695                         }
1696                     }
1697                 }
1698             }
7fe908 1699             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
526b99 1700                 $log_folders = array();
T 1701                 foreach($subdomain_hosts as $subdomain_host){
1702                     $log_folders[] = $log_folder.'/'.$subdomain_host;
1703                 }
1704             } else {
1705                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
1706                 $log_folder .= '/' . $subdomain_host;
1707             }
1708             $web_folder = $data['old']['web_folder'];
7fe908 1709             unset($tmp);
526b99 1710             unset($subdomain_hosts);
3cde19 1711         }
7fe908 1712
526b99 1713         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){
T 1714             if(is_array($log_folders) && !empty($log_folders)){
1715                 foreach($log_folders as $log_folder){
cc6568 1716                     //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1717                     exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1718                 }
T 1719             } else {
cc6568 1720                 //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1721                 exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1722             }
T 1723         }
7fe908 1724
fea5e7 1725         //* remove mountpoint from fstab
526b99 1726         if(is_array($log_folders) && !empty($log_folders)){
T 1727             foreach($log_folders as $log_folder){
1728                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1729                 $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1730             }
T 1731         } else {
1732             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1733             $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1734         }
T 1735         unset($log_folders);
ac933e 1736
6fb93d 1737         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) {
46c683 1738             //* This is a alias domain or subdomain, so we have to update the website instead
fb3339 1739             $parent_domain_id = intval($data['old']['parent_domain_id']);
J 1740             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
1741             $data['new'] = $tmp;
1742             $data['old'] = $tmp;
46c683 1743             $this->action = 'update';
T 1744             // just run the update function
7fe908 1745             $this->update($event_name, $data);
ac933e 1746
46c683 1747         } else {
T 1748             //* This is a website
1749             // Deleting the vhost file, symlink and the data directory
fb3339 1750             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
7fe908 1751
8ab3cd 1752             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1753             if(is_link($vhost_symlink)){
c77103 1754                 $app->system->unlink($vhost_symlink);
7fe908 1755                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1756             }
T 1757             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1758             if(is_link($vhost_symlink)){
c77103 1759                 $app->system->unlink($vhost_symlink);
7fe908 1760                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1761             }
T 1762             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1763             if(is_link($vhost_symlink)){
c77103 1764                 $app->system->unlink($vhost_symlink);
7fe908 1765                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1766             }
7fe908 1767
c77103 1768             $app->system->unlink($vhost_file);
7fe908 1769             $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
ac933e 1770
7fe908 1771             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
MC 1772                 $docroot = escapeshellcmd($data['old']['document_root']);
1773                 if($docroot != '' && !stristr($docroot, '..')) {
1774                     if($data['old']['type'] == 'vhost') {
1775                         // this is a vhost - we delete everything in here.
1776                         exec('rm -rf '.$docroot);
1777                     } elseif(!stristr($data['old']['web_folder'], '..')) {
1778                         // this is a vhost subdomain
1779                         // IMPORTANT: do some folder checks before we delete this!
1780                         $do_delete = true;
1781                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
1782                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
1783                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
46c683 1784
7fe908 1785                         $path_elements = explode('/', $delete_folder);
46c683 1786
7fe908 1787                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
MC 1788                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
1789                             // we use strict check as otherwise directories named '0' may not be deleted
1790                             $do_delete = false;
1791                         } else {
1792                             // read all vhost subdomains with same parent domain
1793                             $used_paths = array();
1794                             $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']));
1795                             foreach($tmp as $tmprec) {
1796                                 // we normalize the folder entries because we need to compare them
1797                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
1798                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
1799                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
ac933e 1800
7fe908 1801                                 // add this path and it's parent paths to used_paths array
MC 1802                                 while(strpos($tmp_folder, '/') !== false) {
1803                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1804                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
1805                                 }
1806                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1807                             }
1808                             unset($tmp);
1809
1810                             // loop and check if the path is still used and stop at first used one
1811                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
1812                             $do_delete = false;
1813                             while(count($path_elements) > 0) {
1814                                 $tmp_folder = implode('/', $path_elements);
1815                                 if(in_array($tmp_folder, $used_paths) == true) break;
1816
1817                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
1818                                 $delete_folder = $tmp_folder;
1819                                 $do_delete = true;
1820                                 array_pop($path_elements);
1821                             }
1822                             unset($tmp_folder);
1823                             unset($used_paths);
1824                         }
1825
1826                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
1827
1828                         unset($delete_folder);
1829                         unset($path_elements);
1830                     }
1831                 }
1832
1833                 //remove the php fastgi starter script if available
1834                 if ($data['old']['php'] == 'fast-cgi') {
1835                     $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
1836                     if($data['old']['type'] == 'vhost') {
1837                         if (is_dir($fastcgi_starter_path)) {
1838                             exec('rm -rf '.$fastcgi_starter_path);
1839                         }
1840                     } else {
1841                         $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
1842                         if (file_exists($fcgi_starter_script)) {
1843                             exec('rm -f '.$fcgi_starter_script);
1844                         }
1845                     }
1846                 }
1847
1848                 // remove PHP-FPM pool
1849                 if ($data['old']['php'] == 'php-fpm') {
1850                     $this->php_fpm_pool_delete($data, $web_config);
1851                 }
1852
1853                 //remove the php cgi starter script if available
1854                 if ($data['old']['php'] == 'cgi') {
1855                     // TODO: fetch the date from the server-settings
1856                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
1857
1858                     $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']);
1859                     if($data['old']['type'] == 'vhost') {
1860                         if (is_dir($cgi_starter_path)) {
1861                             exec('rm -rf '.$cgi_starter_path);
1862                         }
1863                     } else {
1864                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
1865                         if (file_exists($cgi_starter_script)) {
1866                             exec('rm -f '.$cgi_starter_script);
1867                         }
1868                     }
1869                 }
1870
1871                 $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
1872
1873                 // Delete the symlinks for the sites
1874                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
1875                 $client_id = intval($client['client_id']);
1876                 unset($client);
1877                 $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
1878                 if(is_array($tmp_symlinks_array)) {
1879                     foreach($tmp_symlinks_array as $tmp_symlink) {
1880                         $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
1881                         $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
1882                         // Remove trailing slash
1883                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
1884                         // delete the symlink
1885                         if(is_link($tmp_symlink)) {
1886                             $app->system->unlink($tmp_symlink);
1887                             $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG);
1888                         }
1889                     }
1890                 }
1891                 // end removing symlinks
3cde19 1892             }
7fe908 1893
MC 1894             // Delete the log file directory
1895             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
1896             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir);
1897             $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG);
1898
1899             if($data['old']['type'] == 'vhost') {
1900                 //delete the web user
1901                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel';
1902                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
1903                 exec($command);
1904                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
1905
1906             }
1907
1908             //* Remove the awstats configuration file
1909             if($data['old']['stats_type'] == 'awstats') {
1910                 $this->awstats_delete($data, $web_config);
1911             }
1912
1913             if($data['old']['type'] == 'vhostsubdomain') {
1914                 $app->system->web_folder_protection($parent_web_document_root, true);
1915             }
1916
8ab3cd 1917             if($apache_chrooted) {
7fe908 1918                 $app->services->restartServiceDelayed('httpd', 'restart');
8ab3cd 1919             } else {
T 1920                 // request a httpd reload when all records have been processed
7fe908 1921                 $app->services->restartServiceDelayed('httpd', 'reload');
58c210 1922             }
ac933e 1923
46c683 1924         }
7fe908 1925         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true);
46c683 1926     }
ac933e 1927
46c683 1928     //* This function is called when a IP on the server is inserted, updated or deleted
7fe908 1929     function server_ip($event_name, $data) {
46c683 1930         global $app, $conf;
ac933e 1931
46c683 1932         // load the server configuration options
fb3339 1933         $app->uses('getconf');
J 1934         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 1935
46c683 1936         $app->load('tpl');
ac933e 1937
46c683 1938         $tpl = new tpl();
fb3339 1939         $tpl->newTemplate('apache_ispconfig.conf.master');
8133de 1940         $tpl->setVar('apache_version', $app->system->getapacheversion());
fb3339 1941         $records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
7fe908 1942
a2156e 1943         $records_out= array();
T 1944         if(is_array($records)) {
1945             foreach($records as $rec) {
1946                 if($rec['ip_type'] == 'IPv6') {
1947                     $ip_address = '['.$rec['ip_address'].']';
1948                 } else {
1949                     $ip_address = $rec['ip_address'];
1950                 }
7fe908 1951                 $ports = explode(',', $rec['virtualhost_port']);
a2156e 1952                 if(is_array($ports)) {
T 1953                     foreach($ports as $port) {
1954                         $port = intval($port);
1955                         if($port > 0 && $port < 65536 && $ip_address != '') {
1956                             $records_out[] = array('ip_address' => $ip_address, 'port' => $port);
1957                         }
1958                     }
1959                 }
1960             }
1961         }
7fe908 1962
MC 1963
a2156e 1964         if(count($records_out) > 0) {
7fe908 1965             $tpl->setLoop('ip_adresses', $records_out);
46c683 1966         }
ac933e 1967
fb3339 1968         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
7fe908 1969         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1970         $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1971         unset($tpl);
ac933e 1972
46c683 1973     }
7fe908 1974
524077 1975     //* Create or update the .htaccess folder protection
7fe908 1976     function web_folder_user($event_name, $data) {
524077 1977         global $app, $conf;
c69439 1978
524077 1979         $app->uses('system');
7fe908 1980
524077 1981         if($event_name == 'web_folder_user_delete') {
T 1982             $folder_id = $data['old']['web_folder_id'];
1983         } else {
1984             $folder_id = $data['new']['web_folder_id'];
1985         }
7fe908 1986
524077 1987         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
T 1988         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 1989
524077 1990         if(!is_array($folder) or !is_array($website)) {
7fe908 1991             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 1992             return false;
T 1993         }
7fe908 1994
MC 1995         $web_folder = 'web';
1996         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
1997
524077 1998         //* Get the folder path.
7fe908 1999         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2000         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2001         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2002         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2003
524077 2004         //* Check if the resulting path is inside the docroot
7fe908 2005         if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) {
MC 2006             $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
524077 2007             return false;
T 2008         }
7fe908 2009
524077 2010         //* Create the folder path, if it does not exist
8cf78b 2011         if(!is_dir($folder_path)) {
c77103 2012             $app->system->mkdirpath($folder_path);
7fe908 2013             $app->system->chown($folder_path, $website['system_user']);
MC 2014             $app->system->chgrp($folder_path, $website['system_group']);
8cf78b 2015         }
7fe908 2016
524077 2017         //* Create empty .htpasswd file, if it does not exist
T 2018         if(!is_file($folder_path.'.htpasswd')) {
4bd960 2019             $app->system->touch($folder_path.'.htpasswd');
51910d 2020             $app->system->chmod($folder_path.'.htpasswd', 0751);
7fe908 2021             $app->system->chown($folder_path.'.htpasswd', $website['system_user']);
MC 2022             $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
2023             $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2024         }
7fe908 2025
8ab3cd 2026         /*
T 2027         $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
2028         $htpasswd_content = '';
2029         if(is_array($auth_users) && !empty($auth_users)){
2030             foreach($auth_users as $auth_user){
2031                 $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
2032             }
2033         }
2034         $htpasswd_content = trim($htpasswd_content);
2035         @file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
2036         $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
2037         */
7fe908 2038
8ab3cd 2039         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
7fe908 2040             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2041             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
c69439 2042         }
7fe908 2043
524077 2044         //* Add or remove the user from .htpasswd file
T 2045         if($event_name == 'web_folder_user_delete') {
7fe908 2046             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2047             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
524077 2048         } else {
c69439 2049             if($data['new']['active'] == 'y') {
7fe908 2050                 $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1);
MC 2051                 $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG);
c69439 2052             }
524077 2053         }
7fe908 2054
MC 2055
524077 2056         //* Create the .htaccess file
8ab3cd 2057         //if(!is_file($folder_path.'.htaccess')) {
7fe908 2058         $begin_marker = '### ISPConfig folder protection begin ###';
MC 2059         $end_marker = "### ISPConfig folder protection end ###\n\n";
2060         $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2061
2062         if(file_exists($folder_path.'.htaccess')) {
2063             $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
2064
2065             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2066                 $ht_file = str_replace($matches[0], $ht_file, $old_content);
2067             } else {
2068                 $ht_file .= $old_content;
2069             }
2070         }
2071         unset($old_content);
2072
2073         $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
51910d 2074         $app->system->chmod($folder_path.'.htaccess', 0751);
7fe908 2075         $app->system->chown($folder_path.'.htaccess', $website['system_user']);
MC 2076         $app->system->chgrp($folder_path.'.htaccess', $website['system_group']);
2077         $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
8ab3cd 2078         //}
7fe908 2079
524077 2080     }
7fe908 2081
524077 2082     //* Remove .htaccess and .htpasswd file, when folder protection is removed
7fe908 2083     function web_folder_delete($event_name, $data) {
524077 2084         global $app, $conf;
7fe908 2085
524077 2086         $folder_id = $data['old']['web_folder_id'];
7fe908 2087
8ab3cd 2088         $folder = $data['old'];
524077 2089         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 2090
524077 2091         if(!is_array($folder) or !is_array($website)) {
7fe908 2092             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2093             return false;
T 2094         }
7fe908 2095
MC 2096         $web_folder = 'web';
2097         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2098
524077 2099         //* Get the folder path.
7fe908 2100         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2101         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2102         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2103         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2104
524077 2105         //* Check if the resulting path is inside the docroot
7fe908 2106         if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2107             $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG);
524077 2108             return false;
T 2109         }
7fe908 2110
524077 2111         //* Remove .htpasswd file
T 2112         if(is_file($folder_path.'.htpasswd')) {
c77103 2113             $app->system->unlink($folder_path.'.htpasswd');
7fe908 2114             $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2115         }
7fe908 2116
524077 2117         //* Remove .htaccess file
T 2118         if(is_file($folder_path.'.htaccess')) {
7fe908 2119             $begin_marker = '### ISPConfig folder protection begin ###';
MC 2120             $end_marker = "### ISPConfig folder protection end ###\n\n";
2121
2122             $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
2123
2124             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2125                 $ht_file = str_replace($matches[0], '', $ht_file);
2126             } else {
2127                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2128             }
2129
2130             if(trim($ht_file) == '') {
2131                 $app->system->unlink($folder_path.'.htaccess');
2132                 $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2133             } else {
2134                 $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
2135                 $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2136             }
524077 2137         }
2023a7 2138     }
7fe908 2139
2023a7 2140     //* Update folder protection, when path has been changed
7fe908 2141     function web_folder_update($event_name, $data) {
2023a7 2142         global $app, $conf;
7fe908 2143
2023a7 2144         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
7fe908 2145
2023a7 2146         if(!is_array($website)) {
7fe908 2147             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
2023a7 2148             return false;
T 2149         }
7fe908 2150
MC 2151         $web_folder = 'web';
2152         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2153
2023a7 2154         //* Get the folder path.
7fe908 2155         if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
MC 2156         if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1);
6fb93d 2157         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
7fe908 2158         if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/';
MC 2159
2160         if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1);
2161         if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1);
6fb93d 2162         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
7fe908 2163         if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/';
MC 2164
2023a7 2165         //* Check if the resulting path is inside the docroot
7fe908 2166         if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) {
MC 2167             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2168             return false;
T 2169         }
7fe908 2170         if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) {
MC 2171             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2172             return false;
T 2173         }
7fe908 2174
2023a7 2175         //* Check if the resulting path is inside the docroot
7fe908 2176         if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2177             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2178             return false;
T 2179         }
7fe908 2180         if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2181             $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2182             return false;
T 2183         }
7fe908 2184
2023a7 2185         //* Create the folder path, if it does not exist
c77103 2186         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
7fe908 2187
MC 2188         $begin_marker = '### ISPConfig folder protection begin ###';
2189         $end_marker = "### ISPConfig folder protection end ###\n\n";
2190
2023a7 2191         if($data['old']['path'] != $data['new']['path']) {
T 2192
7fe908 2193
2023a7 2194             //* move .htpasswd file
T 2195             if(is_file($old_folder_path.'.htpasswd')) {
7fe908 2196                 $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd');
MC 2197                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2023a7 2198             }
7fe908 2199
8ab3cd 2200             //* delete old .htaccess file
2023a7 2201             if(is_file($old_folder_path.'.htaccess')) {
7fe908 2202                 $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
MC 2203
2204                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2205                     $ht_file = str_replace($matches[0], '', $ht_file);
2206                 } else {
2207                     $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2208                 }
2209
2210                 if(trim($ht_file) == '') {
2211                     $app->system->unlink($old_folder_path.'.htaccess');
2212                     $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2213                 } else {
2214                     $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
2215                     $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2216                 }
2023a7 2217             }
7fe908 2218
2023a7 2219         }
7fe908 2220
2023a7 2221         //* Create the .htaccess file
8ab3cd 2222         if($data['new']['active'] == 'y') {
7fe908 2223             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
MC 2224
2225             if(file_exists($new_folder_path.'.htaccess')) {
2226                 $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
2227
2228                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2229                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2230                 } else {
2231                     $ht_file .= $old_content;
2232                 }
2233             }
2234
2235             $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
51910d 2236             $app->system->chmod($new_folder_path.'.htaccess', 0751);
7fe908 2237             $app->system->chown($new_folder_path.'.htaccess', $website['system_user']);
MC 2238             $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']);
2239             $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
8433d0 2240             
TB 2241             //* Create empty .htpasswd file, if it does not exist
2242             if(!is_file($folder_path.'.htpasswd')) {
2243                 $app->system->touch($new_folder_path.'.htpasswd');
51910d 2244                 $app->system->chmod($new_folder_path.'.htpasswd', 0751);
8433d0 2245                 $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']);
TB 2246                 $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']);
2247                 $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2248             }
2023a7 2249         }
7fe908 2250
2023a7 2251         //* Remove .htaccess file
T 2252         if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
7fe908 2253             $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
MC 2254
2255             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2256                 $ht_file = str_replace($matches[0], '', $ht_file);
2257             } else {
2258                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2259             }
2260
2261             if(trim($ht_file) == '') {
2262                 $app->system->unlink($new_folder_path.'.htaccess');
2263                 $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2264             } else {
2265                 $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
2266                 $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2267             }
2023a7 2268         }
7fe908 2269
MC 2270
524077 2271     }
7fe908 2272
MC 2273     public function ftp_user_delete($event_name, $data) {
26c0fc 2274         global $app, $conf;
7fe908 2275
26c0fc 2276         $ftpquota_file = $data['old']['dir'].'/.ftpquota';
c77103 2277         if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file);
7fe908 2278
26c0fc 2279     }
7fe908 2280
MC 2281
ac933e 2282
V 2283     /**
2284      * This function is called when a Webdav-User is inserted, updated or deleted.
2285      *
2286      * @author Oliver Vogel
2287      * @param string $event_name
2288      * @param array $data
2289      */
7fe908 2290     public function webdav($event_name, $data) {
ac933e 2291         global $app, $conf;
7fe908 2292
52a04e 2293         /*
T 2294          * load the server configuration options
2295         */
fb3339 2296         $app->uses('getconf');
J 2297         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2298
V 2299         if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
2300
2301             /*
2302              * Get additional informations
2303             */
fb3339 2304             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
ac933e 2305             $documentRoot = $sitedata['document_root'];
V 2306             $domain = $sitedata['domain'];
ca14fe 2307             $user = $sitedata['system_user'];
V 2308             $group = $sitedata['system_group'];
b67344 2309             $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
ac933e 2310
V 2311             /* Check if this is a chrooted setup */
2312             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2313                 $apache_chrooted = true;
7fe908 2314                 $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
ac933e 2315             } else {
V 2316                 $apache_chrooted = false;
2317             }
7fe908 2318
b67344 2319             //* We dont want to have relative paths here
7fe908 2320             if(stristr($webdav_user_dir, '..')  || stristr($webdav_user_dir, './')) {
MC 2321                 $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot, LOGLEVEL_WARN);
b67344 2322                 return false;
T 2323             }
7fe908 2324
b67344 2325             //* Check if the resulting path exists if yes, if it is inside the docroot
7fe908 2326             if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir), 0, strlen($documentRoot)) != $documentRoot) {
MC 2327                 $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot, LOGLEVEL_WARN);
b67344 2328                 return false;
T 2329             }
ac933e 2330
V 2331             /*
2332              * First the webdav-root - folder has to exist
2333             */
b67344 2334             if(!is_dir($webdav_user_dir)) {
7fe908 2335                 $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.', LOGLEVEL_DEBUG);
c77103 2336                 $app->system->mkdirpath($webdav_user_dir);
ac933e 2337             }
V 2338
2339             /*
ca14fe 2340              * The webdav - Root needs the group/user as owner and the apache as read and write
ac933e 2341             */
c77103 2342             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
T 2343             //$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
7fe908 2344             $app->system->chown($documentRoot . '/webdav', $user);
MC 2345             $app->system->chgrp($documentRoot . '/webdav', $group);
2346             $app->system->chmod($documentRoot . '/webdav', 0770);
ac933e 2347
V 2348             /*
ca14fe 2349              * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
V 2350              * pwd-files are owned by root)
ac933e 2351             */
c77103 2352             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
T 2353             //$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
7fe908 2354             $app->system->chown($webdav_user_dir, $user);
MC 2355             $app->system->chgrp($webdav_user_dir, $group);
2356             $app->system->chmod($webdav_user_dir, 0770);
ca14fe 2357
V 2358             /*
2359              * if the user is active, we have to write/update the password - file
2360              * if the user is inactive, we have to inactivate the user by removing the user from the file
2361             */
2362             if ($data['new']['active'] == 'y') {
b67344 2363                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
ca14fe 2364             }
V 2365             else {
2366                 /* empty pwd removes the user! */
b67344 2367                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
ca14fe 2368             }
ac933e 2369
V 2370             /*
2371              * Next step, patch the vhost - file
2372             */
fb3339 2373             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
ac933e 2374             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
ca14fe 2375
ac933e 2376             /*
V 2377              * Last, restart apache
2378             */
2379             if($apache_chrooted) {
7fe908 2380                 $app->services->restartServiceDelayed('httpd', 'restart');
ac933e 2381             } else {
V 2382                 // request a httpd reload when all records have been processed
7fe908 2383                 $app->services->restartServiceDelayed('httpd', 'reload');
ac933e 2384             }
V 2385
2386         }
2387
2388         if ($event_name == 'webdav_user_delete') {
2389             /*
2390              * Get additional informations
2391             */
fb3339 2392             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
ac933e 2393             $documentRoot = $sitedata['document_root'];
52a04e 2394             $domain = $sitedata['domain'];
ac933e 2395
V 2396             /*
2397              * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
2398              * So the only thing, we have to do, is to delete the user from the password-file
ca14fe 2399             */
ac933e 2400             $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
7fe908 2401
52a04e 2402             /*
T 2403              * Next step, patch the vhost - file
2404             */
fb3339 2405             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
52a04e 2406             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
7fe908 2407
52a04e 2408             /*
T 2409              * Last, restart apache
2410             */
2411             if($apache_chrooted) {
7fe908 2412                 $app->services->restartServiceDelayed('httpd', 'restart');
52a04e 2413             } else {
T 2414                 // request a httpd reload when all records have been processed
7fe908 2415                 $app->services->restartServiceDelayed('httpd', 'reload');
52a04e 2416             }
ac933e 2417         }
V 2418     }
2419
2420
2421     /**
2422      * This function writes the htdigest - files used by webdav and digest
ca14fe 2423      * more info: see http://riceball.com/d/node/424
ac933e 2424      * @author Oliver Vogel
V 2425      * @param string $filename The name of the digest-file
2426      * @param string $username The name of the webdav-user
2427      * @param string $authname The name of the realm
ca14fe 2428      * @param string $pwd      The password-hash of the user
ac933e 2429      */
ca14fe 2430     private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
4bd960 2431         global $app;
7fe908 2432
ac933e 2433         $changed = false;
c77103 2434         if(is_file($filename) && !is_link($filename)) {
0ff3f1 2435             $in = fopen($filename, 'r');
T 2436             $output = '';
2437             /*
2438             * read line by line and search for the username and authname
2439             */
2440             while (preg_match("/:/", $line = fgets($in))) {
2441                 $line = rtrim($line);
2442                 $tmp = explode(':', $line);
2443                 if ($tmp[0] == $username && $tmp[1] == $authname) {
2444                     /*
2445                     * found the user. delete or change it?
2446                     */
2447                     if ($pwdhash != '') {
2448                         $output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
7fe908 2449                     }
0ff3f1 2450                     $changed = true;
T 2451                 }
2452                 else {
2453                     $output .= $line . "\n";
2454                 }
ac933e 2455             }
0ff3f1 2456             fclose($in);
ac933e 2457         }
V 2458         /*
2459          * if we didn't change anything, we have to add the new user at the end of the file
2460         */
2461         if (!$changed) {
f17dab 2462             $output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
ac933e 2463         }
7fe908 2464
ac933e 2465
V 2466         /*
2467          * Now lets write the new file
2468         */
52a04e 2469         if(trim($output) == '') {
c77103 2470             $app->system->unlink($filename);
52a04e 2471         } else {
c77103 2472             $app->system->file_put_contents($filename, $output);
52a04e 2473         }
ac933e 2474     }
V 2475
2476     /**
2477      * This function patches the vhost-file and adds all webdav - user.
2478      * This function is written, because the creation of the vhost - file is sophisticated and
2479      * i don't want to make it more "heavy" by also adding this code too...
2480      * @author Oliver Vogel
2481      * @param string $fileName The Name of the .vhost-File (path included)
2482      * @param string $webdavRoot The root of the webdav-folder
2483      */
2484     private function _patchVhostWebdav($fileName, $webdavRoot) {
c77103 2485         global $app;
ac933e 2486         $in = fopen($fileName, 'r');
V 2487         $output = '';
2488         $inWebdavSection = false;
2489
2490         /*
2491          * read line by line and search for the username and authname
2492         */
2493         while ($line = fgets($in)) {
2494             /*
2495              *  is the "replace-comment" found...
2496             */
2497             if (trim($line) == '# WEBDAV BEGIN') {
2498                 /*
2499                  * The begin of the webdav - section is found, so ignore all lines til the end  is found
2500                 */
2501                 $inWebdavSection = true;
2502
2503                 $output .= "      # WEBDAV BEGIN\n";
2504
2505                 /*
2506                  * add all the webdav-dirs to the webdav-section
2507                 */
fb3a98 2508                 $files = @scandir($webdavRoot);
T 2509                 if(is_array($files)) {
7fe908 2510                     foreach($files as $file) {
MC 2511                         if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) {
2512                             /*
ac933e 2513                          * found a htdigest - file, so add it to webdav
V 2514                         */
7fe908 2515                             $fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
MC 2516                             $output .= "\n";
2517                             // $output .= "      Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2518                             // $output .= "      <Location /" . $fn . ">\n";
2519                             $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2520                             $output .= "      <Location /webdav/" . $fn . ">\n";
2521                             $output .= "        DAV On\n";
2522                             $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
2523                             $output .= "        AuthType Digest\n";
2524                             $output .= "        AuthName \"" . $fn . "\"\n";
2525                             $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
2526                             $output .= "        Require valid-user \n";
2527                             $output .= "        Options +Indexes \n";
2528                             $output .= "        Order allow,deny \n";
2529                             $output .= "        Allow from all \n";
2530                             $output .= "      </Location> \n";
2531                         }
ac933e 2532                     }
fb3a98 2533                 }
ac933e 2534             }
V 2535             /*
2536              *  is the "replace-comment-end" found...
2537             */
2538             if (trim($line) == '# WEBDAV END') {
2539                 /*
2540                  * The end of the webdav - section is found, so stop ignoring
2541                 */
2542                 $inWebdavSection = false;
2543             }
2544
2545             /*
2546              * Write the line to the output, if it is not in the section
2547             */
2548             if (!$inWebdavSection) {
2549                 $output .= $line;
2550             }
2551         }
2552         fclose($in);
2553
2554         /*
2555          * Now lets write the new file
2556         */
c77103 2557         $app->system->file_put_contents($fileName, $output);
ac933e 2558
V 2559     }
7fe908 2560
58c210 2561     //* Update the awstats configuration file
7fe908 2562     private function awstats_update ($data, $web_config) {
58c210 2563         global $app;
7fe908 2564
MC 2565         $web_folder = $data['new']['web_folder'];
2566         if($data['new']['type'] == 'vhost') $web_folder = 'web';
2a6eac 2567         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2568
6fb93d 2569         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
fb3339 2570         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
J 2571             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2572                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
58c210 2573             }
7fe908 2574
58c210 2575             $content = '';
2a6eac 2576             $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n";
fb3339 2577             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
J 2578             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2579             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
7fe908 2580
MC 2581             $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content);
2582             $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2583         }
7fe908 2584
6fb93d 2585         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 2586         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
7fe908 2587             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2588         } else {
7fe908 2589             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2590         }
58c210 2591     }
7fe908 2592
58c210 2593     //* Delete the awstats configuration file
7fe908 2594     private function awstats_delete ($data, $web_config) {
58c210 2595         global $app;
7fe908 2596
58c210 2597         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2598
fb3339 2599         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2600             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
7fe908 2601             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2602         }
T 2603     }
7fe908 2604
274362 2605     //* Update the PHP-FPM pool configuration file
7fe908 2606     private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
274362 2607         global $app, $conf;
F 2608         //$reload = false;
7fe908 2609
62e4b3 2610         if($data['new']['php'] == 'php-fpm'){
F 2611             if(trim($data['new']['fastcgi_php_version']) != ''){
2612                 $default_php_fpm = false;
2613                 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 2614                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2615             } else {
F 2616                 $default_php_fpm = true;
2617             }
274362 2618         } else {
62e4b3 2619             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 2620                 $default_php_fpm = false;
2621                 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 2622                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2623             } else {
F 2624                 $default_php_fpm = true;
2625             }
274362 2626         }
7fe908 2627
274362 2628         $app->uses("getconf");
F 2629         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2630
274362 2631         if($data['new']['php'] != 'php-fpm'){
F 2632             if(@is_file($pool_dir.$pool_name.'.conf')){
c77103 2633                 $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 2634                 //$reload = true;
F 2635             }
2636             if($data['old']['php'] == 'php-fpm'){
2637                 if(!$default_php_fpm){
7fe908 2638                     $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2639                 } else {
7fe908 2640                     $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2641                 }
F 2642             }
2643             //if($reload == true) $app->services->restartService('php-fpm','reload');
2644             return;
2645         }
7fe908 2646
274362 2647         $app->load('tpl');
F 2648         $tpl = new tpl();
2649         $tpl->newTemplate('php_fpm_pool.conf.master');
8133de 2650         $tpl->setVar('apache_version', $app->system->getapacheversion());
MC 2651         
274362 2652         if($data['new']['php_fpm_use_socket'] == 'y'){
F 2653             $use_tcp = 0;
2654             $use_socket = 1;
c77103 2655             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
274362 2656         } else {
F 2657             $use_tcp = 1;
2658             $use_socket = 0;
2659         }
2660         $tpl->setVar('use_tcp', $use_tcp);
2661         $tpl->setVar('use_socket', $use_socket);
7fe908 2662
274362 2663         $fpm_socket = $socket_dir.$pool_name.'.sock';
F 2664         $tpl->setVar('fpm_socket', $fpm_socket);
b491ad 2665         $tpl->setVar('fpm_listen_mode', '0660');
7fe908 2666
274362 2667         $tpl->setVar('fpm_pool', $pool_name);
F 2668         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
2669         $tpl->setVar('fpm_user', $data['new']['system_user']);
2670         $tpl->setVar('fpm_group', $data['new']['system_group']);
dd7ce4 2671         $tpl->setVar('pm', $data['new']['pm']);
274362 2672         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
F 2673         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
2674         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
2675         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
dd7ce4 2676         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
F 2677         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
274362 2678         $tpl->setVar('document_root', $data['new']['document_root']);
7fe908 2679         $tpl->setVar('security_level', $web_config['security_level']);
f63910 2680         $tpl->setVar('domain', $data['new']['domain']);
274362 2681         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
F 2682         $tpl->setVar('php_open_basedir', $php_open_basedir);
2683         if($php_open_basedir != ''){
2684             $tpl->setVar('enable_php_open_basedir', '');
2685         } else {
2686             $tpl->setVar('enable_php_open_basedir', ';');
2687         }
7fe908 2688
274362 2689         // Custom php.ini settings
F 2690         $final_php_ini_settings = array();
2691         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
2692         if($custom_php_ini_settings != ''){
2693             // Make sure we only have Unix linebreaks
2694             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2695             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2696             $ini_settings = explode("\n", $custom_php_ini_settings);
2697             if(is_array($ini_settings) && !empty($ini_settings)){
2698                 foreach($ini_settings as $ini_setting){
254a4a 2699                     $ini_setting = trim($ini_setting);
7fe908 2700                     if(substr($ini_setting, 0, 1) == ';') continue;
MC 2701                     if(substr($ini_setting, 0, 1) == '#') continue;
2702                     if(substr($ini_setting, 0, 2) == '//') continue;
03cc01 2703                     list($key, $value) = explode('=', $ini_setting, 2);
1d6097 2704                     $value = trim($value);
FT 2705                     if($value != ''){
254a4a 2706                         $key = trim($key);
F 2707                         switch (strtolower($value)) {
7fe908 2708                         case '0':
MC 2709                             // PHP-FPM might complain about invalid boolean value if you use 0
2710                             $value = 'off';
2711                         case '1':
2712                         case 'on':
2713                         case 'off':
2714                         case 'true':
2715                         case 'false':
2716                         case 'yes':
2717                         case 'no':
2718                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
2719                             break;
2720                         default:
2721                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
274362 2722                         }
254a4a 2723                     }
274362 2724                 }
F 2725             }
2726         }
7fe908 2727
274362 2728         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
7fe908 2729
MC 2730         $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
2731         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
274362 2732         unset($tpl);
7fe908 2733
274362 2734         // delete pool in all other PHP versions
F 2735         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2736         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2737         if($default_pool_dir != $pool_dir){
F 2738             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2739                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2740                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2741                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2742             }
F 2743         }
2744         $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"]);
2745         if(is_array($php_versions) && !empty($php_versions)){
2746             foreach($php_versions as $php_version){
7fe908 2747                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2748                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2749                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2750                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2751                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2752                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2753                     }
F 2754                 }
2755             }
2756         }
2757         // Reload current PHP-FPM after all others
2758         sleep(1);
2759         if(!$default_php_fpm){
7fe908 2760             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2761         } else {
7fe908 2762             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2763         }
7fe908 2764
274362 2765         //$reload = true;
F 2766
2767         //if($reload == true) $app->services->restartService('php-fpm','reload');
2768     }
7fe908 2769
274362 2770     //* Delete the PHP-FPM pool configuration file
7fe908 2771     private function php_fpm_pool_delete ($data, $web_config) {
274362 2772         global $app, $conf;
7fe908 2773
62e4b3 2774         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
274362 2775             $default_php_fpm = false;
F 2776             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 2777             if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
274362 2778         } else {
F 2779             $default_php_fpm = true;
2780         }
7fe908 2781
274362 2782         if($default_php_fpm){
F 2783             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2784         } else {
2785             $pool_dir = $custom_php_fpm_pool_dir;
2786         }
7fe908 2787
MC 2788         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 2789         $pool_name = 'web'.$data['old']['domain_id'];
7fe908 2790
274362 2791         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
c77103 2792             $app->system->unlink($pool_dir.$pool_name.'.conf');
7fe908 2793             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2794
274362 2795             //$app->services->restartService('php-fpm','reload');
F 2796         }
7fe908 2797
274362 2798         // delete pool in all other PHP versions
F 2799         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2800         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2801         if($default_pool_dir != $pool_dir){
F 2802             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2803                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2804                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2805                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2806             }
7fe908 2807         }
274362 2808         $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 2809         if(is_array($php_versions) && !empty($php_versions)){
2810             foreach($php_versions as $php_version){
7fe908 2811                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2812                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2813                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2814                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2815                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2816                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2817                     }
F 2818                 }
2819             }
2820         }
7fe908 2821
274362 2822         // Reload current PHP-FPM after all others
F 2823         sleep(1);
2824         if(!$default_php_fpm){
7fe908 2825             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2826         } else {
7fe908 2827             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2828         }
F 2829     }
7fe908 2830
MC 2831     function client_delete($event_name, $data) {
1ca823 2832         global $app, $conf;
7fe908 2833
1ca823 2834         $app->uses("getconf");
T 2835         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2836
1ca823 2837         $client_id = intval($data['old']['client_id']);
T 2838         if($client_id > 0) {
7fe908 2839
1ca823 2840             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
7fe908 2841             if(is_dir($client_dir) && !stristr($client_dir, '..')) {
72695f 2842                 // remove symlinks from $client_dir
7fe908 2843                 $files = array_diff(scandir($client_dir), array('.', '..'));
72695f 2844                 if(is_array($files) && !empty($files)){
T 2845                     foreach($files as $file){
2846                         if(is_link($client_dir.'/'.$file)){
2847                             unlink($client_dir.'/'.$file);
7fe908 2848                             $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG);
72695f 2849                         }
T 2850                     }
2851                 }
7fe908 2852
1ca823 2853                 @rmdir($client_dir);
7fe908 2854                 $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG);
1ca823 2855             }
7fe908 2856
615a0a 2857             if($app->system->is_group('client'.$client_id)){
T 2858                 $this->_exec('groupdel client'.$client_id);
7fe908 2859                 $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG);
615a0a 2860             }
1ca823 2861         }
7fe908 2862
1ca823 2863     }
ac933e 2864
1c40af 2865     //* Wrapper for exec function for easier debugging
T 2866     private function _exec($command) {
2867         global $app;
7fe908 2868         $app->log('exec: '.$command, LOGLEVEL_DEBUG);
1c40af 2869         exec($command);
T 2870     }
7ed741 2871
7fe908 2872     private function _checkTcp ($host, $port) {
MC 2873
2874         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
7ed741 2875
T 2876         if ($fp) {
2877             fclose($fp);
2878             return true;
2879         } else {
2880             return false;
2881         }
2882     }
ac933e 2883
552178 2884     public function create_relative_link($f, $t) {
bfcdef 2885         global $app;
7fe908 2886
552178 2887         // $from already exists
M 2888         $from = realpath($f);
2889
2890         // realpath requires the traced file to exist - so, lets touch it first, then remove
c77103 2891         @$app->system->unlink($t); touch($t);
552178 2892         $to = realpath($t);
c77103 2893         @$app->system->unlink($t);
552178 2894
M 2895         // Remove from the left side matching path elements from $from and $to
2896         // and get path elements counts
2897         $a1 = explode('/', $from); $a2 = explode('/', $to);
2898         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
2899             unset($a1[$c]); unset($a2[$c]);
2900         }
2901         $cfrom = implode('/', $a1);
2902
2903         // Check if a path is fully a subpath of another - no way to create symlink in the case
2904         if (count($a1) == 0 || count($a2) == 0) return false;
2905
2906         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
2907         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
2908
2909         return symlink($cfrom, $to);
2910     }
46c683 2911
7fe908 2912     private function _rewrite_quote($string) {
MC 2913         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
2914     }
2915
2916     private function _is_url($string) {
2917         return preg_match('/^(f|ht)tp(s)?:\/\//i', $string);
2918     }
2919
bfcdef 2920     private function get_seo_redirects($web, $prefix = ''){
T 2921         $seo_redirects = array();
7fe908 2922
bfcdef 2923         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
7fe908 2924
bfcdef 2925         if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){
T 2926             if($web['seo_redirect'] == 'non_www_to_www'){
2927                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2928                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2929                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2930             }
2931             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
2932                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
2933                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
2934                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))';
2935                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2936                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2937             }
2938             if($web['seo_redirect'] == '*_to_www_domain_tld'){
2939                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2940                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2941                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2942             }
2943         }
2944         if($web['seo_redirect'] == 'www_to_non_www'){
2945             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2946             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2947             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2948         }
2949         if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
2950             // ^(.+)\.example\.com$
2951             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '(.+)\.'.str_replace('.', '\.', $web['domain']);
2952             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2953             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2954         }
2955         if($web['seo_redirect'] == '*_to_domain_tld'){
2956             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2957             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2958             $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2959         }
2960         return $seo_redirects;
2961     }
7fe908 2962
46c683 2963 } // end class
T 2964
c09f04 2965 ?>