apache2_plugin.inc.php 74.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

/*
Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of ISPConfig nor the names of its contributors
      may be used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

class apache2_plugin {
32

33
34
	var $plugin_name = 'apache2_plugin';
	var $class_name = 'apache2_plugin';
35

36
37
	// private variables
	var $action = '';
38

39
40
41
42
	//* This function is called during ispconfig installation to determine
	//  if a symlink shall be created for this plugin.
	function onInstall() {
		global $conf;
43

44
45
46
47
48
		if($conf['services']['web'] == true) {
			return true;
		} else {
			return false;
		}
49

50
	}
51
52


53
54
55
	/*
	 	This function is called when the plugin is loaded
	*/
56

57
58
	function onLoad() {
		global $app;
59

60
61
62
63
64
65
		/*
		Register for the events
		*/
		$app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl');
		$app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl');
		$app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl');
66

67
68
69
		$app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert');
		$app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update');
		$app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete');
70

71
72
73
		$app->plugins->registerEvent('server_ip_insert',$this->plugin_name,'server_ip');
		$app->plugins->registerEvent('server_ip_update',$this->plugin_name,'server_ip');
		$app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip');
74
75
76
77

		$app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav');
		$app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav');
		$app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav');
78
79
		
		$app->plugins->registerEvent('client_delete',$this->plugin_name,'client_delete');
80
81
82
83
84
		
		$app->plugins->registerEvent('web_folder_user_insert',$this->plugin_name,'web_folder_user');
		$app->plugins->registerEvent('web_folder_user_update',$this->plugin_name,'web_folder_user');
		$app->plugins->registerEvent('web_folder_user_delete',$this->plugin_name,'web_folder_user');
		
tbrehm's avatar
tbrehm committed
85
		$app->plugins->registerEvent('web_folder_update',$this->plugin_name,'web_folder_update');
86
87
		$app->plugins->registerEvent('web_folder_delete',$this->plugin_name,'web_folder_delete');
		
88
	}
89

90
91
92
	// Handle the creation of SSL certificates
	function ssl($event_name,$data) {
		global $app, $conf;
93
94
95
96
97
98

		// load the server configuration options
		$app->uses('getconf');
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
		if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
			$app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.conf',LOGLEVEL_ERROR);	
99
100
101
		
		//* Only vhosts can have a ssl cert
		if($data["new"]["type"] != "vhost") return;
102

103
104
105
106
107
108
109
		if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
		$ssl_dir = $data['new']['document_root'].'/ssl';
		$domain = $data['new']['ssl_domain'];
		$key_file = $ssl_dir.'/'.$domain.'.key.org';
		$key_file2 = $ssl_dir.'/'.$domain.'.key';
		$csr_file = $ssl_dir.'/'.$domain.'.csr';
		$crt_file = $ssl_dir.'/'.$domain.'.crt';
110

111
		//* Create a SSL Certificate
112
113
		if($data['new']['ssl_action'] == 'create') {
			$rand_file = $ssl_dir.'/random_file';
114
115
116
117
118
119
120
121
122
123
124
			$rand_data = md5(uniqid(microtime(),1));
			for($i=0; $i<1000; $i++) {
				$rand_data .= md5(uniqid(microtime(),1));
				$rand_data .= md5(uniqid(microtime(),1));
				$rand_data .= md5(uniqid(microtime(),1));
				$rand_data .= md5(uniqid(microtime(),1));
			}
			file_put_contents($rand_file, $rand_data);

			$ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15);

125
126
127
			$ssl_cnf = "        RANDFILE               = $rand_file

        [ req ]
128
        default_bits           = 2048
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
        default_keyfile        = keyfile.pem
        distinguished_name     = req_distinguished_name
        attributes             = req_attributes
        prompt                 = no
        output_password        = $ssl_password

        [ req_distinguished_name ]
        C                      = ".$data['new']['ssl_country']."
        ST                     = ".$data['new']['ssl_state']."
        L                      = ".$data['new']['ssl_locality']."
        O                      = ".$data['new']['ssl_organisation']."
        OU                     = ".$data['new']['ssl_organisation_unit']."
        CN                     = $domain
        emailAddress           = webmaster@".$data['new']['domain']."

        [ req_attributes ]
        challengePassword              = A challenge password";
146

147
			$ssl_cnf_file = $ssl_dir.'/openssl.conf';
148
			file_put_contents($ssl_cnf_file,$ssl_cnf);
149

150
151
152
153
154
155
156
157
			$rand_file = escapeshellcmd($rand_file);
			$key_file = escapeshellcmd($key_file);
			$key_file2 = escapeshellcmd($key_file2);
			$ssl_days = 3650;
			$csr_file = escapeshellcmd($csr_file);
			$config_file = escapeshellcmd($ssl_cnf_file);
			$crt_file = escapeshellcmd($crt_file);

158
			if(is_file($ssl_cnf_file)) {
159
				
160
161
				exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048");
				exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file");
162
163
164
				exec("openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2");

				if(file_exists($web_config['CA_path'].'/openssl.cnf'))
165
				{
166
					exec("openssl ca -batch -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file");
167
					$app->log("Creating CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
168
169
170
					if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file",LOGLEVEL_ERROR);
				};
				if (filesize($crt_file)==0 || !file_exists($crt_file)){
171
172
173
					exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file ");
					$app->log("Creating self-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
				};
174
			
175
			}
176

177
			exec('chmod 400 '.$key_file2);
178
179
180
181
			@unlink($config_file);
			@unlink($rand_file);
			$ssl_request = $app->db->quote(file_get_contents($csr_file));
			$ssl_cert = $app->db->quote(file_get_contents($crt_file));
182
			/* Update the DB of the (local) Server */
183
184
			$app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data['new']['domain']."'");
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
185
			/* Update also the master-DB of the Server-Farm */
186
187
			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data['new']['domain']."'");
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
188
		}
189

190
		//* Save a SSL certificate to disk
191
192
193
194
195
196
197
198
199
		if($data["new"]["ssl_action"] == 'save') {
			$ssl_dir = $data["new"]["document_root"]."/ssl";
			$domain = $data["new"]["ssl_domain"];
			$csr_file = $ssl_dir.'/'.$domain.".csr";
			$crt_file = $ssl_dir.'/'.$domain.".crt";
			$bundle_file = $ssl_dir.'/'.$domain.".bundle";
			if(trim($data["new"]["ssl_request"]) != '') file_put_contents($csr_file,$data["new"]["ssl_request"]);
			if(trim($data["new"]["ssl_cert"]) != '') file_put_contents($crt_file,$data["new"]["ssl_cert"]);
			if(trim($data["new"]["ssl_bundle"]) != '') file_put_contents($bundle_file,$data["new"]["ssl_bundle"]);
200
			/* Update the DB of the (local) Server */
201
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
202
			/* Update also the master-DB of the Server-Farm */
203
204
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
			$app->log('Saving SSL Cert for: '.$domain,LOGLEVEL_DEBUG);
205
		}
206

207
		//* Delete a SSL certificate
208
209
210
211
212
213
		if($data['new']['ssl_action'] == 'del') {
			$ssl_dir = $data['new']['document_root'].'/ssl';
			$domain = $data['new']['ssl_domain'];
			$csr_file = $ssl_dir.'/'.$domain.'.csr';
			$crt_file = $ssl_dir.'/'.$domain.'.crt';
			$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
214
			if(file_exists($web_config['CA_path'].'/openssl.cnf'))
215
				{
216
					exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke $crt_file");
217
218
					$app->log("Revoking CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG);
				};
219
220
221
			unlink($csr_file);
			unlink($crt_file);
			unlink($bundle_file);
222
			/* Update the DB of the (local) Server */
223
224
			$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
225
			/* Update also the master-DB of the Server-Farm */
226
227
228
			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
			$app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG);
229
		}
230
231


232
	}
233
234


235
236
	function insert($event_name,$data) {
		global $app, $conf;
237

238
239
240
		$this->action = 'insert';
		// just run the update function
		$this->update($event_name,$data);
241
242


243
	}
244
245


246
247
	function update($event_name,$data) {
		global $app, $conf;
248

249
		if($this->action != 'insert') $this->action = 'update';
250

251
		if($data['new']['type'] != 'vhost' && $data['new']['parent_domain_id'] > 0) {
252

253
254
			$old_parent_domain_id = intval($data['old']['parent_domain_id']);
			$new_parent_domain_id = intval($data['new']['parent_domain_id']);
255

256
			// If the parent_domain_id has been changed, we will have to update the old site as well.
257
258
259
260
			if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
				$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'");
				$data['new'] = $tmp;
				$data['old'] = $tmp;
261
262
263
				$this->action = 'update';
				$this->update($event_name,$data);
			}
264

265
			// This is not a vhost, so we need to update the parent record instead.
266
267
268
			$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'");
			$data['new'] = $tmp;
			$data['old'] = $tmp;
269
270
			$this->action = 'update';
		}
271

272
		// load the server configuration options
273
274
		$app->uses('getconf');
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
275

276
		//* Check if this is a chrooted setup
277
		if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
278
			$apache_chrooted = true;
279
			$app->log('Info: Apache is chrooted.',LOGLEVEL_DEBUG);
280
281
282
		} else {
			$apache_chrooted = false;
		}
283

284
285
		if($data['new']['document_root'] == '') {
			$app->log('document_root not set',LOGLEVEL_WARN);
286
287
			return 0;
		}
288
289
		if($data['new']['system_user'] == 'root' or $data['new']['system_group'] == 'root') {
			$app->log('Websites cannot be owned by the root user or group.',LOGLEVEL_WARN);
290
291
			return 0;
		}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
		
		// Create group and user, if not exist
		$app->uses('system');

		$groupname = escapeshellcmd($data['new']['system_group']);
		if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
			exec('groupadd '.$groupname);
			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
			$app->log('Adding the group: '.$groupname,LOGLEVEL_DEBUG);
		}

		$username = escapeshellcmd($data['new']['system_user']);
		if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
			exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname -G sshusers $username -s /bin/false");
			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname -G sshusers $username -s /bin/false");
			$app->log('Adding the user: '.$username,LOGLEVEL_DEBUG);
		}
309

310
		//* If the client of the site has been changed, we have a change of the document root
311
		if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
312

313
			//* Get the old client ID
314
315
			$old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
			$old_client_id = intval($old_client['client_id']);
316
			unset($old_client);
317

318
			//* Remove the old symlinks
319
			$tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
320
321
			if(is_array($tmp_symlinks_array)) {
				foreach($tmp_symlinks_array as $tmp_symlink) {
322
323
					$tmp_symlink = str_replace('[client_id]',$old_client_id,$tmp_symlink);
					$tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
324
325
326
					// Remove trailing slash
					if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
					// create the symlinks, if not exist
327
					if(is_link($tmp_symlink)) {
328
329
						exec('rm -f '.escapeshellcmd($tmp_symlink));
						$app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG);
330
331
332
					}
				}
			}
333

334
			//* Move the site data
335
			$tmp_docroot = explode('/',$data['new']['document_root']);
336
337
			unset($tmp_docroot[count($tmp_docroot)-1]);
			$new_dir = implode('/',$tmp_docroot);
338

339
			$tmp_docroot = explode('/',$data['old']['document_root']);
340
341
			unset($tmp_docroot[count($tmp_docroot)-1]);
			$old_dir = implode('/',$tmp_docroot);
342

343
			exec('rm -rf '.$data['new']['document_root']);
344
			if(!is_dir($new_dir)) exec('mkdir -p '.$new_dir);
345
346
			exec('mv '.$data['old']['document_root'].' '.$new_dir);
			$app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir,LOGLEVEL_DEBUG);
347

348
349
350
			// Handle the change in php_open_basedir
			$data['new']['php_open_basedir'] = str_replace($data['old']['document_root'],$data['new']['document_root'],$data['old']['php_open_basedir']);

351
			//* Change the owner of the website files to the new website owner
352
			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);
353

354
355
			//* Change the home directory and group of the website user
			$command = 'usermod';
356
			$command .= ' --home '.escapeshellcmd($data['new']['document_root']);
357
			$command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
358
			$command .= ' '.escapeshellcmd($data['new']['system_user']);
359
			exec($command);
360

361
			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
362
363


364
		}
365

366
		//print_r($data);
367

368
369
370
371
372
373
374
		// Check if the directories are there and create them if necessary.
		if(!is_dir($data['new']['document_root'].'/web')) exec('mkdir -p '.$data['new']['document_root'].'/web');
		if(!is_dir($data['new']['document_root'].'/web/error') and $data['new']['errordocs']) exec('mkdir -p '.$data['new']['document_root'].'/web/error');
		//if(!is_dir($data['new']['document_root'].'/log')) exec('mkdir -p '.$data['new']['document_root'].'/log');
		if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
		if(!is_dir($data['new']['document_root'].'/cgi-bin')) exec('mkdir -p '.$data['new']['document_root'].'/cgi-bin');
		if(!is_dir($data['new']['document_root'].'/tmp')) exec('mkdir -p '.$data['new']['document_root'].'/tmp');
375

376
		// Remove the symlink for the site, if site is renamed
377
378
379
		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
			if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
			if(is_link($data['old']['document_root'].'/log')) unlink($data['old']['document_root'].'/log');
380
		}
381

382
		// Create the symlink for the logfiles
383
384
		if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
		if(!is_link($data['new']['document_root'].'/log')) {
385
386
387
388
389
390
391
//			exec("ln -s /var/log/ispconfig/httpd/".$data["new"]["domain"]." ".$data["new"]["document_root"]."/log");
			if ($web_config["website_symlinks_rel"] == 'y') {
				$this->create_relative_link("/var/log/ispconfig/httpd/".$data["new"]["domain"], $data["new"]["document_root"]."/log");
			} else {
				exec("ln -s /var/log/ispconfig/httpd/".$data["new"]["domain"]." ".$data["new"]["document_root"]."/log");
			}

392
			$app->log('Creating symlink: ln -s /var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/log',LOGLEVEL_DEBUG);
393
394
395
		}
		/*
		// Create the symlink for the logfiles
396
397
398
399
		// This does not work as vlogger cannot log trough symlinks.
		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
			if(is_dir($data['old']['document_root'].'/log')) exec('rm -rf '.$data['old']['document_root'].'/log');
			if(is_link('/var/log/ispconfig/httpd/'.$data['old']['domain'])) unlink('/var/log/ispconfig/httpd/'.$data['old']['domain']);
400
401
402
		}
		
		// Create the symlink for the logfiles
403
404
405
406
		if(!is_dir($data['new']['document_root'].'/log')) exec('mkdir -p '.$data['new']['document_root'].'/log');
		if(!is_link('/var/log/ispconfig/httpd/'.$data['new']['domain'])) {
			exec('ln -s '.$data['new']['document_root'].'/log /var/log/ispconfig/httpd/'.$data['new']['domain']);
			$app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/log /var/log/ispconfig/httpd/'.$data['new']['domain'],LOGLEVEL_DEBUG);
407
408
		}
		*/
409

410
		// Get the client ID
411
412
		$client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
		$client_id = intval($client['client_id']);
413
		unset($client);
414

415
		// Remove old symlinks, if site is renamed
416
417
		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
			$tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
418
419
			if(is_array($tmp_symlinks_array)) {
				foreach($tmp_symlinks_array as $tmp_symlink) {
420
421
					$tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
					$tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
422
423
424
425
					// Remove trailing slash
					if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
					// remove the symlinks, if not exist
					if(is_link($tmp_symlink)) {
426
427
						exec('rm -f '.escapeshellcmd($tmp_symlink));
						$app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG);
428
429
430
431
					}
				}
			}
		}
432

433
		// Create the symlinks for the sites
434
		$tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
435
436
		if(is_array($tmp_symlinks_array)) {
			foreach($tmp_symlinks_array as $tmp_symlink) {
437
438
				$tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
				$tmp_symlink = str_replace('[website_domain]',$data['new']['domain'],$tmp_symlink);
439
440
441
				// Remove trailing slash
				if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
				//* Remove symlink if target folder has been changed.
442
				if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
443
444
445
446
					unlink($tmp_symlink);
				}
				// create the symlinks, if not exist
				if(!is_link($tmp_symlink)) {
447
448
449
450
451
452
453
//					exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
					if ($web_config["website_symlinks_rel"] == 'y') {
						$this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
					} else {
						exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
					}

454
					$app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink,LOGLEVEL_DEBUG);
455
456
457
				}
			}
		}
458
459


latham's avatar
latham committed
460
461
462
463
464
465
466
467

        // Install the Standard or Custom Error, Index and other related files
        // /usr/local/ispconfig/server/conf is for the standard files
        // /usr/local/ispconfig/server/conf-custom is for the custom files
        // setting a local var here
           
        // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";

468
		if($this->action == 'insert' && $data['new']['type'] == 'vhost') {
469
			// Copy the error pages
470
471
			if($data['new']['errordocs']) {
				$error_page_path = escapeshellcmd($data['new']['document_root']).'/web/error/';
472
473
				if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
474
475
				}
				else {
476
477
					if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
						exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
478
479
					}
					else {
480
						exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
481
482
					}
				}
483
				exec('chmod -R a+r '.$error_page_path);
484
485
			}

486
487
			if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2))) {
				exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/web/index.html');
latham's avatar
latham committed
488
            
489
490
			if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
                exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/web/');
latham's avatar
latham committed
491
            }
492
493
			if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
                exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/web/');
latham's avatar
latham committed
494
                }
495
496
                if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
                    exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/web/');
latham's avatar
latham committed
497
498
                }
            }
499
			else {
500
501
				if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/web/index.html');
502
503
				}
				else {
504
505
506
507
					exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/web/index.html');
					if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/web/');
					if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/web/');
					if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/web/');
508
509
				}
			}
510
			exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/web/');
511
512

			//** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
513
		} elseif ($this->action == 'update' && $data['new']['type'] == 'vhost' && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
514

515
			$error_page_path = escapeshellcmd($data['new']['document_root']).'/web/error/';
516
517
			if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) {
				exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
518
519
			}
			else {
520
521
				if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
522
523
				}
				else {
524
					exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path);
525
526
				}
			}
527
			exec('chmod -R a+r '.$error_page_path);
latham's avatar
latham committed
528
			exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
529
		}  // end copy error docs
530

531
532
		// Set the quota for the user
		if($username != '' && $app->system->is_user($username)) {
533
534
			if($data['new']['hd_quota'] > 0) {
				$blocks_soft = $data['new']['hd_quota'] * 1024;
535
536
537
538
				$blocks_hard = $blocks_soft + 1024;
			} else {
				$blocks_soft = $blocks_hard = 0;
			}
539
			exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
540
			exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
541
		}
542

543
		if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
544
			// Chown and chmod the directories below the document root
545
			$this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
546
547
			// The document root itself has to be owned by root in normal level and by the web owner in security level 20
			if($web_config['security_level'] == 20) {
548
				$this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
549
			} else {
550
				$this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
551
			}
552
		}
553
554
555



556
		//* If the security level is set to high
tbrehm's avatar
tbrehm committed
557
		if($web_config['security_level'] == 20) {
558

559
560
561
			$this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']));
			$this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']).'/*');
			$this->_exec('chmod 710 '.escapeshellcmd($data['new']['document_root'].'/web'));
562

563
564
			// make tmp directory writable for Apache and the website users
			$this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
565
566
567
			
			// Set Log symlink to 755 to make the logs accessible by the FTP user
			$this->_exec("chmod 755 ".escapeshellcmd($data["new"]["document_root"])."/log");
568

569
570
			$command = 'usermod';
			$command .= ' --groups sshusers';
571
			$command .= ' '.escapeshellcmd($data['new']['system_user']);
572
			$this->_exec($command);
573

574
			//* if we have a chrooted Apache environment
575
			if($apache_chrooted) {
576
				$this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
577

578
579
580
				//* add the apache user to the client group in the chroot environment
				$tmp_groupfile = $app->system->server_conf['group_datei'];
				$app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
581
				$app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
582
				$app->system->server_conf['group_datei'] = $tmp_groupfile;
583
584
				unset($tmp_groupfile);
			}
585

586
			//* add the Apache user to the client group
tbrehm's avatar
tbrehm committed
587
			$app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
588

589
			$this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
590

591
592
593
594
			/*
			* Workaround for jailkit: If jailkit is enabled for the site, the 
			* website root has to be owned by the root user and we have to chmod it to 755 then
			*/
595

596
			//* Check if there is a jailkit user for this site
597
			$tmp = $app->db->queryOneRecord('SELECT count(shell_user_id) as number FROM shell_user WHERE parent_domain_id = '.$data['new']['domain_id']." AND chroot = 'jailkit'");
598
			if($tmp['number'] > 0) {
599
600
				$this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root']));
				$this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
601
602
			}
			unset($tmp);
603
604

			// If the security Level is set to medium
tbrehm's avatar
tbrehm committed
605
		} else {
606

607
608
609
			$this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root']));
			$this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/*'));
			$this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']));
610

611
612
			// make temp directory writable for Apache and the website users
			$this->_exec('chmod 777 '.escapeshellcmd($data['new']['document_root'].'/tmp'));
tbrehm's avatar
tbrehm committed
613
		}
614

615
616
617
		// Change the ownership of the error log to the owner of the website
		if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
		$this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
618
619


620
		//* Write the custom php.ini file, if custom_php_ini filed is not empty
621
		$custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
622
		if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf');
623
		if(trim($data['new']['custom_php_ini']) != '') {
624
625
626
			$has_custom_php_ini = true;
			if(!is_dir($custom_php_ini_dir)) mkdir($custom_php_ini_dir);
			$php_ini_content = '';
627
			if($data['new']['php'] == 'mod') {
628
629
				$master_php_ini_path = $web_config['php_ini_path_apache'];
			} else {
630
631
632
633
634
				if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
					$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
				} else {
					$master_php_ini_path = $web_config['php_ini_path_cgi'];
				}
635
636
637
638
			}
			if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
				$php_ini_content .= file_get_contents($master_php_ini_path)."\n";
			}
639
			$php_ini_content .= trim($data['new']['custom_php_ini']);
640
641
642
643
644
645
646
647
			file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
		} else {
			$has_custom_php_ini = false;
			if(is_file($custom_php_ini_dir.'/php.ini')) unlink($custom_php_ini_dir.'/php.ini');
		}


		//* Create the vhost config file
648
		$app->load('tpl');
649

650
		$tpl = new tpl();
651
652
653
		$tpl->newTemplate('vhost.conf.master');

		$vhost_data = $data['new'];
tbrehm's avatar
tbrehm committed
654
		//unset($vhost_data['ip_address']);
655
656
657
658
659
660
661
662
663
		$vhost_data['web_document_root'] = $data['new']['document_root'].'/web';
		$vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/web';
		$vhost_data['web_basedir'] = $web_config['website_basedir'];
		$vhost_data['security_level'] = $web_config['security_level'];
		$vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override'];
		$vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
		$vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
		$vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
		$vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
664

665
		// Check if a SSL cert exists
666
667
668
669
670
671
		$ssl_dir = $data['new']['document_root'].'/ssl';
		$domain = $data['new']['ssl_domain'];
		$key_file = $ssl_dir.'/'.$domain.'.key';
		$crt_file = $ssl_dir.'/'.$domain.'.crt';
		$bundle_file = $ssl_dir.'/'.$domain.'.bundle';

tbrehm's avatar
tbrehm committed
672
		/*
673
		if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
674
675
			$vhost_data['ssl_enabled'] = 1;
			$app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
676
		} else {
677
			$vhost_data['ssl_enabled'] = 0;
678
			$app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
679
		}
tbrehm's avatar
tbrehm committed
680
		*/
681

682
		if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
683

684
		//$vhost_data['document_root'] = $data['new']['document_root'].'/web';
Falko Timme's avatar
Falko Timme committed
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
		
		// Set SEO Redirect
		if($data['new']['seo_redirect'] != '' && ($data['new']['subdomain'] == 'www' || $data['new']['subdomain'] == '*')){
			$vhost_data['seo_redirect_enabled'] = 1;
			if($data['new']['seo_redirect'] == 'non_www_to_www'){
				$vhost_data['seo_redirect_origin_domain'] = $data['new']['domain'];
				$vhost_data['seo_redirect_target_domain'] = 'www.'.$data['new']['domain'];
			}
			if($data['new']['seo_redirect'] == 'www_to_non_www'){
				$vhost_data['seo_redirect_origin_domain'] = 'www.'.$data['new']['domain'];
				$vhost_data['seo_redirect_target_domain'] = $data['new']['domain'];
			}
		} else {
			$vhost_data['seo_redirect_enabled'] = 0;
		}
		
701
		$tpl->setVar($vhost_data);
702

703
704
		// Rewrite rules
		$rewrite_rules = array();
705
706
		if($data['new']['redirect_type'] != '') {
			if(substr($data['new']['redirect_path'],-1) != '/') $data['new']['redirect_path'] .= '/';
707
708
709
710
711
712
713
			if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){
				$rewrite_target = 'http'.substr($data['new']['redirect_path'],8);
				$rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'],8);
			} else {
				$rewrite_target = $data['new']['redirect_path'];
				$rewrite_target_ssl = $data['new']['redirect_path'];
			}
tbrehm's avatar
tbrehm committed
714
			/* Disabled path extension
715
716
			if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
				$data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
717
			}
tbrehm's avatar
tbrehm committed
718
			*/
719

720
			switch($data['new']['subdomain']) {
721
				case 'www':
Falko Timme's avatar
Falko Timme committed
722
723
724
725
726
					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$data['new']['domain'],
						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
						'rewrite_target' 	=> $rewrite_target,
						'rewrite_target_ssl' => $rewrite_target_ssl);
					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^www.'.$data['new']['domain'],
727
							'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
Falko Timme's avatar
Falko Timme committed
728
729
							'rewrite_target' 	=> $rewrite_target,
							'rewrite_target_ssl' => $rewrite_target_ssl);
730
731
					break;
				case '*':
Falko Timme's avatar
Falko Timme committed
732
733
734
735
					$rewrite_rules[] = array(	'rewrite_domain' 	=> $data['new']['domain'],
						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
						'rewrite_target' 	=> $rewrite_target,
						'rewrite_target_ssl' => $rewrite_target_ssl);
736
					break;
Falko Timme's avatar
Falko Timme committed
737
738
739
740
741
				default:
					$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$data['new']['domain'],
						'rewrite_type' 		=> ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
						'rewrite_target' 	=> $rewrite_target,
						'rewrite_target_ssl' => $rewrite_target_ssl);
742
			}
743
		}
744

745
		// get alias domains (co-domains and subdomains)
746
		$aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y'");
747
		$server_alias = array();
748
		switch($data['new']['subdomain']) {
749
			case 'www':
750
				$server_alias[] .= 'www.'.$data['new']['domain'].' ';
751
752
				break;
			case '*':
753
				$server_alias[] .= '*.'.$data['new']['domain'].' ';
754
755
				break;
		}
756
757
		if(is_array($aliases)) {
			foreach($aliases as $alias) {
758
				switch($alias['subdomain']) {
759
					case 'www':
760
						$server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' ';
761
762
						break;
					case '*':
763
						$server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' ';
764
765
						break;
					default:
766
						$server_alias[] .= $alias['domain'].' ';
767
768
						break;
				}
769
				$app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG);
770
				// Rewriting
771
				if($alias['redirect_type'] != '') {
Falko Timme's avatar
Falko Timme committed
772
773
774
775
776
777
778
779
					if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/';
					if(substr($alias['redirect_path'],0,8) == '[scheme]'){
						$rewrite_target = 'http'.substr($alias['redirect_path'],8);
						$rewrite_target_ssl = 'https'.substr($alias['redirect_path'],8);
					} else {
						$rewrite_target = $alias['redirect_path'];
						$rewrite_target_ssl = $alias['redirect_path'];
					}
tbrehm's avatar
tbrehm committed
780
					/* Disabled the path extension
781
782
					if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
						$data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
783
					}
tbrehm's avatar
tbrehm committed
784
					*/
Falko Timme's avatar
Falko Timme committed
785
					
786
					switch($alias['subdomain']) {
787
						case 'www':
Falko Timme's avatar
Falko Timme committed
788
789
790
791
792
							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$alias['domain'],
								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
								'rewrite_target' 	=> $rewrite_target,
								'rewrite_target_ssl' => $rewrite_target_ssl);
							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^www.'.$alias['domain'],
793
									'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
Falko Timme's avatar
Falko Timme committed
794
795
									'rewrite_target' 	=> $rewrite_target,
									'rewrite_target_ssl' => $rewrite_target_ssl);
796
797
							break;
						case '*':
Falko Timme's avatar
Falko Timme committed
798
799
800
801
							$rewrite_rules[] = array(	'rewrite_domain' 	=> $alias['domain'],
								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
								'rewrite_target' 	=> $rewrite_target,
								'rewrite_target_ssl' => $rewrite_target_ssl);
802
							break;
Falko Timme's avatar
Falko Timme committed
803
804
805
806
807
						default:
							$rewrite_rules[] = array(	'rewrite_domain' 	=> '^'.$alias['domain'],
								'rewrite_type' 		=> ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
								'rewrite_target' 	=> $rewrite_target,
								'rewrite_target_ssl' => $rewrite_target_ssl);
808
					}
809
810
811
				}
			}
		}
812

813
814
815
816
		//* If we have some alias records
		if(count($server_alias) > 0) {
			$server_alias_str = '';
			$n = 0;
817

818
819
820
821
822
823
			// begin a new ServerAlias line after 30 alias domains
			foreach($server_alias as $tmp_alias) {
				if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
				$server_alias_str .= $tmp_alias;
			}
			unset($tmp_alias);
824

825
826
827
828
			$tpl->setVar('alias',trim($server_alias_str));
		} else {
			$tpl->setVar('alias','');
		}
829

830
831
832
833
834
835
		if(count($rewrite_rules) > 0) {
			$tpl->setVar('rewrite_enabled',1);
		} else {
			$tpl->setVar('rewrite_enabled',0);
		}
		$tpl->setLoop('redirects',$rewrite_rules);
836
837
838

		/**
		 * install fast-cgi starter script and add script aliasd config
839
840
841
842
		 * first we create the script directory if not already created, then copy over the starter script
		 * settings are copied over from the server ini config for now
		 * TODO: Create form for fastcgi configs per site.
		 */
843

844
845
		if ($data['new']['php'] == 'fast-cgi') {
			$fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
846

847
848
			$fastcgi_starter_path = str_replace('[system_user]',$data['new']['system_user'],$fastcgi_config['fastcgi_starter_path']);
			$fastcgi_starter_path = str_replace('[client_id]',$client_id,$fastcgi_starter_path);
849
850

			if (!is_dir($fastcgi_starter_path)) {
851
852
				exec('mkdir -p '.escapeshellcmd($fastcgi_starter_path));
				//exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
853
854


855
				$app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path,LOGLEVEL_DEBUG);
856
			}
857

858
			exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));