From aa370627b211a51dc46891cfa4b6e3d2ef3e52db Mon Sep 17 00:00:00 2001
From: mcramer <m.cramer@pixcept.de>
Date: Tue, 16 Jul 2013 10:45:17 -0400
Subject: [PATCH] - Fixed FS#2924 - the month will not set automatically in the autoresponder by click now   Along with this fixed some display problems with the combo boxes introduced in 3.0.5.   Some fields were not correctly displayed with the predefined values if value and text of the underlying option element differ.

---
 server/lib/classes/system.inc.php |  454 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 408 insertions(+), 46 deletions(-)

diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index c194881..f6b52cf 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -41,9 +41,9 @@
 	 * @return system
 	 */
 	public function system(){
-		global $go_info;
-	  	$this->server_id = $go_info['isp']['server_id'];
-	  	$this->server_conf = $go_info['isp']['server_conf'];
+		//global $go_info;
+	  	//$this->server_id = $go_info['isp']['server_id'];
+	  	//$this->server_conf = $go_info['isp']['server_conf'];
 	  	$this->server_conf['passwd_datei'] = '/etc/passwd';
 	  	$this->server_conf['shadow_datei'] = '/etc/shadow';
 	  	$this->server_conf['group_datei'] = '/etc/group';
@@ -575,6 +575,58 @@
 	}
 	
 	/**
+	 * Get the group id from an group
+	 *
+	 */
+	function getgid($group){
+		global $app;
+	  	if($this->is_group($group)){
+		    $group_datei = $this->server_conf['group_datei'];
+			$groups = $app->file->no_comments($group_datei);
+			$lines = explode("\n", $groups);
+			if(is_array($lines)){
+		    foreach($lines as $line){
+					if(trim($line) != ""){
+						list($f1, $f2, $f3, $f4) = explode(':', $line);
+						if($f1 == $group) return $f3;
+					}
+				}
+			}
+	  	} else {
+		    return false;
+	  	}
+	}
+	
+	/**
+	* Return info about a group by name
+	*
+	*/
+	function posix_getgrnam($group) {
+		if(!function_exists('posix_getgrnam')){
+			$group_datei = $this->server_conf['group_datei'];
+			$cmd = 'grep -m 1 "^'.$group.':" '.$group_datei;
+			exec($cmd, $output, $return_var);
+			if($return_var != 0 || !$output[0]) return false;
+			list($f1, $f2, $f3, $f4) = explode(':', $output[0]);
+			$f2 = trim($f2);
+			$f3 = trim($f3);
+			$f4 = trim($f4);
+			if($f4 != ''){
+				$members = explode(',', $f4);
+			} else {
+				$members = array();
+			}
+			$group_details = array(	'name' => $group,
+									'passwd' => $f2,
+									'members' => $members,
+									'gid' => $f3);
+			return $group_details;	
+		} else {
+			return posix_getgrnam($group);
+		}
+    }
+	
+	/**
 	 * Get all information from a user
 	 *
 	 */
@@ -610,18 +662,135 @@
 	 * Edit the owner of a file
 	 *
 	 */
-	function chown($file, $owner, $group = ''){
-	  $owner_change = @chown($file, $owner);
-	  if($group != ''){
-	    $group_change = @chgrp($file, $group);
-	  } else {
-	    $group_change = 1;
+	function chown($file, $owner, $allow_symlink = false){
+	  global $app;
+	  if($allow_symlink == false && $this->checkpath($file) == false) {
+		$app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+		return false;
 	  }
-	  if($owner_change && $group_change){
-	    return true;
-	  } else {
-	    return false;
+	  if(file_exists($file)) {
+		if(@chown($file, $owner)) {
+			return true;
+		} else {
+			$app->log("chown failed: $file : $owner",LOGLEVEL_DEBUG);
+			return false;
+		}
 	  }
+	}
+	
+	function chgrp($file, $group = '', $allow_symlink = false){
+	  global $app;
+	  if($allow_symlink == false && $this->checkpath($file) == false) {
+		$app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+		return false;
+	  }
+	  if(file_exists($file)) {
+		if(@chgrp($file, $group)) {
+			return true;
+		} else {
+			$app->log("chgrp failed: $file : $group",LOGLEVEL_DEBUG);
+			return false;
+		}
+	  }
+	}
+	
+	//* Change the mode of a file
+	function chmod($file, $mode, $allow_symlink = false) {
+		global $app;
+		if($allow_symlink == false && $this->checkpath($file) == false) {
+			$app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+			return false;
+		}
+		if(@chmod($file, $mode)) {
+			return true;
+		} else {
+			$app->log("chmod failed: $file : $mode",LOGLEVEL_DEBUG);
+			return false;
+		}
+	}
+	
+	function file_put_contents($filename, $data, $allow_symlink = false) {
+		global $app;
+		if($allow_symlink == false && $this->checkpath($filename) == false) {
+			$app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+			return false;
+		}
+		if(file_exists($filename)) unlink($filename);
+		return file_put_contents($filename, $data);
+	}
+	
+	function file_get_contents($filename, $allow_symlink = false) {
+		global $app;
+		if($allow_symlink == false && $this->checkpath($filename) == false) {
+			$app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+			return false;
+		}
+		return file_get_contents($filename, $data);
+	}
+	
+	function rename($filename, $new_filename, $allow_symlink = false) {
+		global $app;
+		if($allow_symlink == false && $this->checkpath($filename) == false) {
+			$app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+			return false;
+		}
+		return rename($filename, $new_filename);
+	}
+	
+	function mkdir($dirname, $allow_symlink = false) {
+		global $app;
+		if($allow_symlink == false && $this->checkpath($dirname) == false) {
+			$app->log("Action aborted, file is a symlink: $dirname",LOGLEVEL_WARN);
+			return false;
+		}
+		if(@mkdir($dirname)) {
+			return true;
+		} else {
+			$app->log("mkdir failed: $dirname",LOGLEVEL_DEBUG);
+			return false;
+		}
+	}
+	
+	function unlink($filename) {
+		if(file_exists($filename) || is_link($filename)) {
+			return unlink($filename);
+		}
+	}
+	
+	function copy($file1,$file2) {
+		return copy($file1,$file2);
+	}
+	
+	function touch($file, $allow_symlink = false){
+	  global $app;
+	  if($allow_symlink == false && @file_exists($file) && $this->checkpath($file) == false) {
+		$this->unlink($file);
+	  }
+	  if(@touch($file)) {
+			return true;
+	  } else {
+			$app->log("touch failed: $file",LOGLEVEL_DEBUG);
+			return false;
+	  }
+	}
+	
+	function checkpath($path) {
+		$path = trim($path);
+		//* We allow only absolute paths
+		if(substr($path,0,1) != '/') return false;
+		
+		//* We allow only some characters in the path
+		if(!preg_match('/^\/[a-zA-Z0-9_\/\.\-]{1,}$/',$path)) return false;
+		
+		//* Check path for symlinks
+		$path_parts = explode('/',$path);
+		$testpath = '';
+		foreach($path_parts as $p) {
+			$testpath .= '/'.$p;
+			if(is_link($testpath)) return false;
+		}
+		
+		return true;
 	}
 	
 	/**
@@ -653,6 +822,7 @@
 	  	}
 	}
 	
+	/*
 	function usermod($user, $groups){
 		global $app;
 	  	if($this->is_user($user)){
@@ -692,6 +862,7 @@
 		    return false;
 	  	}
 	}
+	*/
 	
 	/**boot autostart etc
 	 *
@@ -926,7 +1097,7 @@
 	 *
 	 */
 	function network_info(){
-		$dist = $this->server_conf["dist"];
+		$dist = $this->server_conf['dist'];
 	  	ob_start();
 	  	passthru('ifconfig');
 	  	$output = ob_get_contents();
@@ -950,9 +1121,9 @@
 	      		}
 	      		$output = trim(ob_get_contents());
 	      		ob_end_clean();
-	      		if($output != ""){
-	        		$ifconfig["INTERFACE"][$interface] = $output;
-	        		$ifconfig["IP"][$output] = $interface;
+	      		if($output != ''){
+	        		$ifconfig['INTERFACE'][$interface] = $output;
+	        		$ifconfig['IP'][$output] = $interface;
 	      		}
 	    	}
 	    	if(!empty($ifconfig)){
@@ -1046,7 +1217,7 @@
 	function make_trashscan(){
 		global $app;
 	  	//trashscan erstellen
-	  	// Template �ffnen
+	  	// Template Öffnen
 	  	$app->tpl->clear_all();
 	  	$app->tpl->define( array(table    => 'trashscan.master'));
 	
@@ -1087,23 +1258,23 @@
 	  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";
+	    $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';
+	    $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();
@@ -1132,6 +1303,11 @@
 	}
 	
 	function replaceLine($filename,$search_pattern,$new_line,$strict = 0,$append = 1) {
+		global $app;
+		if($this->checkpath($filename) == false) {
+			$app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+			return false;
+		}
 		$lines = @file($filename);
 		$out = '';
 		$found = 0;
@@ -1157,14 +1333,21 @@
 		
 		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") $out .= "\n";
+			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";
+			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) {
@@ -1187,32 +1370,49 @@
 		global $app;
 		
 		if($subfolder != '') {
-			$dir = escapeshellarg($maildir_path.'/.'.$subfolder);
-			$dir_cur = escapeshellarg($maildir_path.'/.'.$subfolder.'/cur');
-			$dir_new = escapeshellarg($maildir_path.'/.'.$subfolder.'/new');
-			$dir_tmp = escapeshellarg($maildir_path.'/.'.$subfolder.'/tmp');
+			$dir = escapeshellcmd($maildir_path.'/.'.$subfolder);
 		} else {
-			$dir = escapeshellarg($maildir_path);
-			$dir_cur = escapeshellarg($maildir_path.'/cur');
-			$dir_new = escapeshellarg($maildir_path.'/new');
-			$dir_tmp = escapeshellarg($maildir_path.'/tmp');
+			$dir = escapeshellcmd($maildir_path);
 		}
 		
-		exec("mkdir -p $dir_cur $dir_new $dir_tmp");
-		exec("chmod 0700 $dir $dir_cur $dir_new $dir_tmp");
+		if(!is_dir($dir)) mkdir($dir, 0700, true);
+
+		if($user != '' && $user != 'root' && $this->is_user($user)) {
+			$user = escapeshellcmd($user);
+			// I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
+			$group = $user;
+			if(is_dir($dir)) $this->chown($dir,$user);
+			if(is_dir($dir)) $this->chgrp($dir,$group);
+
+			$chown_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);
+				chgrp($dir.'/'.$mdsub, $group);
+			}
+		}
+
+		chmod($dir, 0700);
+		
+		/*
 		if($user != '' && $this->is_user($user) && $user != 'root') {
-			$user = escapeshellarg($user);
+			$user = escapeshellcmd($user);
 			// I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
 			$group = $user;
 			exec("chown $user:$group $dir $dir_cur $dir_new $dir_tmp");
 		}
+		*/
 		
 		//* Add the subfolder to the subscriptions and courierimapsubscribed files
 		if($subfolder != '') {
 			// Courier
 			if(!is_file($maildir_path.'/courierimapsubscribed')) {
-				$tmp_file = escapeshellarg($maildir_path.'/courierimapsubscribed');
+				$tmp_file = escapeshellcmd($maildir_path.'/courierimapsubscribed');
 				touch($tmp_file);
 				chmod($tmp_file, 0744);
 				chown($tmp_file,'vmail');
@@ -1222,7 +1422,7 @@
 			
 			// Dovecot
 			if(!is_file($maildir_path.'/subscriptions')) {
-				$tmp_file = escapeshellarg($maildir_path.'/subscriptions');
+				$tmp_file = escapeshellcmd($maildir_path.'/subscriptions');
 				touch($tmp_file);
 				chmod($tmp_file, 0744);
 				chown($tmp_file,'vmail');
@@ -1234,6 +1434,168 @@
 		$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->mkdir($new_path);
+					$this->chmod($new_path,$mode);
+					if($user != '') $this->chown($new_path,$user);
+					if($group != '') $this->chgrp($new_path,$group);
+				}
+			}
+		}
+		
+	}
+	
+	//* Check if a application is installed
+	function is_installed($appname) {
+		exec('which '.escapeshellcmd($appname).' 2> /dev/null',$out,$returncode);
+		if(isset($out[0]) && stristr($out[0],$appname) && $returncode == 0) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	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);
+			return false;
+		}
+		
+		//* 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,'..')) exec('chattr +i '.escapeshellcmd($document_root));
+		} else {
+			//* Remove protection
+			if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr -i '.escapeshellcmd($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);
+				}
+			}
+			unset($passwd_file_array);
+		}
+		
+		//* 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);
+					}
+				}
+			}
+			unset($group_file_array);
+			
+			$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);
+					}
+				}
+			}
+			unset($group_file_array);
+		}
+		
+		
+		//* 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);
+					}
+				}
+			}
+			unset($shadow_file_array);
+		}
+	}
+	
+	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 " on '.$mountpoint.' type "';
+		exec($cmd, $output, $return_var);
+		return $return_var == 0 ? true : false; 
+	}
 
 }
 ?>

--
Gitblit v1.9.1