mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-24 17:04:14 +01:00
1. NTLM Single Sign ON
NTLM SSO removes Windows users on a PC, which is a member of a Windows domain and who are logged into that domain, from the need to explicitly log into eGW. They simply point IE to the eGW URL (eg. http://domain.com/egroupware/) and start working. They can of cause explicitly log out and log in as an other user. For more information look at the README at http://www.egroupware.org/viewvc/trunk/phpgwapi/ntml/README 2. different authentication for SyncML and/or GroupDAV You can now use eg. an external auth provider for the login via the WebGUI (eg. ADS) and the passwords stored in SQL for SyncML.
This commit is contained in:
parent
5477c71045
commit
b5c28fba48
@ -17,15 +17,6 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
$GLOBALS['sessionid'] = isset($_GET['sessionid']) ? $_GET['sessionid'] : @$_COOKIE['sessionid'];
|
||||
if(!$GLOBALS['sessionid'])
|
||||
{
|
||||
Header('Location: login.php'.
|
||||
(isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING']) ?
|
||||
'?phpgw_forward='.urlencode('/index.php?'.$_SERVER['QUERY_STRING']):''));
|
||||
exit;
|
||||
}
|
||||
|
||||
if(isset($_GET['hasupdates']) && $_GET['hasupdates'] == 'yes')
|
||||
{
|
||||
$hasupdates = True;
|
||||
|
@ -11,10 +11,17 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
// allow to set an application depending authentication type (eg. for syncml, groupdav, ...)
|
||||
if (isset($GLOBALS['egw_info']['server']['auth_type_'.$GLOBALS['egw_info']['flags']['currentapp']]) &&
|
||||
$GLOBALS['egw_info']['server']['auth_type_'.$GLOBALS['egw_info']['flags']['currentapp']])
|
||||
{
|
||||
$GLOBALS['egw_info']['server']['auth_type'] = $GLOBALS['egw_info']['server']['auth_type_'.$GLOBALS['egw_info']['flags']['currentapp']];
|
||||
}
|
||||
if(empty($GLOBALS['egw_info']['server']['auth_type']))
|
||||
{
|
||||
$GLOBALS['egw_info']['server']['auth_type'] = 'sql';
|
||||
}
|
||||
//error_log('using auth_type='.$GLOBALS['egw_info']['server']['auth_type'].', currentapp='.$GLOBALS['egw_info']['flags']['currentapp']);
|
||||
include(EGW_API_INC.'/class.auth_'.$GLOBALS['egw_info']['server']['auth_type'].'.inc.php');
|
||||
|
||||
/**
|
||||
|
@ -131,7 +131,6 @@ class egw extends egw_minimal
|
||||
// setup the other subclasses
|
||||
$this->translation = new translation();
|
||||
$this->common = new common();
|
||||
$this->auth = new auth();
|
||||
$this->accounts = accounts::getInstance();
|
||||
$this->acl = new acl();
|
||||
/* Do not create the session object if called by the sessions class. This way
|
||||
@ -277,7 +276,9 @@ class egw extends egw_minimal
|
||||
}
|
||||
// this removes the sessiondata if its saved in the URL
|
||||
$query = preg_replace('/[&]?sessionid(=|%3D)[^&]+&kp3(=|%3D)[^&]+&domain=.*$/','',$_SERVER['QUERY_STRING']);
|
||||
Header('Location: '.$GLOBALS['egw_info']['server']['webserver_url'].'/login.php?cd=10&phpgw_forward='.urlencode($relpath.(!empty($query) ? '?'.$query : '')));
|
||||
$redirect = '/login.php?cd=10&';
|
||||
if ($GLOBALS['egw_info']['server']['http_auth_types']) $redirect = '/phpgwapi/ntlm/index.php?';
|
||||
Header('Location: '.$GLOBALS['egw_info']['server']['webserver_url'].$redirect.'phpgw_forward='.urlencode($relpath.(!empty($query) ? '?'.$query : '')));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
@ -560,9 +560,10 @@
|
||||
* @param string $passwd user password
|
||||
* @param string $passwd_type type of password being used, ie plaintext, md5, sha1
|
||||
* @param boolean $no_session_needed=false dont create a real session, eg. for GroupDAV clients using only basic auth, no cookie support
|
||||
* @param boolean $auth_check=true if false, the user is loged in without checking his password (eg. for single sign on), default = true
|
||||
* @return string session id
|
||||
*/
|
||||
function create($login,$passwd = '',$passwd_type = '',$no_session=false)
|
||||
function create($login,$passwd = '',$passwd_type = '',$no_session=false,$auth_check=true)
|
||||
{
|
||||
if (is_array($login))
|
||||
{
|
||||
@ -577,6 +578,7 @@
|
||||
$this->passwd = $passwd;
|
||||
$this->passwd_type = $passwd_type;
|
||||
}
|
||||
//error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check)");
|
||||
|
||||
$this->clean_sessions();
|
||||
$this->split_login_domain($login,$this->account_lid,$this->account_domain);
|
||||
@ -618,7 +620,7 @@
|
||||
|
||||
if (($blocked = $this->login_blocked($login,$user_ip)) || // too many unsuccessful attempts
|
||||
$GLOBALS['egw_info']['server']['global_denied_users'][$this->account_lid] ||
|
||||
!$GLOBALS['egw']->auth->authenticate($this->account_lid, $this->passwd, $this->passwd_type) ||
|
||||
$auth_check && !$GLOBALS['egw']->auth->authenticate($this->account_lid, $this->passwd, $this->passwd_type) ||
|
||||
$this->account_id && $GLOBALS['egw']->accounts->get_type($this->account_id) == 'g')
|
||||
{
|
||||
$this->reason = $blocked ? 'blocked, too many attempts' : 'bad login or password';
|
||||
|
@ -244,51 +244,57 @@ class EGW_SyncML_State extends Horde_SyncML_State
|
||||
|
||||
}
|
||||
|
||||
function isAuthorized()
|
||||
{
|
||||
if (!$this->_isAuthorized) {
|
||||
|
||||
if(!isset($this->_locName) && !isset($this->_password))
|
||||
function isAuthorized()
|
||||
{
|
||||
if (!$this->_isAuthorized)
|
||||
{
|
||||
Horde::logMessage('SyncML: Authentication not yet possible currently. Username and password not available' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!isset($this->_password))
|
||||
{
|
||||
Horde::logMessage('SyncML: Authentication not yet possible currently. Password not available' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(strpos($this->_locName,'@') === False)
|
||||
{
|
||||
$this->_locName .= '@'.$GLOBALS['egw_info']['server']['default_domain'];
|
||||
}
|
||||
|
||||
#Horde::logMessage('SyncML: authenticate with username: ' . $this->_locName . ' and password: ' . $this->_password, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
||||
if($GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($this->_locName,$this->_password,'text'))
|
||||
{
|
||||
$this->_isAuthorized = true;
|
||||
Horde::logMessage('SyncML_EGW: Authentication of ' . $this->_locName . '/' . $GLOBALS['sessionid'] . ' succeded' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
if(!isset($this->_locName) && !isset($this->_password))
|
||||
{
|
||||
Horde::logMessage('SyncML: Authentication not yet possible currently. Username and password not available' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!isset($this->_password))
|
||||
{
|
||||
Horde::logMessage('SyncML: Authentication not yet possible currently. Password not available' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(strpos($this->_locName,'@') === False)
|
||||
{
|
||||
$this->_locName .= '@'.$GLOBALS['egw_info']['server']['default_domain'];
|
||||
}
|
||||
|
||||
#Horde::logMessage('SyncML: authenticate with username: ' . $this->_locName . ' and password: ' . $this->_password, __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
|
||||
if($GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($this->_locName,$this->_password,'text'))
|
||||
{
|
||||
$this->_isAuthorized = true;
|
||||
Horde::logMessage('SyncML_EGW: Authentication of ' . $this->_locName . '/' . $GLOBALS['sessionid'] . ' succeded' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_isAuthorized = false;
|
||||
Horde::logMessage('SyncML: Authentication of ' . $this->_locName . ' failed' , __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* RalfBecker 2008-07-16: commented out, as return value is NOT used anyway
|
||||
* It is not a security problem, as without a valid SyncML session
|
||||
* one is created anyway. The horde SyncML codes handles that on it's own.
|
||||
* Leaving it in gives problems with NTLM auth, as verify redirects there.
|
||||
*
|
||||
else
|
||||
{
|
||||
$this->_isAuthorized = false;
|
||||
Horde::logMessage('SyncML: Authentication of ' . $this->_locName . ' failed' , __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// store sessionID in a variable, because ->verify maybe resets that value
|
||||
$sessionID = session_id();
|
||||
if(!$GLOBALS['egw']->session->verify($sessionID, 'staticsyncmlkp3')) {
|
||||
Horde::logMessage('SyncML_EGW: egw session(' .$sessionID. ') not verified ' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
// store sessionID in a variable, because ->verify maybe resets that value
|
||||
$sessionID = session_id();
|
||||
if(!$GLOBALS['egw']->session->verify($sessionID, 'staticsyncmlkp3')) {
|
||||
Horde::logMessage('SyncML_EGW: egw session(' .$sessionID. ') not verified ' , __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||
}
|
||||
}*/
|
||||
|
||||
return $this->_isAuthorized;
|
||||
}
|
||||
return $this->_isAuthorized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all locid<->guid mappings for the given type.
|
||||
|
40
phpgwapi/ntlm/README
Normal file
40
phpgwapi/ntlm/README
Normal file
@ -0,0 +1,40 @@
|
||||
Steps to set up NTLM Single Sign On for eGroupWare 1.6
|
||||
======================================================
|
||||
(Version: $Id$)
|
||||
|
||||
NTLM SSO removes Windows users on a PC, which is a member of a Windows domain
|
||||
and who are logged into that domain, from the need to explicitly log into eGW.
|
||||
They simply point IE to the eGW URL (eg. http://domain.com/egroupware/) and
|
||||
start working. They can of cause explicitly log out and log in as an other user.
|
||||
|
||||
As far as I tested, Firefox 3 only allows to enter user (including domain(!), eg. DOMAIN\user)
|
||||
and password in a popup, which then get's checked from apache via winbind.
|
||||
It does NOT automatically log you in, if you're logged into the domain on your PC!
|
||||
|
||||
Here's in short what you need:
|
||||
-----------------------------
|
||||
1. eGW 1.6 running on Apache
|
||||
2. a fully working and configured winbind configuration (not described here)
|
||||
3. mod_ntlm_winbind (eg. for openSUSE from their package apache2-mod_auth_ntml_winbind)
|
||||
4. an Apache configuration with the egroupware.conf in this directory (expecting eGW
|
||||
to be installed in it's default location /usr/share/egroupware) or port the necessary
|
||||
settings to your Apache configuration.
|
||||
--> You NEED to change the domain from "TEST" to your used domain name!
|
||||
5. Make the following changes in eGW's setup >> configuraition:
|
||||
- HTTP auth types (comma-separated) to use without login-page, eg. "NTLM": NTLM
|
||||
- Select which type of authentication you are using: ADS
|
||||
This is not needed for NTLM authentication, but allows the users to use their windows
|
||||
user and password to log into eGW, if they log in using an other browser or location.
|
||||
- Host/IP Domain controler: ... <-- NEED to be filled out
|
||||
- Domain name: ... <-- NEED to be filled out, same domain name as above
|
||||
6. If you use EMail, you have to explicitly specify user/pw to use for contacting the IMAP
|
||||
(and SMTP) server, it's no longer available to eGW!
|
||||
|
||||
Please note the DC has to be started before you start winbind!
|
||||
|
||||
The eGW code should work with every Apache authentication, which sets REMOTE_USER and AUTH_TYPE.
|
||||
With slight modifications (different var names) it should work eg. with SSL client certificates.
|
||||
|
||||
This feature was sponsored by Sponsored by Carl Knauber Holding GmbH und Co. KG.
|
||||
|
||||
Ralf Becker
|
58
phpgwapi/ntlm/egroupware.conf
Normal file
58
phpgwapi/ntlm/egroupware.conf
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Apache and PHP configuration for eGroupWare using NTLM authentication
|
||||
#
|
||||
# Version: $Id$
|
||||
#
|
||||
|
||||
Alias /egroupware /usr/share/egroupware
|
||||
|
||||
<Directory /usr/share/egroupware/phpgwapi/ntlm/>
|
||||
AuthName "NTLM eGroupWare Authentication"
|
||||
NTLMAuth on
|
||||
NegotiateAuth off
|
||||
NTLMBasicRealm TEST
|
||||
NTLMBasicAuth on
|
||||
NTLMAuthHelper "/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp"
|
||||
NegotiateAuthHelper "/usr/bin/ntlm_auth --helper-protocol=gss-spnego"
|
||||
PlaintextAuthHelper "/usr/bin/ntlm_auth --domain=TEST.LOCAL --helper-protocol=squid-2.5-basic"
|
||||
NTLMBasicAuthoritative on
|
||||
AuthType NTLM
|
||||
require valid-user
|
||||
</Directory>
|
||||
|
||||
<Directory /usr/share/egroupware/>
|
||||
Options FollowSymLinks ExecCGI
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
DirectoryIndex index.html index.php
|
||||
AddHandler cgi-script .cgi
|
||||
AddDefaultCharset Off
|
||||
php_flag file_uploads on
|
||||
php_flag log_errors on
|
||||
php_flag magic_quotes_gpc off
|
||||
php_flag magic_quotes_runtime off
|
||||
php_flag register_globals off
|
||||
php_flag track_vars on
|
||||
php_value error_reporting E_ALL
|
||||
php_value max_execution_time 90
|
||||
php_value mbstring.func_overload 7
|
||||
php_value memory_limit 48M
|
||||
php_value session.gc_maxlifetime 14400
|
||||
php_value open_basedir /usr/share/egroupware:/var/lib/egroupware:/tmp:/var/lib/php5
|
||||
php_value upload_max_filesize 16M
|
||||
<Files ~ "\.inc\.php$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Files>
|
||||
</Directory>
|
||||
|
||||
<Directory /usr/share/egroupware/phpsysinfo/>
|
||||
php_value open_basedir /
|
||||
</Directory>
|
||||
|
||||
<Location /egroupware/rpc.php>
|
||||
php_value mbstring.func_overload 0
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Location>
|
61
phpgwapi/ntlm/index.php
Normal file
61
phpgwapi/ntlm/index.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* eGroupWare - NTLM or other http auth access without login page
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @subpackage authentication
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2008 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* check if the given user has access
|
||||
*
|
||||
* Create a session or if the user has no account return authenticate header and 401 Unauthorized
|
||||
*
|
||||
* @param array &$account
|
||||
* @return int session-id
|
||||
*/
|
||||
function check_access(&$account)
|
||||
{
|
||||
//error_log("AUTH_TYPE={$_SERVER['AUTH_TYPE']}, REMOTE_USER={$_SERVER['REMOTE_USER']}, HTTP_USER_AGENT={$_SERVER['HTTP_USER_AGENT']}, http_auth_types={$GLOBALS['egw_info']['server']['http_auth_types']}");
|
||||
|
||||
if (isset($_SERVER['REMOTE_USER']) && $_SERVER['REMOTE_USER'] && isset($_SERVER['AUTH_TYPE']) &&
|
||||
isset($GLOBALS['egw_info']['server']['http_auth_types']) && $GLOBALS['egw_info']['server']['http_auth_types'] &&
|
||||
in_array(strtoupper($_SERVER['AUTH_TYPE']),explode(',',strtoupper($GLOBALS['egw_info']['server']['http_auth_types']))))
|
||||
{
|
||||
if (strpos($account=$_SERVER['REMOTE_USER'],'\\') !== false)
|
||||
{
|
||||
list(,$account) = explode('\\',$account,2);
|
||||
}
|
||||
$sessionid = $GLOBALS['egw']->session->create($account,null,'ntlm',false,false); // false=no auth check
|
||||
//error_log("create('$account',null,'ntlm',false,false)=$sessionid ({$GLOBALS['egw']->session->reason})");
|
||||
}
|
||||
if (!$sessionid)
|
||||
{
|
||||
header('Location: ../../login.php'.(isset($_REQUEST['phpgw_forward']) ? '?'.$_REQUEST['phpgw_forward'] : ''));
|
||||
exit;
|
||||
}
|
||||
return $sessionid;
|
||||
}
|
||||
|
||||
$GLOBALS['egw_info']['flags'] = array(
|
||||
'noheader' => True,
|
||||
'currentapp' => 'home',
|
||||
'autocreate_session_callback' => 'check_access',
|
||||
);
|
||||
// if you move this file somewhere else, you need to adapt the path to the header!
|
||||
include(dirname(__FILE__).'/../../header.inc.php');
|
||||
|
||||
if ($_REQUEST['phpgw_forward'])
|
||||
{
|
||||
$forward = '../../'.(isset($_GET['phpgw_forward']) ? urldecode($_GET['phpgw_forward']) : @$_POST['phpgw_forward']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$forward = '../../index.php';
|
||||
}
|
||||
header('Location: '.$forward);
|
3
rpc.php
3
rpc.php
@ -24,6 +24,9 @@ $GLOBALS['egw_info'] = array(
|
||||
);
|
||||
include('./header.inc.php');
|
||||
|
||||
// allow to use an authentication specific for SyncML
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'syncml';
|
||||
|
||||
$errors = array();
|
||||
|
||||
// SyncML works currently only with PHP sessions
|
||||
|
@ -175,7 +175,7 @@
|
||||
<td colspan="2"><b>{lang_Authentication_/_Accounts}</b></td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<tr class="row_off">
|
||||
<td>{lang_Select_which_type_of_authentication_you_are_using}:</td>
|
||||
<td>
|
||||
<select name="newsettings[auth_type]">
|
||||
@ -191,6 +191,46 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<td>{lang_Authentication_type_for_application}: <b>SyncML</b></td>
|
||||
<td>
|
||||
<select name="newsettings[auth_type_syncml]">
|
||||
<option value="">{lang_Standard,_as_defined_above}</option>
|
||||
<option value="sql"{selected_auth_type_syncml_sql}>SQL</option>
|
||||
<option value="sqlssl"{selected_auth_type_syncml_sqlssl}>SQL / SSL</option>
|
||||
<option value="ldap"{selected_auth_type_syncml_ldap}>LDAP</option>
|
||||
<option value="ads"{selected_auth_type_syncml_ads}>ADS</option>
|
||||
<option value="mail"{selected_auth_type_syncml_mail}>Mail</option>
|
||||
<option value="http"{selected_auth_type_syncml_http}>HTTP</option>
|
||||
<option value="nis"{selected_auth_type_syncml_nis}>NIS</option>
|
||||
<option value="pam"{selected_auth_type_syncml_pam}>PAM</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<td>{lang_Authentication_type_for_application}: <b>GroupDAV/CalDAV/CardDAV</b></td>
|
||||
<td>
|
||||
<select name="newsettings[auth_type_groupdav]">
|
||||
<option value="">{lang_Standard,_as_defined_above}</option>
|
||||
<option value="sql"{selected_auth_type_groupdav_sql}>SQL</option>
|
||||
<option value="sqlssl"{selected_auth_type_groupdav_sqlssl}>SQL / SSL</option>
|
||||
<option value="ldap"{selected_auth_type_groupdav_ldap}>LDAP</option>
|
||||
<option value="ads"{selected_auth_type_groupdav_ads}>ADS</option>
|
||||
<option value="mail"{selected_auth_type_groupdav_mail}>Mail</option>
|
||||
<option value="http"{selected_auth_type_groupdav_http}>HTTP</option>
|
||||
<option value="nis"{selected_auth_type_groupdav_nis}>NIS</option>
|
||||
<option value="pam"{selected_auth_type_groupdav_pam}>PAM</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<td>{lang_HTTP_auth_types_(comma-separated)_to_use_without_login-page, eg. "NTLM"}:</td>
|
||||
<td>
|
||||
<input name="newsettings[http_auth_types]" value="{value_http_auth_types}" size="20" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<td>{lang_Select_where_you_want_to_store/retrieve_user_accounts}:</td>
|
||||
|
Loading…
Reference in New Issue
Block a user