Skip to content
system.inc.php 60.1 KiB
Newer Older
				}
				$group_users = implode(',', $group_users);
				if(substr($group_users, 0, 1) == ',') $group_users = substr($group_users, 1);
				$group_file_line = $group_name.':'.$group_x.':'.$group_id.':'.$group_users;
			}
			$new_group_file[] = $group_file_line;
		}
		$new_group_file = implode("\n", $new_group_file);
		$app->file->wf($this->server_conf['group_datei'], $new_group_file);
		$app->file->remove_blank_lines($this->server_conf['group_datei']);
		if($this->server_conf['shadow_datei'] != '/etc/shadow'){
			$app->log->caselog('pwd_mkdb '.$this->server_conf['shadow_datei'].' &> /dev/null', $this->FILE, __LINE__);
		}
	function usermod($user, $groups){
		global $app;
	  	if($this->is_user($user)){
		    $groups = explode(',', str_replace(' ', '', $groups));
	    	$group_file = $app->file->rf($this->server_conf['group_datei']);
	    	$group_file_lines = explode("\n", $group_file);
	    	foreach($group_file_lines as $group_file_line){
	      		if(trim($group_file_line) != ""){
	        		list($f1, $f2, $f3, $f4) = explode(':', $group_file_line);
	        		$group_users = explode(',', str_replace(' ', '', $f4));
	        		if(!in_array($f1, $groups)){
	          			if(in_array($user, $group_users)){
	            			$g_users = array();
	            			foreach($group_users as $group_user){
	              				if($group_user != $user) $g_users[] = $group_user;
	            			}
	            			$f4 = implode(',', $g_users);
	          			}
		        	} else {
	          			if(!in_array($user, $group_users)){
	            			if(trim($group_users[0]) == '') unset($group_users);
	          			$f4 = implode(',', $group_users);
	        		$new_group_file[] = $f1.':'.$f2.':'.$f3.':'.$f4;
	      		}
	    	}
	    	$new_group_file = implode("\n", $new_group_file);
	    	$app->file->wf($this->server_conf['group_datei'], $new_group_file);
	    	$app->file->remove_blank_lines($this->server_conf['group_datei']);
	    	if($this->server_conf['shadow_datei'] != '/etc/shadow'){
	      		$app->log->caselog('pwd_mkdb '.$this->server_conf['shadow_datei'].' &> /dev/null', $this->FILE, __LINE__);
	*/

	/**boot autostart etc
	 *
	 */
	function rc_edit($service, $rl, $action){
		// $action = "on|off";
		global $app;
		$dist_init_scripts = $app->system->server_conf['dist_init_scripts'];
		$dist_runlevel = $app->system->server_conf['dist_runlevel'];
		$dist = $app->system->server_conf['dist'];
		if(trim($dist_runlevel) == ''){ // falls es keine runlevel gibt (FreeBSD)
			if($action == 'on'){
				@symlink($dist_init_scripts.'/'.$service, $dist_init_scripts.'/'.$service.'.sh');
			}
			if($action == 'off'){
				if(is_link($dist_init_scripts.'/'.$service.'.sh')){
					unlink($dist_init_scripts.'/'.$service.'.sh');
				} else {
					rename($dist_init_scripts.'/'.$service.'.sh', $dist_init_scripts.'/'.$service);
				}
			}
		} else { // Linux
			if(substr($dist, 0, 4) == 'suse'){
				if($action == 'on'){
					$this->exec_safe("chkconfig --add ? &> /dev/null", $service);
				}
				if($action == 'off'){
					$this->exec_safe("chkconfig --del ? &> /dev/null", $service);
				}
			} else {
				$runlevels = explode(',', $rl);
				foreach($runlevels as $runlevel){
					$runlevel = trim($runlevel);
					if($runlevel != '' && is_dir($dist_runlevel.'/rc'.$runlevel.'.d')){
						$handle=opendir($dist_runlevel.'/rc'.$runlevel.'.d');
						while($file = readdir($handle)){
							if($file != '.' && $file != '..'){
								$target = @readlink($dist_runlevel.'/rc'.$runlevel.'.d/'.$file);
								if(strstr($file, $service) && strstr($target, $service) && substr($file, 0, 1) == 'S') $ln_arr[$runlevel][] = $dist_runlevel.'/rc'.$runlevel.'.d/'.$file;
							}
						}
						closedir($handle);
					}
					if($action == 'on'){
						if(!is_array($ln_arr[$runlevel])) @symlink($dist_init_scripts.'/'.$service, $dist_runlevel.'/rc'.$runlevel.'.d/S99'.$service);
					}
					if($action == 'off'){
						if(is_array($ln_arr[$runlevel])){
							foreach($ln_arr[$runlevel] as $link){
								unlink($link);
							}
						}
					}
				}
			}
		}
	}





	/**
	 * Filter information from the commands
	 *
	 */
	function grep($content, $string, $params = ''){
		global $app;
		// params: i, v, w
		$content = $app->file->unix_nl($content);
		$lines = explode("\n", $content);
		foreach($lines as $line){
			if(!strstr($params, 'w')){
				if(strstr($params, 'i')){
					if(strstr($params, 'v')){
						if(!stristr($line, $string)) $find[] = $line;
					} else {
						if(stristr($line, $string)) $find[] = $line;
					}
				} else {
					if(strstr($params, 'v')){
						if(!strstr($line, $string)) $find[] = $line;
					} else {
						if(strstr($line, $string)) $find[] = $line;
					}
				}
			} else {
				if(strstr($params, 'i')){
					if(strstr($params, 'v')){
						if(!$app->string->is_word($string, $line, 'i')) $find[] = $line;
					} else {
						if($app->string->is_word($string, $line, 'i')) $find[] = $line;
					}
				} else {
					if(strstr($params, 'v')){
						if(!$app->string->is_word($string, $line)) $find[] = $line;
					} else {
						if($app->string->is_word($string, $line)) $find[] = $line;
					}
				}
			}
		}
		if(is_array($find)){
			$ret_val = implode("\n", $find);
			if(substr($ret_val, -1) != "\n") $ret_val .= "\n";
			$find = NULL;
			return $ret_val;
		} else {
			return false;
		}
	/**
	 * Strip content from fields
	 *
	 */
	function cut($content, $field, $delimiter = ':'){
		global $app;
		$content = $app->file->unix_nl($content);
		$lines = explode("\n", $content);
		foreach($lines as $line){
			$elms = explode($delimiter, $line);
			$find[] = $elms[($field-1)];
		}
		if(is_array($find)){
			$ret_val = implode("\n", $find);
			if(substr($ret_val, -1) != "\n") $ret_val .= "\n";
			$find = NULL;
			return $ret_val;
		} else {
			return false;
		}
	/**
	 * Get the content off a file
	 *
	 */
	function cat($file){
		global $app;
		return $app->file->rf($file);
	/**
	 * Control services to restart etc
	 *
	 */
	function daemon_init($daemon, $action){
		//* $action = start|stop|restart|reload
		global $app;
		$dist = $this->server_conf['dist'];
		$dist_init_scripts = $this->server_conf['dist_init_scripts'];
		if(!strstr($dist, 'freebsd')){
			$app->log->caselog("$dist_init_scripts/$daemon $action &> /dev/null", $this->FILE, __LINE__);
		} else {
			if(is_file($dist_init_scripts.'/'.$daemon.'.sh') || is_link($dist_init_scripts.'/'.$daemon.'.sh')){
				if($action == 'start' || $action == 'stop'){
					$app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh '.$action.' &> /dev/null', $this->FILE, __LINE__);
				} else {
					$app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh stop &> /dev/null', $this->FILE, __LINE__);
					sleep(3);
					$app->log->caselog($dist_init_scripts.'/'.$daemon.'.sh start &> /dev/null', $this->FILE, __LINE__);
				}
			} else {
				if(is_file($dist_init_scripts.'/'.$daemon) || is_link($dist_init_scripts.'/'.$daemon)){
					if($action == 'start' || $action == 'stop'){
						$app->log->caselog($dist_init_scripts.'/'.$daemon.' '.$action.' &> /dev/null', $this->FILE, __LINE__);
					} else {
						$app->log->caselog($dist_init_scripts.'/'.$daemon.' stop &> /dev/null', $this->FILE, __LINE__);
						sleep(3);
						$app->log->caselog($dist_init_scripts.'/'.$daemon.' start &> /dev/null', $this->FILE, __LINE__);
					}
				} else {
					if(is_file('/etc/rc.d/'.$daemon) || is_link('/etc/rc.d/'.$daemon)){
						if($action == 'start' || $action == 'stop'){
							$app->log->caselog('/etc/rc.d/'.$daemon.' '.$action.' &> /dev/null', $this->FILE, __LINE__);
						} else {
							$app->log->caselog('/etc/rc.d/'.$daemon.' stop &> /dev/null', $this->FILE, __LINE__);
							sleep(3);
							$app->log->caselog('/etc/rc.d/'.$daemon.' start &> /dev/null', $this->FILE, __LINE__);
						}
					}
				}
			}
		}
	function netmask($netmask){
		list($f1, $f2, $f3, $f4) = explode('.', trim($netmask));
		$bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
		$parts = explode('0', $bin);
		$bin = str_pad($parts[0], 32, '0', STR_PAD_RIGHT);
		$bin = wordwrap($bin, 8, '.', 1);
		list($f1, $f2, $f3, $f4) = explode('.', trim($bin));
		return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
	function binary_netmask($netmask){
		list($f1, $f2, $f3, $f4) = explode('.', trim($netmask));
		$bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
		$parts = explode('0', $bin);
		return substr_count($parts[0], '1');
	function network($ip, $netmask){
		$netmask = $this->netmask($netmask);
		list($f1, $f2, $f3, $f4) = explode('.', $netmask);
		$netmask_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
		list($f1, $f2, $f3, $f4) = explode('.', $ip);
		$ip_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
		for($i=0;$i<32;$i++){
			$network_bin .= substr($netmask_bin, $i, 1) * substr($ip_bin, $i, 1);
		}
		$network_bin = wordwrap($network_bin, 8, '.', 1);
		list($f1, $f2, $f3, $f4) = explode('.', trim($network_bin));
		return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
	/**
	 * Make a broadcast address from an IP number in combination with netmask
	 *
	 */
	function broadcast($ip, $netmask){
		$netmask = $this->netmask($netmask);
		$binary_netmask = $this->binary_netmask($netmask);
		list($f1, $f2, $f3, $f4) = explode('.', $ip);
		$ip_bin = str_pad(decbin($f1), 8, '0', STR_PAD_LEFT).str_pad(decbin($f2), 8, '0', STR_PAD_LEFT).str_pad(decbin($f3), 8, '0', STR_PAD_LEFT).str_pad(decbin($f4), 8, '0', STR_PAD_LEFT);
		$broadcast_bin = str_pad(substr($ip_bin, 0, $binary_netmask), 32, '1', STR_PAD_RIGHT);
		$broadcast_bin = wordwrap($broadcast_bin, 8, '.', 1);
		list($f1, $f2, $f3, $f4) = explode('.', trim($broadcast_bin));
		return bindec($f1).'.'.bindec($f2).'.'.bindec($f3).'.'.bindec($f4);
	/**
	 * Get the network address information
	 *
	 */
	function network_info(){
		$dist = $this->server_conf['dist'];
		ob_start();
		passthru('ifconfig');
		$output = ob_get_contents();
		ob_end_clean();
		$lines = explode("\n", $output);
		foreach($lines as $line){
			$elms = explode(' ', $line);
			if(trim($elms[0]) != '' && substr($elms[0], 0, 1) != "\t"){
				$elms[0] = trim($elms[0]);
				if(strstr($dist, 'freebsd')) $elms[0] = substr($elms[0], 0, -1);
				$interfaces[] = $elms[0];
			}
		}
		if(!empty($interfaces)){
			foreach($interfaces as $interface){
				ob_start();
				if(!strstr($dist, 'freebsd')){
					passthru('ifconfig '.$interface." | grep -iw 'inet' | cut -f2 -d: | cut -f1 -d' '");
				} else {
					passthru('ifconfig '.$interface." | grep -iw 'inet' | grep -iv 'inet6' | cut -f2 -d' '");
				}
				$output = trim(ob_get_contents());
				ob_end_clean();
				if($output != ''){
					$ifconfig['INTERFACE'][$interface] = $output;
					$ifconfig['IP'][$output] = $interface;
				}
			}
			if(!empty($ifconfig)){
				return $ifconfig;
			} else {
				return false;
			}
		} else {
			return false;
		}
	/**
	 * Configure the network settings from the system
	 *
	 */
	function network_config(){
		$ifconfig = $this->network_info();
		if($ifconfig){
			$main_interface = $ifconfig['IP'][$this->server_conf['server_ip']];
			if(strstr($main_interface, ':')){
				$parts = explode(':', $main_interface);
				$main_interface = trim($parts[0]);
			}
			if($main_interface != ''){
				$ips = $this->data['isp_server_ip'];
				if(!empty($ips)){
					foreach($ips as $ip){
						if(!isset($ifconfig['IP'][$ip['server_ip']])){
							$to_set[] = $ip['server_ip'];
						} else {
							unset($ifconfig['IP'][$ip['server_ip']]);
						}
					}
					if(!empty($ifconfig['IP'])){
						foreach($ifconfig['IP'] as $key => $val){
							if(!strstr($val, 'lo') && !strstr($val, 'lp') && strstr($val, $main_interface)){
								$this->exec_safe('ifconfig ? down &> /dev/null', $val);
								unset($ifconfig['INTERFACE'][$val]);
							}
						}
					}
					if(!empty($to_set)){
						foreach($to_set as $to){
							$i = 0;
							while($i >= 0){
								if(isset($ifconfig['INTERFACE'][$main_interface.':'.$i])){
									$i++;
								} else {
									$new_interface = $main_interface.':'.$i;
									$i = -1;
								}
							}
							$this->exec_safe('ifconfig ? ? netmask ? up &> /dev/null', $new_interface, $to, $this->server_conf['server_netzmaske']);
							$ifconfig['INTERFACE'][$new_interface] = $to;
						}
					}
				}
			}
		}
		global $app;
		$content = $app->file->unix_nl($app->file->no_comments('/etc/fstab'));
		$lines = explode("\n", $content);
		foreach($lines as $line){
			$line = trim($line);
			if($line != ''){
				$elms = explode("\t", $line);
				foreach($elms as $elm){
					if(trim($elm) != '') $f[] = $elm;
				}
				if(!empty($f) && stristr($f[3], 'userquota') && stristr($f[3], 'groupquota')){
					$q_dirs[] = trim($f[1]);
				}
				unset($f);
			}
		}
		if(!empty($q_dirs)){
			return $q_dirs;
		} else {
			return false;
		}
	/**
	 * Scan the trash for virusses infection
	 *
	 */
	function make_trashscan(){
		global $app;
		//trashscan erstellen
		// Template Öffnen
		$app->tpl->clear_all();
		$app->tpl->define( array(table    => 'trashscan.master'));

		if(!isset($this->server_conf['virusadmin']) || trim($this->server_conf['virusadmin']) == '') $this->server_conf['virusadmin'] = 'admispconfig@localhost';
		if(substr($this->server_conf['virusadmin'], 0, 1) == '#'){
			$notify = 'no';
		} else {
			$notify = 'yes';
		}

		// Variablen zuweisen
		$app->tpl->assign( array(VIRUSADMIN => $this->server_conf['virusadmin'],
				NOTIFICATION => $notify));

		$app->tpl->parse(TABLE, table);

		$trashscan_text = $app->tpl->fetch();

		$datei = '/home/admispconfig/ispconfig/tools/clamav/bin/trashscan';
		$app->file->wf($datei, $trashscan_text);

		chmod($datei, 0755);
		chown($datei, 'admispconfig');
		chgrp($datei, 'admispconfig');
	/**
	 * Get the current time
	 *
	 */
	function get_time(){
		$addr = 'http://www.ispconfig.org/';
		$timeout = 1;
		$url_parts = parse_url($addr);
		$path = $url_parts['path'];
		$port = 80;
		$urlHandle = @fsockopen($url_parts['host'], $port, $errno, $errstr, $timeout);
		if ($urlHandle){
			socket_set_timeout($urlHandle, $timeout);

			$urlString = 'GET '.$path." HTTP/1.0\r\nHost: ".$url_parts['host']."\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
			if ($user) $urlString .= 'Authorization: Basic '.base64_encode($user.':'.$pass)."\r\n";
			$urlString .= "\r\n";
			fputs($urlHandle, $urlString);

			$month['Jan'] = '01';
			$month['Feb'] = '02';
			$month['Mar'] = '03';
			$month['Apr'] = '04';
			$month['May'] = '05';
			$month['Jun'] = '06';
			$month['Jul'] = '07';
			$month['Aug'] = '08';
			$month['Sep'] = '09';
			$month['Oct'] = '10';
			$month['Nov'] = '11';
			$month['Dec'] = '12';
			$c = 0;
			$l = 0;
			$startzeit = time();
			while(!feof($urlHandle) && $c < 2 && $l == 0){
				$line = trim(fgets($urlHandle, 128));
				$response .= $line;
				$c = time() - $startzeit;
				if($line == '' || substr($line, 0, 5) == 'Date:') $l += 1; // nur den Header auslesen
				if(substr($line, 0, 5) == 'Date:'){
					$parts = explode(' ', $line);
					$tag = $parts[2];
					$monat = $month[$parts[3]];
					$jahr = $parts[4];
					list($stunde, $minute, $sekunde) = explode(':', $parts[5]);
					$timestamp = mktime($stunde, $minute, $sekunde, $monat, $tag, $jahr);
				}
			}

			@fclose($urlHandle);

			return $timestamp;
		} else {
			@fclose($urlHandle);
			return false;
		}

	function replaceLine($filename, $search_pattern, $new_line, $strict = 0, $append = 1) {
		if($this->checkpath($filename) == false) {
			$app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
		$lines = @file($filename);
		$out = '';
		$found = 0;
		if(is_array($lines)) {
			foreach($lines as $line) {
				if($strict == 0 && preg_match('/^REGEX:(.*)$/', $search_pattern)) {
					if(preg_match(substr($search_pattern, 6), $line)) {
						$out .= $new_line."\n";
						$found = 1;
					} else {
						$out .= $line;
					}
				} elseif($strict == 0) {
					if(stristr($line, $search_pattern)) {
						$out .= $new_line."\n";
						$found = 1;
					} else {
						$out .= $line;
					}
				} else {
					if(trim($line) == $search_pattern) {
						$out .= $new_line."\n";
						$found = 1;
					} else {
						$out .= $line;
					}
				}
			}
		}
		if($found == 0) {
			//* add \n if the last line does not end with \n or \r
			if(substr($out, -1) != "\n" && substr($out, -1) != "\r" && filesize($filename) > 0) $out .= "\n";
			//* add the new line at the end of the file
			if($append == 1) {
				$out .= $new_line."\n";
			}
		file_put_contents($filename, $out);

	function removeLine($filename, $search_pattern, $strict = 0) {
		global $app;
		if($this->checkpath($filename) == false) {
			$app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
			return false;
		}
		if($lines = @file($filename)) {
			$out = '';
			foreach($lines as $line) {
				if($strict == 0 && preg_match('/^REGEX:(.*)$/', $search_pattern)) {
					if(preg_match(substr($search_pattern, 6), $line)) {
						$out .= $new_line."\n";
						$found = 1;
					} else {
						$out .= $line;
					}
				} elseif($strict == 0) {
					if(!stristr($line, $search_pattern)) {
						$out .= $line;
					}
				} else {
					if(!trim($line) == $search_pattern) {
						$out .= $line;
					}
			file_put_contents($filename, $out);
Dominik's avatar
Dominik committed
	function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
		global $app, $conf;
		
		// load the server configuration options
		$app->uses("getconf");
		$mail_config = $app->getconf->get_server_config($conf["server_id"], 'mail');
		if($subfolder != '') {
		} else {

		if($user != '' && $user != 'root' && $this->is_user($user)) {
			if(is_dir($dir)) $this->chown($dir, $user);

			$chown_mdsub = true;
		if($group != '' && $group != 'root' && $this->is_group($group)) {
			if(is_dir($dir)) $this->chgrp($dir, $group);
		
			$chgrp_mdsub = true;
		}

		$maildirsubs = array('cur', 'new', 'tmp');

		foreach ($maildirsubs as $mdsub) {
			if(!is_dir($dir.'/'.$mdsub)) mkdir($dir.'/'.$mdsub, 0700, true);
			if ($chown_mdsub) chown($dir.'/'.$mdsub, $user);
			if ($chgrp_mdsub) chgrp($dir.'/'.$mdsub, $group);
		//* Add the subfolder to the subscriptions and courierimapsubscribed files
		if($subfolder != '') {
			// Courier
			if($mail_config['pop3_imap_daemon'] == 'courier') {
				if(!is_file($maildir_path.'/courierimapsubscribed')) {
					$tmp_file = $maildir_path.'/courierimapsubscribed';
					touch($tmp_file);
					chmod($tmp_file, 0744);
					chown($tmp_file, 'vmail');
					chgrp($tmp_file, 'vmail');
				}
				$this->replaceLine($maildir_path.'/courierimapsubscribed', 'INBOX.'.$subfolder, 'INBOX.'.$subfolder, 1, 1);
			// Dovecot
			if($mail_config['pop3_imap_daemon'] == 'dovecot') {
				if(!is_file($maildir_path.'/subscriptions')) {
					$tmp_file = $maildir_path.'/subscriptions';
					touch($tmp_file);
					chmod($tmp_file, 0744);
					chown($tmp_file, 'vmail');
					chgrp($tmp_file, 'vmail');
				}
				$this->replaceLine($maildir_path.'/subscriptions', $subfolder, $subfolder, 1, 1);

		$app->log('Created Maildir '.$maildir_path.' with subfolder: '.$subfolder, LOGLEVEL_DEBUG);

	//* Function to create directory paths and chown them to a user and group
	function mkdirpath($path, $mode = 0755, $user = '', $group = '') {
		$path_parts = explode('/', $path);
		$new_path = '';
		if(is_array($path_parts)) {
			foreach($path_parts as $part) {
				$new_path .= '/'.$part;
				if(!@is_dir($new_path)) {
					$this->chmod($new_path, $mode);
					if($user != '') $this->chown($new_path, $user);
					if($group != '') $this->chgrp($new_path, $group);
	
	function _exec($command) {
		global $app;
		$out = array();
		$ret = 0;
		$app->log('exec: '.$command, LOGLEVEL_DEBUG);
		exec($command, $out, $ret);
		if($ret != 0) return false;
		else return true;
	}
	//* Check if a application is installed
	function is_installed($appname) {
		$this->exec_safe('which ? 2> /dev/null', $appname);
		$out = $this->last_exec_out();
		$returncode = $this->last_exec_retcode();
		if(isset($out[0]) && stristr($out[0], $appname) && $returncode == 0) {

	function web_folder_protection($document_root, $protect) {
		global $app, $conf;

		if($this->checkpath($document_root) == false) {
			$app->log("Action aborted, target is a symlink: $document_root", LOGLEVEL_DEBUG);
		//* load the server configuration options
		$app->uses('getconf');
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
		if($protect == true && $web_config['web_folder_protection'] == 'y') {
			//* Add protection
			if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root, '..')) $this->exec_safe('chattr +i ?', $document_root);
			if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root, '..')) $this->exec_safe('chattr -i ?', $document_root);
	function usermod($username, $uid = 0, $gid = 0, $home = '', $shell = '', $password = '', $login = '') {
		global $app;
		if($login == '') $login = $username;
		//* Change values in /etc/passwd
		$passwd_file_array = file('/etc/passwd');
		if(is_array($passwd_file_array)) {
			foreach($passwd_file_array as $line) {
				$line = trim($line);
				$parts = explode(':', $line);
				if($parts[0] == $username) {
					if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
					if(!empty($uid)) $parts[2] = trim($uid);
					if(!empty($gid)) $parts[3] = trim($gid);
					if(trim($home) != '') $parts[5] = trim($home);
					if(trim($shell) != '') $parts[6] = trim($shell);
					$new_line = implode(':', $parts);
					copy('/etc/passwd', '/etc/passwd~');
					chmod('/etc/passwd~', 0600);
					$app->uses('system');
					$app->system->replaceLine('/etc/passwd', $line, $new_line, 1, 0);
		//* If username != login, change username in group and gshadow file
		if($username  != $login) {
			$group_file_array = file('/etc/group');
			if(is_array($group_file_array)) {
				foreach($group_file_array as $line) {
					$line = trim($line);
					$parts = explode(':', $line);
					if(strstr($parts[3], $username)) {
						$uparts = explode(',', $parts[3]);
						if(is_array($uparts)) {
							foreach($uparts as $key => $val) {
								if($val == $username) $uparts[$key] = $login;
							}
						}
						$parts[3] = implode(',', $uparts);
						$new_line = implode(':', $parts);
						copy('/etc/group', '/etc/group~');
						chmod('/etc/group~', 0600);
						$app->system->replaceLine('/etc/group', $line, $new_line, 1, 0);
			$gshadow_file_array = file('/etc/gshadow');
			if(is_array($gshadow_file_array)) {
				foreach($gshadow_file_array as $line) {
					$line = trim($line);
					$parts = explode(':', $line);
					if(strstr($parts[3], $username)) {
						$uparts = explode(',', $parts[3]);
						if(is_array($uparts)) {
							foreach($uparts as $key => $val) {
								if($val == $username) $uparts[$key] = $login;
							}
						}
						$parts[3] = implode(',', $uparts);
						$new_line = implode(':', $parts);
						copy('/etc/gshadow', '/etc/gshadow~');
						chmod('/etc/gshadow~', 0600);
						$app->system->replaceLine('/etc/gshadow', $line, $new_line, 1, 0);
		//* When password or login name has been changed
		if($password != '' || $username  != $login) {
			$shadow_file_array = file('/etc/shadow');
			if(is_array($shadow_file_array)) {
				foreach($shadow_file_array as $line) {
					$line = trim($line);
					$parts = explode(':', $line);
					if($parts[0] == $username) {
						if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
						if(trim($password) != '') $parts[1] = trim($password);
						$new_line = implode(':', $parts);
						copy('/etc/shadow', '/etc/shadow~');
						chmod('/etc/shadow~', 0600);
						$app->system->replaceLine('/etc/shadow', $line, $new_line, 1, 0);
	function intval($string, $force_numeric = false) {
		if(intval($string) == 2147483647) {
			if($force_numeric == true) return floatval($string);
			elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2];
			else return 0;
		} else {
			return intval($string);
		}
	}

	function is_mounted($mountpoint){
		//$cmd = 'df 2>/dev/null | grep " '.$mountpoint.'$"';
		$cmd = 'mount 2>/dev/null | grep ?';
		$this->exec_safe($cmd, ' on '. $mountpoint . ' type ');
		$return_var = $this->last_exec_retcode();
		return $return_var == 0 ? true : false;
	function mount_backup_dir($backup_dir, $mount_cmd = '/usr/local/ispconfig/server/scripts/backup_dir_mount.sh'){
		
		if($this->is_mounted($backup_dir)) return true;
		
		$mounted = true;
		if ( 	is_file($mount_cmd) &&
				is_executable($mount_cmd) &&
				fileowner($mount_cmd) === 0
		) {
			if (!$this->is_mounted($backup_dir)){
				sleep(1);
				if (!$this->is_mounted($backup_dir)) $mounted = false;
			}
		} else $mounted = false;
		if (!$mounted) {
			//* send email to admin that backup directory could not be mounted
			$global_config = $app->getconf->get_global_config('mail');
			if($global_config['admin_mail'] != ''){
				$subject = 'Backup directory '.$backup_dir.' could not be mounted';
				$message = "Backup directory ".$backup_dir." could not be mounted.\n\nThe command\n\n".$mount_cmd."\n\nfailed.";
				mail($global_config['admin_mail'], $subject, $message);
			}
		}

	function umount_backup_dir($backup_dir, $mount_cmd = '/usr/local/ispconfig/server/scripts/backup_dir_umount.sh'){
		if ( 	is_file($mount_cmd) &&
				is_executable($mount_cmd) &&
				fileowner($mount_cmd) === 0
		) {
			if ($this->is_mounted($backup_dir)){
				exec($mount_cmd);
				sleep(1);

Florian Schaal's avatar
Florian Schaal committed
		        $unmounted = $this->is_mounted($backup_dir) == 0 ? true : false;
				if(!$unmounted) {
					//* send email to admin that backup directory could not be unmounted
					$global_config = $app->getconf->get_global_config('mail');
					if($global_config['admin_mail'] != ''){
						$subject = 'Backup directory '.$backup_dir.' could not be unmounted';
						$message = "Backup directory ".$backup_dir." could not be unmounted.\n\nThe command\n\n".$mount_cmd."\n\nfailed.";
						mail($global_config['admin_mail'], $subject, $message);
					}
				}
	function _getinitcommand($servicename, $action, $init_script_directory = '', $check_service) {
		global $conf;
		// upstart
		if(is_executable('/sbin/initctl')){
			exec('/sbin/initctl version 2>/dev/null | /bin/grep -q upstart', $retval['output'], $retval['retval']);
			if(intval($retval['retval']) == 0) return 'service '.$servicename.' '.$action;
		}
		// systemd
		if(is_executable('/bin/systemd') || is_executable('/usr/bin/systemctl')){
				$this->exec_safe("systemctl is-enabled ? 2>&1", $servicename);
				$ret_val = $this->last_exec_retcode();
			}
			if ($ret_val == 0 || !$check_service) {
				return 'systemctl '.$action.' '.$servicename.'.service';
			}
		// sysvinit
		if($init_script_directory == '') $init_script_directory = $conf['init_scripts'];
		if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1);
		if($check_service && is_executable($init_script_directory.'/'.$servicename)) {
			return $init_script_directory.'/'.$servicename.' '.$action;
		}
		if (!$check_service) {
			return $init_script_directory.'/'.$servicename.' '.$action;
		}

	function getinitcommand($servicename, $action, $init_script_directory = '', $check_service=false) {
		if (is_array($servicename)) {
			foreach($servicename as $service) {
				$out = $this->_getinitcommand($service, $action, $init_script_directory, true);
				if ($out != '') return $out;
			}
		} else {
			return $this->_getinitcommand($servicename, $action, $init_script_directory, $check_service);
		}
	}

	function getapacheversion($get_minor = false) {
		global $app;
		
		$cmd = '';
		if($this->is_installed('apache2ctl')) $cmd = 'apache2ctl -v';
		elseif($this->is_installed('apachectl')) $cmd = 'apachectl -v';
		else {
			$app->log("Could not check apache version, apachectl not found.", LOGLEVEL_DEBUG);
			return '2.2';
		}
		
		exec($cmd, $output, $return_var);
		if($return_var != 0 || !$output[0]) {
			$app->log("Could not check apache version, apachectl did not return any data.", LOGLEVEL_WARN);
			return '2.2';
		}
		
		if(preg_match('/version:\s*Apache\/(\d+)(\.(\d+)(\.(\d+))*)?(\D|$)/i', $output[0], $matches)) {
			return $matches[1] . (isset($matches[3]) ? '.' . $matches[3] : '') . (isset($matches[5]) && $get_minor == true ? '.' . $matches[5] : '');
		} else {
			$app->log("Could not check apache version, did not find version string in apachectl output.", LOGLEVEL_WARN);
			return '2.2';
		}
	}
	function getapachemodules() {
		global $app;
		
		$cmd = '';
		if($this->is_installed('apache2ctl')) $cmd = 'apache2ctl -t -D DUMP_MODULES';
		elseif($this->is_installed('apachectl')) $cmd = 'apachectl -t -D DUMP_MODULES';
		else {
			$app->log("Could not check apache modules, apachectl not found.", LOGLEVEL_WARN);
			return array();
		}
		
		exec($cmd . ' 2>/dev/null', $output, $return_var);
		if($return_var != 0 || !$output[0]) {
			$app->log("Could not check apache modules, apachectl did not return any data.", LOGLEVEL_WARN);
			return array();
		}
		
		$modules = array();
		for($i = 0; $i < count($output); $i++) {
			if(preg_match('/^\s*(\w+)\s+\((shared|static)\)\s*$/', $output[$i], $matches)) {
				$modules[] = $matches[1];
			}
		}