diff --git a/api/ntlm/README b/api/ntlm/README
new file mode 100644
index 0000000000..ff3054dc46
--- /dev/null
+++ b/api/ntlm/README
@@ -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
\ No newline at end of file
diff --git a/api/ntlm/egroupware.conf b/api/ntlm/egroupware.conf
new file mode 100644
index 0000000000..154a766a99
--- /dev/null
+++ b/api/ntlm/egroupware.conf
@@ -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
+
+
+ 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
+
+
+
+ Options FollowSymLinks ExecCGI
+ AllowOverride None
+
+ # Apache 2.4
+ Order allow,deny
+ Allow from all
+
+
+ # Apache 2.4
+ Require all granted
+
+ 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
+
+
+ # Apache 2.4
+ Order allow,deny
+ Deny from all
+
+
+ # Apache 2.4
+ Require all denied
+
+
+
diff --git a/api/ntlm/index.php b/api/ntlm/index.php
new file mode 100644
index 0000000000..1097049b6a
--- /dev/null
+++ b/api/ntlm/index.php
@@ -0,0 +1,102 @@
+
+ * @copyright (c) 2008-2016 by Ralf Becker
+ * @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);
diff --git a/api/src/Egw.php b/api/src/Egw.php
index bfbb4fb689..6c8687c968 100644
--- a/api/src/Egw.php
+++ b/api/src/Egw.php
@@ -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
{