From 5c4970210d62fb6b5c8b6a4e59c6648d80939c7a Mon Sep 17 00:00:00 2001
From: vogelor <vogelor@ispconfig3>
Date: Sun, 14 Dec 2008 12:31:52 +0000
Subject: [PATCH] It is now possible to "login as" as admin from the user-list
 It is now possible to redirect to a different url as result of the
 loadContent AJAX function

---
 interface/web/admin/login_as.php              | 72 +++++++++++++++++++
 interface/web/admin/templates/users_list.htm  |  1 +
 interface/web/js/scrigo.js.php                |  5 +-
 interface/web/login/index.php                 | 44 +++++++++++-
 interface/web/login/logout.php                | 37 ++++++++--
 .../default/css/screen/content_ispc.css       |  1 +
 .../web/themes/default/templates/main.tpl.htm |  2 +-
 7 files changed, 153 insertions(+), 9 deletions(-)
 create mode 100644 interface/web/admin/login_as.php

diff --git a/interface/web/admin/login_as.php b/interface/web/admin/login_as.php
new file mode 100644
index 0000000000..4c9c0b6ca2
--- /dev/null
+++ b/interface/web/admin/login_as.php
@@ -0,0 +1,72 @@
+<?php
+/*
+Copyright (c) 2008, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com
+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.
+*/
+
+
+require_once('../../lib/config.inc.php');
+require_once('../../lib/app.inc.php');
+
+/* Check permissions for module */
+$app->auth->check_module_permissions('admin');
+
+/* for security reasons ONLY the admin can login as other user */
+if ($_SESSION["s"]["user"]["typ"] != 'admin') {
+	die ("You don't have the right to login as other user!");
+}
+
+/* get the id of the user (must be int!) */
+if (!isset($_GET['id'])){
+    die ("No user selected!");
+}
+$userId = intval($_GET['id']);
+
+/*
+ * Get the data to login as user x
+ */
+$dbData = $app->db->queryOneRecord(
+    "SELECT username, passwort FROM sys_user WHERE userid = " . $userId);
+
+/*
+ * Now generate the login-Form
+ */
+echo '
+	<br /> <br />	<br /> <br />
+	Do you want to login as user ' .  $dbData['username'] . '?<br />
+	If you do so, you can "go back" by clicking at logout.<br />
+	<div style="visibility:hidden">
+		<input type="text" name="username" value="' . $dbData['username'] . '" />
+		<input type="password" name="passwort" value="' . $dbData['passwort'] .'" />
+	</div>
+	<input type="hidden" name="s_mod" value="login" />
+	<input type="hidden" name="s_pg" value="index" />
+    <div class="wf_actions buttons">
+      <button class="positive iconstxt icoPositive" type="button" value="Yes, login as Client" onClick="submitLoginForm(' . "'pageForm'" . ');"><span>Yes, login as Client</span></button>
+      <button class="negative iconstxt icoNegative" type="button" value="No, back to list" onClick="loadContent('. "'admin/users_list.php'" . ');"><span>No, back to list</span></button>
+    </div>
+';
+?>
diff --git a/interface/web/admin/templates/users_list.htm b/interface/web/admin/templates/users_list.htm
index b222cb6102..4829e40608 100644
--- a/interface/web/admin/templates/users_list.htm
+++ b/interface/web/admin/templates/users_list.htm
@@ -40,6 +40,7 @@
             <td class="tbl_col_ort"><a href="#" onClick="loadContent('admin/users_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="ort"}</a></td>
             <td class="tbl_col_buttons">
               <div class="buttons icons16">    
+			    <a class="icons16 icoLoginAs" href="#" onclick="loadContent('/admin/login_as.php?id={tmpl_var name='id'}');"><span>{tmpl_var name='login_as_txt'}</span></a>
                 <a class="icons16 icoDelete" href="javascript: del_record('admin/users_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
               </div>
             </td>
diff --git a/interface/web/js/scrigo.js.php b/interface/web/js/scrigo.js.php
index 6e6affb204..519f767e01 100644
--- a/interface/web/js/scrigo.js.php
+++ b/interface/web/js/scrigo.js.php
@@ -159,9 +159,12 @@ function submitUploadForm(formname,target) {
 function loadContent(pagename) {
 	var pageContentCallback2 = {
 		success: function(o) {
-				if(o.responseText.indexOf('HEADER_REDIRECT:') > -1) {
+			if(o.responseText.indexOf('HEADER_REDIRECT:') > -1) {
 				var parts = o.responseText.split(':');
 				loadContent(parts[1]);
+			} else if (o.responseText.indexOf('URL_REDIRECT:') > -1) {
+				var newUrl= o.responseText.substr(o.responseText.indexOf('URL_REDIRECT:') + "URL_REDIRECT:".length);
+				document.location.href = newUrl;
 			} else {
 				document.getElementById('pageContent').innerHTML = o.responseText;
 			}
diff --git a/interface/web/login/index.php b/interface/web/login/index.php
index df30e3b784..5e9eb6867e 100644
--- a/interface/web/login/index.php
+++ b/interface/web/login/index.php
@@ -41,8 +41,11 @@ class login_index {
 		
 		global $app, $conf;
 		
-		if(isset($_SESSION['s']['user']) && is_array($_SESSION['s']['user']) && is_array($_SESSION['s']['module'])) {
-			die('HEADER_REDIRECT:'.$_SESSION['s']['module']['startpage']);
+		/* Redirect to page, if login form was NOT send */
+		if(count($_POST) == 0) {
+			if(isset($_SESSION['s']['user']) && is_array($_SESSION['s']['user']) && is_array($_SESSION['s']['module'])) {
+				die('HEADER_REDIRECT:'.$_SESSION['s']['module']['startpage']);
+			}
 		}
 		
 		$app->uses('tpl');
@@ -60,6 +63,34 @@ class login_index {
 	        $passwort = $app->db->quote($_POST['passwort']); 
 	
 	        if($username != '' and $passwort != '') {
+				/*
+				 *  Check, if there is a "login as" instead of a "normal" login
+				 */
+				if (isset($_SESSION['s']['user'])){
+					/*
+					 * only the admin can "login as" so if the user is NOT a admin, we
+					 * open the startpage (after killing the old session), so the user
+					 * is logout and has to start again!
+					 */
+					if ($_SESSION['s']['user']['typ'] != 'admin') {
+						/*
+						 * The actual user is NOT a admin, but maybe the admin
+						 * has logged in as "normal" user bevore...
+						 */
+						if (isset($_SESSION['s_old'])&& ($_SESSION['s_old']['user']['typ'] == 'admin')){
+							/* The "old" user is admin, so everything is ok */
+						}
+						else {
+							die("You don't have the right to 'login as'!");
+						}
+					}
+					$loginAs = true;
+				}
+				else {
+					/* normal login */
+					$loginAs = false;
+				}
+
 	        	//* Check if there already wrong logins
 	        	$sql = "SELECT * FROM `attempts_login` WHERE `ip`= '{$ip}' AND  `login_time` < NOW() + INTERVAL 15 MINUTE LIMIT 1";
 	        	$alreadyfailed = $app->db->queryOneRecord($sql);
@@ -67,7 +98,12 @@ class login_index {
 	        	if($alreadyfailed['times'] > 5) {
 	        		$error = $app->lng(1004);
 	        	} else {
-		        	$sql = "SELECT * FROM sys_user WHERE USERNAME = '$username' and ( PASSWORT = '".md5($passwort)."' or PASSWORT = password('$passwort') )";
+					if ($loginAs){
+			        	$sql = "SELECT * FROM sys_user WHERE USERNAME = '$username' and PASSWORT = '". $passwort. "'";
+					}
+					else {
+			        	$sql = "SELECT * FROM sys_user WHERE USERNAME = '$username' and ( PASSWORT = '".md5($passwort)."' or PASSWORT = password('$passwort') )";
+					}
 		            $user = $app->db->queryOneRecord($sql);
 		            if($user) {
 		                if($user['active'] == 1) {
@@ -75,7 +111,9 @@ class login_index {
 		                	$sql = "DELETE FROM `attempts_login` WHERE `ip`='{$ip}'";
 		                	$app->db->query($sql);
 		                	$user = $app->db->toLower($user);
+							if ($loginAs) $oldSession = $_SESSION['s_old'];
 		                    $_SESSION = array();
+							if ($loginAs) $_SESSION['s_old'] = $oldSession; // keep the way back!
 		                    $_SESSION['s']['user'] = $user;
 		                    $_SESSION['s']['user']['theme'] = isset($user['app_theme']) ? $user['app_theme'] : 'default';
 		                    $_SESSION['s']['language'] = $user['language'];
diff --git a/interface/web/login/logout.php b/interface/web/login/logout.php
index d4dae003b5..aa07714b67 100644
--- a/interface/web/login/logout.php
+++ b/interface/web/login/logout.php
@@ -30,19 +30,48 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 require_once('../../lib/config.inc.php');
 require_once('../../lib/app.inc.php');
 
+/*
+ * Check if the logout is forced
+ */
+$forceLogout = false;
+if (isset($_GET['l']) && ($_GET['l']== 1)) $forceLogout = true;
+
+/*
+ * if the admin is logged in as client, then ask, if the admin want't to
+ * "re-login" as admin again
+ */
+if ((isset($_SESSION['s_old']) && ($_SESSION['s_old']['user']['typ'] == 'admin')) &&
+	(!$forceLogout)){
+	echo '
+		<br /> <br />	<br /> <br />
+		Do you want to re-login as admin or log out?<br />
+		<div style="visibility:hidden">
+			<input type="text" name="username" value="' . $_SESSION['s_old']['user']['username'] . '" />
+			<input type="password" name="passwort" value="' . $_SESSION['s_old']['user']['passwort'] .'" />
+		</div>
+		<input type="hidden" name="s_mod" value="login" />
+		<input type="hidden" name="s_pg" value="index" />
+	    <div class="wf_actions buttons">
+	      <button class="positive iconstxt icoPositive" type="button" value="Yes, re-login as Admin" onClick="submitLoginForm(' . "'pageForm'" . ');"><span>Yes, re-login as Admin</span></button>
+	      <button class="negative iconstxt icoNegative" type="button" value="No, logout" onClick="loadContent('. "'login/logout.php?l=1'" . ');"><span>No, logout</span></button>
+	    </div>
+	';
+	exit;
+}
+
 $_SESSION["s"]["user"] = null;
 $_SESSION["s"]["module"] = null;
+$_SESSION['s_old'] = null;
 
 //header("Location: ../index.php?phpsessid=".$_SESSION["s"]["id"]);
 
-
 if($_SESSION["s"]["site"]["logout"] != '') {
-	header("Location: ".$_SESSION["s"]["site"]["logout"]);
+	echo('URL_REDIRECT:'.$_SESSION["s"]["site"]["logout"]);
 } else {
 	if($conf["interface_logout_url"] != '') {
-		header("Location: ".$conf["interface_logout_url"]);
+		echo('URL_REDIRECT:'.$conf["interface_logout_url"]);
 	} else {
-		header("Location: ../index.php");
+		echo('URL_REDIRECT:../index.php');
 	}
 }
 exit;
diff --git a/interface/web/themes/default/css/screen/content_ispc.css b/interface/web/themes/default/css/screen/content_ispc.css
index 4a33732d53..ab01dc4e42 100644
--- a/interface/web/themes/default/css/screen/content_ispc.css
+++ b/interface/web/themes/default/css/screen/content_ispc.css
@@ -288,5 +288,6 @@
 	.icons16.icoFilter { background-image: url(../../icons/x16/funnel.png); }
 	.icons16.icoEdit { background-image: url("../../icons/x16/wrench.png"); }
 	.icons16.icoDbAdmin { background-image: url("../../icons/x16/database.png"); }
+	.icons16.icoLoginAs { background-image: url("../../icons/x16/user_go.png"); }
 }
 
diff --git a/interface/web/themes/default/templates/main.tpl.htm b/interface/web/themes/default/templates/main.tpl.htm
index 4a44874766..c40e36a6f8 100644
--- a/interface/web/themes/default/templates/main.tpl.htm
+++ b/interface/web/themes/default/templates/main.tpl.htm
@@ -22,7 +22,7 @@
                     <a class="skip" href="#navigation" title="skip link">Skip to the navigation</a><span class="hideme">.</span>
                     <a class="skip" href="#content" title="skip link">Skip to the content</a><span class="hideme">.</span>
                     <!-- end: skip link navigation -->
-                    <span><a href="login/logout.php">Logout</a> | <a href="#" onclick="capp('help')">Help</a><!-- | <a href="#">Imprint</a>--></span>
+                    <span><a href="#" onclick="loadContent('login/logout.php');">Logout</a> | <a href="#" onclick="capp('help')">Help</a><!-- | <a href="#">Imprint</a>--></span>
                 </div>
                 <h1 id="ir-HeaderLogo" class="swap"><span>ISPConfig 3</span></h1>
                 <span>hosting control panel</span>
-- 
GitLab