* NTLM: move ntlm login code from phpgwapi to api to allow NTLM login in 16.1 minimal install

This commit is contained in:
Ralf Becker 2016-07-15 08:05:44 +02:00
parent e1f8fa7799
commit 847fb38194
4 changed files with 223 additions and 1 deletions

41
api/ntlm/README Normal file
View File

@ -0,0 +1,41 @@
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.
Firefox (at least 3.6) requires to manually enable NTLM Auth via about:config:
search for ntlm and set "network.automatic-ntlm-auth.trusted-uris" to the domain
your EGroupware install is using. Otherwise you will only get a popup to enter
username (with prepended windows domain eg. DOMAIN\username) and password.
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

79
api/ntlm/egroupware.conf Normal file
View File

@ -0,0 +1,79 @@
#
# Apache and PHP configuration for EGroupware using NTLM authentication
#
# This version of EGroupware configuration might not be as up to date as
# the one in /usr/share/doc/rpm-build/apache.conf!
#
# Version: $Id$
#
# this makes EGroupware available for all vhosts
Alias /egroupware /usr/share/egroupware
# Enable ActiveSync protocol support via eSync app
Alias /Microsoft-Server-ActiveSync /usr/share/egroupware/activesync/index.php
RedirectMatch ^/.well-known/(caldav|carddav)$ /egroupware/groupdav.php/
# iOS 4.3+ calendar requires that to autodetect accounts
RedirectMatch ^(/principals/users/.*)$ /egroupware/groupdav.php$1
<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
<IfModule !mod_authz_core.c>
# Apache 2.4
Order allow,deny
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
# Apache 2.4
Require all granted
</IfModule>
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 short_open_tag on
php_flag track_vars on
php_flag display_errors off
# E_ALL & ~E_NOTICE & ~E_STRICT = 8191 - 8 - 2048 = 6135
php_value error_reporting 6135
php_value max_execution_time 90
php_admin_value mbstring.func_overload 0
php_value memory_limit 128M
php_value session.gc_maxlifetime 14400
php_value include_path .
php_admin_value open_basedir /usr/share/egroupware:/var/lib/egroupware:/tmp:/usr/bin/zip
php_value upload_max_filesize 64M
php_admin_value upload_tmp_dir /tmp
php_value post_max_size 65M
<Files ~ "\.inc\.php$">
<IfModule !mod_authz_core.c>
# Apache 2.4
Order allow,deny
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
# Apache 2.4
Require all denied
</IfModule>
</Files>
</Directory>

102
api/ntlm/index.php Normal file
View File

@ -0,0 +1,102 @@
<?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-2016 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$
*/
use EGroupware\Api;
/**
* Check if given domain is either whitelisted, the current one or the EGroupware one
*
* Used to NOT redirect to arbitrary urls.
*
* @param string $url full url or just path, later is always allowed, as it stays within the domain
* @return boolean
*/
function check_domain($url)
{
$whitelisted = array(
$_SERVER['HTTP_HOST'], // can contain :port
// add additional domains-names (just full qualified hostnames) here
);
if ($GLOBALS['egw_info']['server']['webserver_url'][0] === 'h')
{
$whitelisted[] = parse_url($GLOBALS['egw_info']['server']['webserver_url'], PHP_URL_HOST);
}
$parts = parse_url($url);
$host = $parts['host'].($parts['port'] ? ':'.$parts['port'] : '');
return $url[0] == '/' || in_array($host, $whitelisted);
}
/**
* 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)
{
if (isset($_GET['forward']) && check_domain($_GET['forward']))
{
header('Location: '.$_GET['forward']);
}
else
{
header('Location: ../../login.php'.(isset($_REQUEST['phpgw_forward']) ? '?phpgw_forward='.urlencode($_REQUEST['phpgw_forward']) : ''));
}
exit;
}
return $sessionid;
}
$GLOBALS['egw_info']['flags'] = array(
'noheader' => True,
'currentapp' => 'api',
'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 (isset($_GET['forward']) && check_domain($_GET['forward']))
{
$forward = $_GET['forward'];
Api\Cache::setSession('login', 'referer', $forward);
}
elseif ($_REQUEST['phpgw_forward'])
{
$forward = '../..'.(isset($_GET['phpgw_forward']) ? urldecode($_GET['phpgw_forward']) : @$_POST['phpgw_forward']);
}
else
{
$forward = '../../index.php';
}
// commiting the session, before redirecting might fix racecondition in session creation
$GLOBALS['egw']->session->commit_session();
header('Location: '.$forward);

View File

@ -322,7 +322,7 @@ class Egw extends Egw\Base
$query = preg_replace('/[&]?sessionid(=|%3D)[^&]+&kp3(=|%3D)[^&]+&domain=.*$/','',$_SERVER['QUERY_STRING']);
if ($GLOBALS['egw_info']['server']['http_auth_types'])
{
$redirect = '/phpgwapi/ntlm/index.php?';
$redirect = '/api/ntlm/index.php?';
}
else
{