Newer
Older
exec('chmod 755 '.$fcgi_starter_script);
exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$fcgi_starter_script);
$tpl->setVar('fastcgi_alias',$fastcgi_config['fastcgi_alias']);
$tpl->setVar('fastcgi_starter_path',$fastcgi_starter_path);
$tpl->setVar('fastcgi_starter_script',$fastcgi_config['fastcgi_starter_script']);
$tpl->setVar('fastcgi_config_syntax',$fastcgi_config['fastcgi_config_syntax']);
} else {
//remove the php fastgi starter script if available
if ($data['old']['php'] == 'fast-cgi') {
$fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
$fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$fastcgi_config['fastcgi_starter_path']);
$fastcgi_starter_path = str_replace('[client_id]',$client_id,$fastcgi_starter_path);
if (is_dir($fastcgi_starter_path)) {
exec('rm -rf '.$fastcgi_starter_path);
}
}
/**
* PHP-FPM
*/
// Support for multiple PHP versions
if($data['new']['php'] == 'php-fpm'){
if(trim($data['new']['fastcgi_php_version']) != ''){
$default_php_fpm = false;
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']));
if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
} else {
$default_php_fpm = true;
}
if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
$default_php_fpm = false;
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']));
if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
} else {
$default_php_fpm = true;
}
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
}
if($default_php_fpm){
$pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
} else {
$pool_dir = $custom_php_fpm_pool_dir;
}
if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
$pool_name = 'web'.$data['new']['domain_id'];
$socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
if(substr($socket_dir,-1) != '/') $socket_dir .= '/';
if($data['new']['php_fpm_use_socket'] == 'y'){
$use_tcp = 0;
$use_socket = 1;
} else {
$use_tcp = 1;
$use_socket = 0;
}
$tpl->setVar('use_tcp', $use_tcp);
$tpl->setVar('use_socket', $use_socket);
$fpm_socket = $socket_dir.$pool_name.'.sock';
$tpl->setVar('fpm_socket', $fpm_socket);
$tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
/**
* install cgi starter script and add script alias to config.
* This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
* first we create the script directory if not already created, then copy over the starter script.
* TODO: we have to fetch the data from the server-settings.
*/
if ($data['new']['php'] == 'cgi') {
//$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
$cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
$cgi_config['cgi_starter_script'] = 'php-cgi-starter';
$cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
$cgi_starter_path = str_replace('[system_user]',$data['new']['system_user'],$cgi_config['cgi_starter_path']);
$cgi_starter_path = str_replace('[client_id]',$client_id,$cgi_starter_path);
exec('mkdir -p '.escapeshellcmd($cgi_starter_path));
exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($cgi_starter_path));
$app->log('Creating cgi starter script directory: '.$cgi_starter_path,LOGLEVEL_DEBUG);
}
$cgi_tpl = new tpl();
$cgi_tpl->newTemplate('php-cgi-starter.master');
// This works because PHP "rewrites" a symlink to the physical path
$php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
$cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
$cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
// This will NOT work!
//$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
$cgi_tpl->setVar('php_cgi_bin',$cgi_config['cgi_bin']);
$cgi_tpl->setVar('security_level',$web_config['security_level']);
$cgi_tpl->setVar('has_custom_php_ini',$has_custom_php_ini);
if($has_custom_php_ini) {
$cgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_php_ini_dir));
} else {
$cgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
$cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script']);
file_put_contents($cgi_starter_script,$cgi_tpl->grab());
unset($cgi_tpl);
$app->log('Creating cgi starter script: '.$cgi_starter_script,LOGLEVEL_DEBUG);
exec('chmod 755 '.$cgi_starter_script);
exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$cgi_starter_script);
$tpl->setVar('cgi_starter_path',$cgi_starter_path);
$tpl->setVar('cgi_starter_script',$cgi_config['cgi_starter_script']);
}
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
//* Make a backup copy of vhost file
tbrehm
committed
if(file_exists($vhost_file)) copy($vhost_file,$vhost_file.'~');
//* create empty vhost array
$vhosts = array();
//* Add vhost for ipv4 IP
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
}
$ssl_dir = $data['new']['document_root'].'/ssl';
$domain = $data['new']['ssl_domain'];
$key_file = $ssl_dir.'/'.$domain.'.key';
$crt_file = $ssl_dir.'/'.$domain.'.crt';
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)) {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
}
$app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
}
//* Add vhost for IPv6 IP
if($data['new']['ipv6_address'] != '') {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
}
//* Add vhost for ipv6 IP with SSL
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)) {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
}
$app->log('Enable SSL for IPv6: '.$domain,LOGLEVEL_DEBUG);
}
}
//* Set the vhost loop
$tpl->setLoop('vhosts',$vhosts);
//* Write vhost file
file_put_contents($vhost_file,$tpl->grab());
$app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
unset($tpl);
/*
* maybe we have some webdav - user. If so, add them...
*/
$this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
//* Set the symlink to enable the vhost
//* First we check if there is a old type of symlink and remove it
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
if(is_link($vhost_symlink)) unlink($vhost_symlink);
//* Remove old or changed symlinks
if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
}
//* New symlink
if($data['new']['subdomain'] == '*') {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
} else {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
}
if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
symlink($vhost_file,$vhost_symlink);
$app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
// remove old symlink and vhost file, if domain name of the site has changed
if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
unlink($vhost_file);
$app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG);
//* Create .htaccess and .htpasswd file for website statistics
if(!is_file($data['new']['document_root'].'/web/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
if(!is_dir($data['new']['document_root'].'/web/stats')) mkdir($data['new']['document_root'].'/web/stats');
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/.htpasswd_stats\nrequire valid-user";
file_put_contents($data['new']['document_root'].'/web/stats/.htaccess',$ht_file);
chmod($data['new']['document_root'].'/web/stats/.htaccess',0755);
unset($ht_file);
}
if(!is_file($data['new']['document_root'].'/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
if(trim($data['new']['stats_password']) != '') {
$htp_file = 'admin:'.trim($data['new']['stats_password']);
$app->system->web_folder_protection($data['new']['document_root'],false);
file_put_contents($data['new']['document_root'].'/.htpasswd_stats',$htp_file);
$app->system->web_folder_protection($data['new']['document_root'],true);
chmod($data['new']['document_root'].'/.htpasswd_stats',0755);
unset($htp_file);
}
}
//* Create awstats configuration
if($data['new']['stats_type'] == 'awstats' && $data['new']['type'] == 'vhost') {
$this->awstats_update($data,$web_config);
}
$this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir);
if($web_config['check_apache_config'] == 'y') {
//* Test if apache starts with the new configuration file
$apache_online_status_before_restart = $this->_checkTcp('localhost',80);
$app->log('Apache status is: '.$apache_online_status_before_restart,LOGLEVEL_DEBUG);
$app->services->restartService('httpd','restart');
// wait a few seconds, before we test the apache status again
sleep(2);
//* Check if apache restarted successfully if it was online before
$apache_online_status_after_restart = $this->_checkTcp('localhost',80);
$app->log('Apache online status after restart is: '.$apache_online_status_after_restart,LOGLEVEL_DEBUG);
if($apache_online_status_before_restart && !$apache_online_status_after_restart) {
$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);
copy($vhost_file,$vhost_file.'.err');
if(is_file($vhost_file.'~')) {
//* Copy back the last backup file
copy($vhost_file.'~',$vhost_file);
} else {
//* There is no backup file, so we create a empty vhost file with a warning message inside
file_put_contents($vhost_file,"# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
}
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
if($this->ssl_certificate_changed === true) {
$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';
$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
//* Backup the files that might have caused the error
if(is_file($key_file)) copy($key_file,$key_file.'.err');
if(is_file($key_file2)) copy($key_file2,$key_file2.'.err');
if(is_file($csr_file)) copy($csr_file,$csr_file.'.err');
if(is_file($crt_file)) copy($crt_file,$crt_file.'.err');
if(is_file($bundle_file)) copy($bundle_file,$bundle_file.'.err');
//* Restore the ~ backup files
if(is_file($key_file.'~')) copy($key_file.'~',$key_file);
if(is_file($key_file2.'~')) copy($key_file2.'~',$key_file2);
if(is_file($crt_file.'~')) copy($crt_file.'~',$crt_file);
if(is_file($csr_file.'~')) copy($csr_file.'~',$csr_file);
if(is_file($bundle_file.'~')) copy($bundle_file.'~',$bundle_file);
$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);
}
$app->services->restartService('httpd','restart');
}
} else {
//* We do not check the apache config after changes (is faster)
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
//* The vhost is written and apache has been restarted, so we
// can reset the ssl changed var to false and cleanup some files
$this->ssl_certificate_changed = false;
$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';
$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
if(@is_file($key_file.'~')) unlink($key_file.'~');
if(@is_file($key2_file.'~')) unlink($key2_file.'~');
if(@is_file($crt_file.'~')) unlink($crt_file.'~');
if(@is_file($csr_file.'~')) unlink($csr_file.'~');
if(@is_file($bundle_file.'~')) unlink($bundle_file.'~');
// Remove the backup copy of the config file.
if(@is_file($vhost_file.'~')) unlink($vhost_file.'~');
//* Unset action to clean it for next processed vhost.
$this->action = '';
function delete($event_name,$data) {
global $app, $conf;
// load the server configuration options
$app->uses('getconf');
$app->uses('system');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
$app->system->web_folder_protection($data['new']['document_root'],false);
tbrehm
committed
//* Check if this is a chrooted setup
if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
tbrehm
committed
$apache_chrooted = true;
} else {
$apache_chrooted = false;
}
if($data['old']['type'] != 'vhost' && $data['old']['parent_domain_id'] > 0) {
//* This is a alias domain or subdomain, so we have to update the website instead
$parent_domain_id = intval($data['old']['parent_domain_id']);
$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
$data['new'] = $tmp;
$data['old'] = $tmp;
$this->action = 'update';
// just run the update function
$this->update($event_name,$data);
} else {
//* This is a website
// Deleting the vhost file, symlink and the data directory
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
unlink($vhost_file);
$app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
$docroot = escapeshellcmd($data['old']['document_root']);
if($docroot != '' && !stristr($docroot,'..')) exec('rm -rf '.$docroot);
//remove the php fastgi starter script if available
if ($data['old']['php'] == 'fast-cgi') {
$fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']);
exec('rm -rf '.$fastcgi_starter_path);
// remove PHP-FPM pool
if ($data['old']['php'] == 'php-fpm') {
$this->php_fpm_pool_delete($data,$web_config);
}
//remove the php cgi starter script if available
if ($data['old']['php'] == 'cgi') {
// TODO: fetch the date from the server-settings
$web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
$cgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['cgi_starter_path']);
exec('rm -rf '.$cgi_starter_path);
}
}
$app->log('Removing website: '.$docroot,LOGLEVEL_DEBUG);
// Delete the symlinks for the sites
$client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
$client_id = intval($client['client_id']);
unset($client);
$tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
if(is_array($tmp_symlinks_array)) {
foreach($tmp_symlinks_array as $tmp_symlink) {
$tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
$tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
// Remove trailing slash
if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
// create the symlinks, if not exist
if(is_link($tmp_symlink)) {
unlink($tmp_symlink);
$app->log('Removing symlink: '.$tmp_symlink,LOGLEVEL_DEBUG);
}
}
}
// end removing symlinks
// Delete the log file directory
$vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir);
$app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG);
//delete the web user
$command = 'userdel';
$command .= ' '.$data['old']['system_user'];
exec($command);
if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
//* Remove the awstats configuration file
if($data['old']['stats_type'] == 'awstats') {
$this->awstats_delete($data,$web_config);
}
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
//* This function is called when a IP on the server is inserted, updated or deleted
function server_ip($event_name,$data) {
global $app, $conf;
// load the server configuration options
$app->uses('getconf');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
$app->load('tpl');
$tpl = new tpl();
$tpl->newTemplate('apache_ispconfig.conf.master');
$records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
$records_out= array();
if(is_array($records)) {
foreach($records as $rec) {
if($rec['ip_type'] == 'IPv6') {
$ip_address = '['.$rec['ip_address'].']';
} else {
$ip_address = $rec['ip_address'];
}
$ports = explode(',',$rec['virtualhost_port']);
if(is_array($ports)) {
foreach($ports as $port) {
$port = intval($port);
if($port > 0 && $port < 65536 && $ip_address != '') {
$records_out[] = array('ip_address' => $ip_address, 'port' => $port);
}
}
}
}
}
if(count($records_out) > 0) {
$tpl->setLoop('ip_adresses',$records_out);
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
file_put_contents($vhost_file,$tpl->grab());
$app->log('Writing the conf file: '.$vhost_file,LOGLEVEL_DEBUG);
unset($tpl);
}
//* Create or update the .htaccess folder protection
function web_folder_user($event_name,$data) {
global $app, $conf;
$app->uses('system');
if($event_name == 'web_folder_user_delete') {
$folder_id = $data['old']['web_folder_id'];
} else {
$folder_id = $data['new']['web_folder_id'];
}
$folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
if(!is_array($folder) or !is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
$folder_path = escapeshellcmd($website['document_root'].'/web/'.$folder['path']);
if(substr($folder_path,-1) != '/') $folder_path .= '/';
//* Check if the resulting path is inside the docroot
if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) {
$app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
//* Create the folder path, if it does not exist
if(!is_dir($folder_path)) {
exec('mkdir -p '.$folder_path);
chown($folder_path,$website['system_user']);
chgrp($folder_path,$website['system_group']);
}
//* Create empty .htpasswd file, if it does not exist
if(!is_file($folder_path.'.htpasswd')) {
touch($folder_path.'.htpasswd');
chmod($folder_path.'.htpasswd',0755);
chown($folder_path.'.htpasswd',$website['system_user']);
chgrp($folder_path.'.htpasswd',$website['system_group']);
$app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
/*
$auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
$htpasswd_content = '';
if(is_array($auth_users) && !empty($auth_users)){
foreach($auth_users as $auth_user){
$htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
}
$htpasswd_content = trim($htpasswd_content);
@file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
$app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
*/
if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
$app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
$app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
}
//* Add or remove the user from .htpasswd file
if($event_name == 'web_folder_user_delete') {
$app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
$app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
if($data['new']['active'] == 'y') {
$app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1);
$app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG);
}
//if(!is_file($folder_path.'.htaccess')) {
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user";
file_put_contents($folder_path.'.htaccess',$ht_file);
chmod($folder_path.'.htaccess',0755);
chown($folder_path.'.htaccess',$website['system_user']);
chgrp($folder_path.'.htaccess',$website['system_group']);
$app->log('Created file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
//}
}
//* Remove .htaccess and .htpasswd file, when folder protection is removed
function web_folder_delete($event_name,$data) {
global $app, $conf;
$folder_id = $data['old']['web_folder_id'];
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
if(!is_array($folder) or !is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
$folder_path = realpath($website['document_root'].'/web/'.$folder['path']);
if(substr($folder_path,-1) != '/') $folder_path .= '/';
//* Check if the resulting path is inside the docroot
if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
//* Remove .htpasswd file
if(is_file($folder_path.'.htpasswd')) {
unlink($folder_path.'.htpasswd');
$app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
//* Remove .htaccess file
if(is_file($folder_path.'.htaccess')) {
unlink($folder_path.'.htaccess');
$app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
}
//* Update folder protection, when path has been changed
function web_folder_update($event_name,$data) {
global $app, $conf;
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
if(!is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1);
if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1);
$old_folder_path = realpath($website['document_root'].'/web/'.$data['old']['path']);
if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/';
if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1);
if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1);
$new_folder_path = escapeshellcmd($website['document_root'].'/web/'.$data['new']['path']);
if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/';
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
//* Check if the resulting path is inside the docroot
if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) {
$app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) {
$app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
//* Check if the resulting path is inside the docroot
if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
//* Create the folder path, if it does not exist
if(!is_dir($new_folder_path)) exec('mkdir -p '.$new_folder_path);
if($data['old']['path'] != $data['new']['path']) {
//* move .htpasswd file
if(is_file($old_folder_path.'.htpasswd')) {
rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd');
$app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
//* delete old .htaccess file
unlink($old_folder_path.'.htaccess');
$app->log('Deleted file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
}
}
//* Create the .htaccess file
if($data['new']['active'] == 'y') {
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user";
file_put_contents($new_folder_path.'.htaccess',$ht_file);
chmod($new_folder_path.'.htpasswd',0755);
chown($folder_path.'.htpasswd',$website['system_user']);
chgrp($folder_path.'.htpasswd',$website['system_group']);
$app->log('Created file '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
//* Remove .htaccess file
if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
unlink($new_folder_path.'.htaccess');
$app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
public function ftp_user_delete($event_name,$data) {
global $app, $conf;
$ftpquota_file = $data['old']['dir'].'/.ftpquota';
if(file_exists($ftpquota_file)) unlink($ftpquota_file);
}
/**
* This function is called when a Webdav-User is inserted, updated or deleted.
*
* @author Oliver Vogel
* @param string $event_name
* @param array $data
*/
public function webdav($event_name,$data) {
global $app, $conf;
/*
* load the server configuration options
*/
$app->uses('getconf');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
/*
* Get additional informations
*/
$sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
$documentRoot = $sitedata['document_root'];
$domain = $sitedata['domain'];
$user = $sitedata['system_user'];
$group = $sitedata['system_group'];
$webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
/* Check if this is a chrooted setup */
if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
$apache_chrooted = true;
$app->log('Info: Apache is chrooted.',LOGLEVEL_DEBUG);
} else {
$apache_chrooted = false;
}
//* We dont want to have relative paths here
if(stristr($webdav_user_dir,'..') || stristr($webdav_user_dir,'./')) {
$app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot,LOGLEVEL_WARN);
return false;
}
//* Check if the resulting path exists if yes, if it is inside the docroot
if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir),0,strlen($documentRoot)) != $documentRoot) {
$app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot,LOGLEVEL_WARN);
return false;
}
/*
* First the webdav-root - folder has to exist
*/
if(!is_dir($webdav_user_dir)) {
$app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.',LOGLEVEL_DEBUG);
exec('mkdir -p '.escapeshellcmd($webdav_user_dir));
* The webdav - Root needs the group/user as owner and the apache as read and write
$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
* The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
* pwd-files are owned by root)
$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
/*
* if the user is active, we have to write/update the password - file
* if the user is inactive, we have to inactivate the user by removing the user from the file
*/
if ($data['new']['active'] == 'y') {
$this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
}
else {
/* empty pwd removes the user! */
$this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
/*
* Next step, patch the vhost - file
*/
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
$this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
/*
* Last, restart apache
*/
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
if ($event_name == 'webdav_user_delete') {
/*
* Get additional informations
*/
$sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
$documentRoot = $sitedata['document_root'];
/*
* We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
* So the only thing, we have to do, is to delete the user from the password-file
$this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
/*
* Next step, patch the vhost - file
*/
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
$this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
/*
* Last, restart apache
*/
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
}
/**
* This function writes the htdigest - files used by webdav and digest
* more info: see http://riceball.com/d/node/424
* @author Oliver Vogel
* @param string $filename The name of the digest-file
* @param string $username The name of the webdav-user
* @param string $authname The name of the realm
* @param string $pwd The password-hash of the user
private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
if(is_file($filename)) {
$in = fopen($filename, 'r');
$output = '';
/*
* read line by line and search for the username and authname
*/
while (preg_match("/:/", $line = fgets($in))) {
$line = rtrim($line);
$tmp = explode(':', $line);
if ($tmp[0] == $username && $tmp[1] == $authname) {
/*
* found the user. delete or change it?
*/
if ($pwdhash != '') {
$output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
}
$changed = true;
}
else {
$output .= $line . "\n";
}
fclose($in);
}
/*
* if we didn't change anything, we have to add the new user at the end of the file
*/
if (!$changed) {
$output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
/*
* Now lets write the new file
*/
if(trim($output) == '') {
unlink($filename);
} else {
file_put_contents($filename, $output);
}
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
}
/**
* This function patches the vhost-file and adds all webdav - user.
* This function is written, because the creation of the vhost - file is sophisticated and
* i don't want to make it more "heavy" by also adding this code too...
* @author Oliver Vogel
* @param string $fileName The Name of the .vhost-File (path included)
* @param string $webdavRoot The root of the webdav-folder
*/
private function _patchVhostWebdav($fileName, $webdavRoot) {
$in = fopen($fileName, 'r');
$output = '';
$inWebdavSection = false;
/*
* read line by line and search for the username and authname
*/
while ($line = fgets($in)) {
/*
* is the "replace-comment" found...
*/
if (trim($line) == '# WEBDAV BEGIN') {
/*
* The begin of the webdav - section is found, so ignore all lines til the end is found
*/
$inWebdavSection = true;
$output .= " # WEBDAV BEGIN\n";
/*
* add all the webdav-dirs to the webdav-section
*/
tbrehm
committed
$files = @scandir($webdavRoot);
if(is_array($files)) {
foreach($files as $file) {
if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest') {
/*
* found a htdigest - file, so add it to webdav
*/
$fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
$output .= "\n";
// $output .= " Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
// $output .= " <Location /" . $fn . ">\n";
$output .= " Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
$output .= " <Location /webdav/" . $fn . ">\n";
$output .= ' BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
$output .= " AuthType Digest\n";
$output .= " AuthName \"" . $fn . "\"\n";
$output .= " AuthUserFile " . $webdavRoot . '/' . $file . "\n";
$output .= " Require valid-user \n";
$output .= " Options +Indexes \n";
$output .= " Order allow,deny \n";
$output .= " Allow from all \n";
$output .= " </Location> \n";
}
}
tbrehm
committed
}
}
/*
* is the "replace-comment-end" found...
*/
if (trim($line) == '# WEBDAV END') {
/*
* The end of the webdav - section is found, so stop ignoring
*/
$inWebdavSection = false;
}
/*