+=head1 NAME
+
+C4::Auth - Authenticates Koha users
+
+=head1 SYNOPSIS
+
+ use C4::Auth_with_ldap;
+
+=head1 LDAP Configuration
+
+ This module is specific to LDAP authentification. It requires Net::LDAP package and one or more
+ working LDAP servers.
+ To use it :
+ * Modify ldapserver element in KOHA_CONF
+ * Establish field mapping in <mapping> element.
+
+ For example, if your user records are stored according to the inetOrgPerson schema, RFC#2798,
+ the username would match the "uid" field, and the password should match the "userpassword" field.
+
+ Make sure that ALL required fields are populated by your LDAP database (and mapped in KOHA_CONF).
+ What are the required fields? Well, in mysql you can check the database table "borrowers" like this:
+
+ mysql> show COLUMNS from borrowers;
+ +---------------------+--------------+------+-----+---------+----------------+
+ | Field | Type | Null | Key | Default | Extra |
+ +---------------------+--------------+------+-----+---------+----------------+
+ | borrowernumber | int(11) | NO | PRI | NULL | auto_increment |
+ | cardnumber | varchar(16) | YES | UNI | NULL | |
+ | surname | mediumtext | NO | | NULL | |
+ | firstname | text | YES | | NULL | |
+ | title | mediumtext | YES | | NULL | |
+ | othernames | mediumtext | YES | | NULL | |
+ | initials | text | YES | | NULL | |
+ | streetnumber | varchar(10) | YES | | NULL | |
+ | streettype | varchar(50) | YES | | NULL | |
+ | address | mediumtext | NO | | NULL | |
+ | address2 | text | YES | | NULL | |
+ | city | mediumtext | NO | | NULL | |
+ | state | mediumtext | YES | | NULL | |
+ | zipcode | varchar(25) | YES | | NULL | |
+ | country | text | YES | | NULL | |
+ | email | mediumtext | YES | | NULL | |
+ | phone | text | YES | | NULL | |
+ | mobile | varchar(50) | YES | | NULL | |
+ | fax | mediumtext | YES | | NULL | |
+ | emailpro | text | YES | | NULL | |
+ | phonepro | text | YES | | NULL | |
+ | B_streetnumber | varchar(10) | YES | | NULL | |
+ | B_streettype | varchar(50) | YES | | NULL | |
+ | B_address | varchar(100) | YES | | NULL | |
+ | B_address2 | text | YES | | NULL | |
+ | B_city | mediumtext | YES | | NULL | |
+ | B_state | mediumtext | YES | | NULL | |
+ | B_zipcode | varchar(25) | YES | | NULL | |
+ | B_country | text | YES | | NULL | |
+ | B_email | text | YES | | NULL | |
+ | B_phone | mediumtext | YES | | NULL | |
+ | dateofbirth | date | YES | | NULL | |
+ | branchcode | varchar(10) | NO | MUL | | |
+ | categorycode | varchar(10) | NO | MUL | | |
+ | dateenrolled | date | YES | | NULL | |
+ | dateexpiry | date | YES | | NULL | |
+ | gonenoaddress | tinyint(1) | YES | | NULL | |
+ | lost | tinyint(1) | YES | | NULL | |
+ | debarred | date | YES | | NULL | |
+ | debarredcomment | varchar(255) | YES | | NULL | |
+ | contactname | mediumtext | YES | | NULL | |
+ | contactfirstname | text | YES | | NULL | |
+ | contacttitle | text | YES | | NULL | |
+ | guarantorid | int(11) | YES | MUL | NULL | |
+ | borrowernotes | mediumtext | YES | | NULL | |
+ | relationship | varchar(100) | YES | | NULL | |
+ | ethnicity | varchar(50) | YES | | NULL | |
+ | ethnotes | varchar(255) | YES | | NULL | |
+ | sex | varchar(1) | YES | | NULL | |
+ | password | varchar(30) | YES | | NULL | |
+ | flags | int(11) | YES | | NULL | |
+ | userid | varchar(30) | YES | MUL | NULL | |
+ | opacnote | mediumtext | YES | | NULL | |
+ | contactnote | varchar(255) | YES | | NULL | |
+ | sort1 | varchar(80) | YES | | NULL | |
+ | sort2 | varchar(80) | YES | | NULL | |
+ | altcontactfirstname | varchar(255) | YES | | NULL | |
+ | altcontactsurname | varchar(255) | YES | | NULL | |
+ | altcontactaddress1 | varchar(255) | YES | | NULL | |
+ | altcontactaddress2 | varchar(255) | YES | | NULL | |
+ | altcontactaddress3 | varchar(255) | YES | | NULL | |
+ | altcontactstate | mediumtext | YES | | NULL | |
+ | altcontactzipcode | varchar(50) | YES | | NULL | |
+ | altcontactcountry | text | YES | | NULL | |
+ | altcontactphone | varchar(50) | YES | | NULL | |
+ | smsalertnumber | varchar(50) | YES | | NULL | |
+ | privacy | int(11) | NO | | 1 | |
+ +---------------------+--------------+------+-----+---------+----------------+
+ 66 rows in set (0.00 sec)
+ Where Null="NO", the field is required.
+
+=head1 KOHA_CONF and field mapping
+
+Example XML stanza for LDAP configuration in KOHA_CONF.
+
+ <config>
+ ...
+ <useldapserver>1</useldapserver>
+ <!-- LDAP SERVER (optional) -->
+ <ldapserver id="ldapserver">
+ <hostname>localhost</hostname>
+ <base>dc=metavore,dc=com</base>
+ <user>cn=Manager,dc=metavore,dc=com</user> <!-- DN, if not anonymous -->
+ <pass>metavore</pass> <!-- password, if not anonymous -->
+ <replicate>1</replicate> <!-- add new users from LDAP to Koha database -->
+ <update>1</update> <!-- update existing users in Koha database -->
+ <auth_by_bind>0</auth_by_bind> <!-- set to 1 to authenticate by binding instead of
+ password comparison, e.g., to use Active Directory -->
+ <principal_name>%s@my_domain.com</principal_name>
+ <!-- optional, for auth_by_bind: a printf format to make userPrincipalName from koha userid -->
+ <mapping> <!-- match koha SQL field names to your LDAP record field names -->
+ <firstname is="givenname" ></firstname>
+ <surname is="sn" ></surname>
+ <address is="postaladdress" ></address>
+ <city is="l" >Athens, OH</city>
+ <zipcode is="postalcode" ></zipcode>
+ <branchcode is="branch" >MAIN</branchcode>
+ <userid is="uid" ></userid>
+ <password is="userpassword" ></password>
+ <email is="mail" ></email>
+ <categorycode is="employeetype" >PT</categorycode>
+ <phone is="telephonenumber"></phone>
+ </mapping>
+ </ldapserver>
+ </config>
+
+The <mapping> subelements establish the relationship between mysql fields and LDAP attributes. The element name
+is the column in mysql, with the "is" characteristic set to the LDAP attribute name. Optionally, any content
+between the element tags is taken as the default value. In this example, the default categorycode is "PT" (for
+patron).
+
+=head1 CONFIGURATION
+
+Once a user has been accepted by the LDAP server, there are several possibilities for how Koha will behave, depending on
+your configuration and the presence of a matching Koha user in your local DB:
+
+ LOCAL_USER
+ OPTION UPDATE REPLICATE EXISTS? RESULT
+ A1 1 1 1 OK : We're updating them anyway.
+ A2 1 1 0 OK : We're adding them anyway.
+ B1 1 0 1 OK : We update them.
+ B2 1 0 0 FAIL: We cannot add new user.
+ C1 0 1 1 OK : We do nothing. (maybe should update password?)
+ C2 0 1 0 OK : We add the new user.
+ D1 0 0 1 OK : We do nothing. (maybe should update password?)
+ D2 0 0 0 FAIL: We cannot add new user.
+
+Note: failure here just means that Koha will fallback to checking the local DB. That is, a given user could login with
+their LDAP password OR their local one. If this is a problem, then you should enable update and supply a mapping for
+password. Then the local value will be updated at successful LDAP login and the passwords will be synced.
+
+If you choose NOT to update local users, the borrowers table will not be affected at all.
+Note that this means that patron passwords may appear to change if LDAP is ever disabled, because
+the local table never contained the LDAP values.
+
+=head2 auth_by_bind
+
+Binds as the user instead of retrieving their record. Recommended if update disabled.
+
+=head2 principal_name
+
+Provides an optional sprintf-style format for manipulating the userid before the bind.
+Even though the userPrincipalName is one intended target, any uniquely identifying
+attribute that the server allows to be used for binding could be used.
+
+Currently, principal_name only operates when auth_by_bind is enabled.
+
+=head2 Active Directory
+
+The auth_by_bind and principal_name settings are recommended for Active Directory.
+
+Under default Active Directory rules, we cannot determine the distinguishedName attribute from the Koha userid as reliably as
+we would typically under openldap. Instead of:
+
+ distinguishedName: CN=barnes.7,DC=my_company,DC=com
+
+We might get:
+
+ distinguishedName: CN=Barnes\, Jim,OU=Test Accounts,OU=User Accounts,DC=my_company,DC=com
+
+Matching that would require us to know more info about the account (firstname, surname) and to include punctuation and whitespace
+in Koha userids. But the userPrincipalName should be consistent, something like:
+
+ userPrincipalName: barnes.7@my_company.com
+
+Therefore it is often easier to bind to Active Directory with userPrincipalName, effectively the
+canonical email address for that user, or what it would be if email were enabled for them. If Koha userid values
+will match the username portion of the userPrincipalName, and the domain suffix is the same for all users, then use principal_name
+like this:
+ <principal_name>%s@core.my_company.com</principal_name>
+
+The user of the previous example, barnes.7, would then attempt to bind as:
+ barnes.7@core.my_company.com