[horde] Problems with PASSWD and LDAP
Andy Dorman
adorman at ironicdesign.com
Thu Jan 21 14:39:45 UTC 2016
On 01/21/2016 07:56 AM, Jan Schneider wrote:
> Zitat von David Cunningham <dcunningham at additionnetworks.net>:
>
>> Here is a further follow up…
>>
>> This works:
>>
>> <?php
>> $backends['ldap'] = array(
>> 'disabled' => false,
>> 'name' => 'Courier Mail Server',
>> 'preferred' =>
>> 'courier.additionnetworks.net<http://courier.additionnetworks.net>',
>> 'driver' => 'Ldap',
>> 'policy' => array(
>> 'minLength' => 6,
>> 'minNumeric' => 1,
>> ),
>> 'params' => array(
>> 'host' =>
>> 'courier.additionnetworks.net<http://courier.additionnetworks.net>',
>> 'port' => 389,
>> 'basedn' =>
>> 'ou=test.mecnet.net<http://test.mecnet.net>,ou=customers,dc=mecnet,dc=net',
>>
>> // LDAP object key attribute.
>> 'uid' => 'uid',
>> // The attribute storing the password.
>> //'attribute' => 'Password',
>> // These attributes will enable shadow password policies.
>> // 'shadowlastchange' => 'shadowLastChange',
>> // 'shadowmin' => 'shadowMin',
>> // This will be appended to the username when looking for the
>> userdn.
>> //'realm' => '',
>> // Use this filter when searching for the user's DN.
>> //'filter' => 'uid',
>> // Hash method to use when storing the password
>> 'encryption' => 'crypt',
>> // Whether to enable TLS for this LDAP connection
>> // Note: make sure that the host matches cn in the server
>> certificate.
>> 'tls' => false,
>> // Determine the user's DN. %u will be replaced by the user's ID.
>> // Alternatively, disable this option and instead use the
>> 'userdn'
>> // hook (config/hooks.php) to dynamically set the userdn.
>> //'userdn' => 'uid=%u,ou=%d,ou=customers,dc=mecnet,dc=net'
>> ),
>> );
>>
>>
>> But!!! I cannot do that… I need the domain name (IE,
>> test.mecnet.net<http://test.mecnet.net> in this example) to be dynamic
>> as I have dozens of different domains logging in. This user is
>> dcunningham at test.mecnet.net<mailto:dcunningham at test.mecnet.net>. I
>> need that OU to be dynamic. It says that %d should be replaced with
>> the domain, but it does not work. When searching the code, I do not
>> see a str_replace for %d… just %u.
>
> And it doesn't say that anywhere either. No idea where you got that
> information from.
>
>> Dave
>>
>>
>>
>>
>> On Jan 20, 2016, at 8:38 AM, David Cunningham
>> <dcunningham at additionnetworks.net<mailto:dcunningham at additionnetworks.net>>
>> wrote:
>>
>> Hi All, especially Jan,
>>
>> I never received a follow-up to this. Can you help?
>>
>> Dave
>>
>>
>>
>> On Jan 14, 2016, at 3:49 PM, David Cunningham
>> <dcunningham at additionnetworks.net<mailto:dcunningham at additionnetworks.net>>
>> wrote:
>>
>> {
>> // Example: Provide LDAP server with a userdn so that you do not
>> // have to perform anonymous binds.
>> return 'uid=' . $authid .
>> ',ou=$domain,ou=customers,dc=mecnet,dc=net';
>> }
>
> You need to parse the domain from the username. If $authid doesn't
> contain the domain, you need to get it from somewhere else.
>
We use OpenLDAP with a master write server and several replica dbs
hosted on each Horde/Imp web server and we use Imp for our authentication.
Below is our code in imp/config/hooks.local.php for checking credentials
and fetching and setting the IMAP server name. It may be more complex
than you would need for a single server hosting Horde and LDAP.
FWIW we also support multiple domains, so we manually build the dn
ourselves with this line in the code below:
$dn = 'uid=' . $userId . ',ou=addresses,o=antespam.com';
Hope it helps.
* AUTHENTICATION HOOK: pre-authentication actions.
*
* See horde/config/hooks.php.dist for more information.
*
* IMP uses the following credentials:
* - password: (string) The password for mail server authentication.
* - server: (string) [optional] Use this server key (see
* config/backends.php).
* - transparent: (boolean) If $credentials['authMethod'] is
* 'transparent', and you want IMP to use the
* userId/credentials generated in the preauthenticate
* hook, this must be true. If false, IMP will instead
* try to authenticate using hordeauth.
*
* The following credentials will exist in $credentials, but changing
* these values has no effect on authentication:
* - imp_server_key: (string; 'authenticate' only) The backend server
* key selected on the login page.
*/
public function preauthenticate($userId, $credentials)
{
Horde::log (sprintf ('In preauthenticate hook for: %s', $userId),
'DEBUG');
if ($userId && $credentials['authMethod'] == 'authenticate') {
// set IMAP server based on sideline server value saved in LDAP
for username
$dn = 'uid=' . $userId . ',ou=addresses,o=antespam.com';
$ldappass = $credentials['password'];
$justthese = array ("asSidelineServer");
$ldapPort = '389';
// connect to local ldap server to read
$ldapRead = ldap_connect ('localhost', $ldapPort)
or die ("Could not connect to LDAP server.");
// must manually set the version 3 protocol
@ldap_set_option ($ldapRead, LDAP_OPT_PROTOCOL_VERSION,3);
// bind to ldap server and search for assidelineserver
$ldapReadBind = @ldap_bind ($ldapRead, $dn, $ldappass);
if ($ldapReadBind) {
$searchResult = @ldap_search ($ldapRead, $dn,
'(objectClass=fmAddress)', $justthese);
if ($searchResult) {
$information = @ldap_get_entries ($ldapRead,
$searchResult);
if (isset ($information[0]["assidelineserver"][0])) {
$credentials['server'] =
$information[0]["assidelineserver"][0];
Horde::log (sprintf ('Setting preauth hook hostname
"%s" from client [%s]', $credentials['server'],
$_SERVER['REMOTE_ADDR']), 'DEBUG');
@ldap_close ($ldapRead);
return array(
'credentials' => $credentials,
'userId' => $userId
);
} else {
Horde::log (sprintf ('Unable to find hostname for
dn: %s', $dn), 'ERR');
}
} else {
Horde::log (sprintf ('Problem with search for dn: %s ,
the error was %s', $dn, ldap_error($ldapRead)), 'ERR');
}
} else {
Horde::log (sprintf ('Unable to bind to LDAP on localhost
for user: %s with dn: %s and password %s, the error was %s', $userId,
$dn, $ldappass, ldap_error ($ldapRead)), 'ERR');
}
return true;
}
}
Good luck!
--
Andy Dorman
More information about the horde
mailing list