If you're looking for some help with LDAP, here are some error messages to look for and what they mean:
Quick super hint: You need to set up at least one admin account that's not root@localhost to get started with ldap. If you "forget", there's an easy way to get that user setup after LDAP is set up:
Code: Select all
bin/otrs.AddUser.pl -f firstname -l lastname -p password -g admin -e user@example.com username
Look at your logs (otrs.log or var/log/messages or Admin System Log). There is important information that the following won't make sense unless you see these logs.
ERRORS
Can't locate Net/LDAP.pm in @INC
This means it isn't installed. You did run otrs.CheckModules, right?
Code: Select all
cpan Net::LDAP
Code: Select all
ppm install Net::LDAP
http://wiki.servicenow.com/index.php?ti ... rror_Codes
first bind failed
Almost always SearchUser credentials, password. Invalid syntax means poorly formatted dn/distinguished name. 52e is password/credentials. If you doubt this, then it's related to the ldap host not accepting/validating the credentials. This could be for several different reasons, but it is not something OTRS can fix.
See this thread for discussion
Note that Active Directory by default needs a SearchUser and SearchPw for every bind. (A bind is simply the authority/permission to perform a search). The user to perform an LDAP lookup should not be a domain admin. It should be a basic user.
First bind failed! Bad file descriptor
This is because IPv6 is being attempted. The best way to get around this is to add the following to your Params (changed because it makes more sense):
Code: Select all
inet4 => 1,
Code: Select all
inet6 => 0,
This means you've successfully queried (logged in to query) the LDAP server, but the request doesn't return a result. Usually, this means you're trying to ask for a username in the wrong field or basedn.
You'll see Filter='(Param1=Param2Param3)'
Param1 is uid or the value of UserAttr
Param2 is the submitted username/login entry
Param3 is the UserSuffix, if provided
If you have an additional filter, it may show up as
Filter='(&(Param1=Param2Param3)(Param4))'
In which Param4 will be your filter parameters.
SETUP
First thing: Read the docs. Make changes in Kernel/Config.pm. Do not touch Defaults.pm (but read the file!)
3.1: http://otrs.github.io/doc/manual/admin/ ... ckend-ldap
3.1: http://otrs.github.io/doc/manual/admin/ ... ckend-ldap
3.1: http://otrs.github.io/doc/manual/admin/ ... ckend-ldap
Agents, and agents *only* sync with the database. if the AuthSyncModule is enabled. (Don't forget UseSyncBackend) There is no need for *customers* to sync to the database from LDAP. Any customer information in LDAP is available by query.
Three reasons for not customers:
- customers aren't constantly using OTRS
- the database doesn't need mass updates to query information
- AuthSync for Agents is the integrated solution for the issue where legitimate agents can authenticate on index.pl but can't be found in the database because they weren't manually set up. The membership of AuthSync *is* the list of allowed agents from LDAP.
$Self->{'Customer::AuthModule'} (Customer::AuthModule::LDAP, etc) is for Customer authentication (permission) (customer.pl)
$Self->{CustomerUser} is for Data (information)
$Self->{AuthModule} is for Agent (User) authentication (index.pl)
$Self->{'AuthSyncModule'} is for Agent (User) Data -- information, but mostly frontend (web interface) connection/allow access to OTRS. The documentation states "the LDAP directory is the last instance for authentication". It really means, "an additional instance for authentication." LDAP is checked as one of the user-configured (Config.pm) backend methods to verify the user attempting to login has a valid username/password pair. If that verify is invalid, OTRS won't allow the user to access the web interface. AuthSyncModule is interface-side (frontend), but both backend and frontend must succeed in order for access.
If you want to use LDAP in addition to other backends (or multiple ldap connections), you will need to append an index value (1-9) to the Array keys of the entries in Config.pm
What that means in "I don't know what you mean" speak:
$Self->{AuthModule1} = ...
$Self->{'AuthModule::LDAP::Host1'} = ...
and so on.
The following is taken directly from 3.1.7 Defaults.pm
Code: Select all
#
# (take care that Net::LDAP is installed!)
# $Self->{AuthModule} = 'Kernel::System::Auth::LDAP';
# $Self->{'AuthModule::LDAP::Host'} = 'ldap.example.com';
# $Self->{'AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com';
# $Self->{'AuthModule::LDAP::UID'} = 'uid';
# Check if the user is allowed to auth in a posixGroup
# (e. g. user needs to be in a group xyz to use otrs)
# $Self->{'AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=example,dc=com';
# $Self->{'AuthModule::LDAP::AccessAttr'} = 'memberUid';
# for ldap posixGroups objectclass (just uid)
# $Self->{'AuthModule::LDAP::UserAttr'} = 'UID';
# for non ldap posixGroups objectclass (with full user dn)
# $Self->{'AuthModule::LDAP::UserAttr'} = 'DN';
# The following is valid but would only be necessary if the
# anonymous user do NOT have permission to read from the LDAP tree
# $Self->{'AuthModule::LDAP::SearchUserDN'} = '';
# $Self->{'AuthModule::LDAP::SearchUserPw'} = '';
# in case you want to add always one filter to each ldap query, use
# this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
# $Self->{'AuthModule::LDAP::AlwaysFilter'} = '';
# in case you want to add a suffix to each login name, then
# you can use this option. e. g. user just want to use user but
# in your ldap directory exists user@domain.
# $Self->{'AuthModule::LDAP::UserSuffix'} = '@domain.com';
# In case you want to convert all given usernames to lower letters you
# should activate this option. It might be helpfull if databases are
# in use that do not distinguish selects for upper and lower case letters
# (Oracle, postgresql). User might be synched twice, if this option
# is not in use.
# $Self->{'AuthModule::LDAP::UserLowerCase'} = 0;
# In case you need to use OTRS in iso-charset, you can define this
# by using this option (converts utf-8 data from LDAP to iso).
# $Self->{'AuthModule::LDAP::Charset'} = 'iso-8859-1';
# Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
# $Self->{'AuthModule::LDAP::Params'} = {
# port => 389,
# timeout => 120,
# async => 0,
# version => 3,
# };
# Die if backend can't work, e. g. can't connect to server.
# $Self->{'AuthModule::LDAP::Die'} = 1;
$Self->{AuthModule} = 'Kernel::System::Auth::LDAP'; #You need this line to start talking about LDAP as the method to authenticate.
$Self->{'AuthModule::LDAP::Host'} = 'ldap.example.com'; #This tells us where we're going to authenticate against
$Self->{'AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com'; #Where do we start looking? We can start lower (OU level, for instance)
$Self->{'AuthModule::LDAP::UID'} = 'uid'; #a field named uid. don't need to change this unless it doesn't exist in ldap. sAMAccountName is good to use here for Active Directory
$Self->{'AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=example,dc=com'; #directly assigned members of this group are allowed to authenticate
$Self->{'AuthModule::LDAP::AccessAttr'} = 'memberUid'; #only relevant if GroupDN is specified. This is an attribute that exists only to indicate group membership. (See also member, or memberOf for instance)
$Self->{'AuthModule::LDAP::UserAttr'} = 'UID'; #This is a unique user attribute. In Active Directory, try 'DN', or maybe userPrincipalName
$Self->{'AuthModule::LDAP::SearchUserDN'} = ''; #a distinguished name for the user who is authorized to read ldap, if necessary. Don't use a domain admin.
$Self->{'AuthModule::LDAP::SearchUserPw'} = ''; #the user's password to read ldap
$Self->{'AuthModule::LDAP::AlwaysFilter'} = ''; #Don't try to use a bunch of "not"s here. start your BaseDN as inclusive of everyone, and filter here. For instance, users only, people with email addresses. Some examples
$Self->{'AuthModule::LDAP::Params'} = { #Keep the defaults unless you must try the global catalog port, have nonstandard ldap, etc. }
...
}
$Self->{'AuthModule::LDAP::Die'} = 1; #it's not nice to kill your app, but then again, if you can't authenticate, does it really matter? Probably good for troubleshooting, maybe not so much in production.
http://wiki.otterhub.org/index.php?titl ... for_agents
Note that an OU is not a group. If all and only agents are part of an OU, set that OU as the BaseDN for agents, and ignore Group. An OU can be considered like a nested folder structure where a user is uniquely positioned. A group can be considered like a label attached to a user. A user is in exactly one OU. A user can be a member of multiple groups.
There will likely be more, but I thought this might be helpful.
Note that AuthSyncModule, CustomerUser, and CustomerAuth for LDAP use the same concepts to connect. The use of "Map" in CustomerUser may be addressed in another post.
Advanced User Hint:
If you're using the same information multiple times (like BaseDN, Host, SearchUserDN, SearchUserPw for Authentication and Information of both Customers and Agents/Users), create and set them up as variables before you start your configuration of the rest:
Code: Select all
my $BaseDN = 'dc=domain,dc=tld';
my $Host = 'ldapserver.domain.tld';
my $SearchUserDN = 'cn=ldapreader,ou=someOU,dc=domain,dc=tld';
my $SearchUserPw = 'som3$3cr3t';
#... code...
$Self->{'Customer::AuthModule::LDAP::Host'} = $Host;
$Self->{'Authmodule::LDAP::Host'} = $Host;
$Self->{'AuthSyncModule::LDAP::Host'} = $Host;
$Self->{CustomerUser} = {
#... other params (Name, Module)
Params => {
Host => $Host,
#other params ...
}
};