2021-08-05 04:17:07 +00:00
package authentication
import (
"strings"
"github.com/go-ldap/ldap/v3"
2021-09-17 09:53:59 +00:00
"github.com/authelia/authelia/v4/internal/configuration/schema"
2021-08-05 04:17:07 +00:00
)
2021-09-17 09:53:59 +00:00
// StartupCheck implements the startup check provider interface.
2021-11-23 09:45:38 +00:00
func ( p * LDAPUserProvider ) StartupCheck ( ) ( err error ) {
2021-08-05 04:17:07 +00:00
conn , err := p . connect ( p . configuration . User , p . configuration . Password )
if err != nil {
return err
}
defer conn . Close ( )
searchRequest := ldap . NewSearchRequest ( "" , ldap . ScopeBaseObject , ldap . NeverDerefAliases ,
1 , 0 , false , "(objectClass=*)" , [ ] string { ldapSupportedExtensionAttribute } , nil )
sr , err := conn . Search ( searchRequest )
if err != nil {
return err
}
if len ( sr . Entries ) != 1 {
return nil
}
// Iterate the attribute values to see what the server supports.
for _ , attr := range sr . Entries [ 0 ] . Attributes {
if attr . Name == ldapSupportedExtensionAttribute {
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "LDAP Supported Extension OIDs: %s" , strings . Join ( attr . Values , ", " ) )
2021-08-05 04:17:07 +00:00
for _ , oid := range attr . Values {
if oid == ldapOIDPasswdModifyExtension {
p . supportExtensionPasswdModify = true
break
}
}
break
}
}
2021-09-17 09:53:59 +00:00
if ! p . supportExtensionPasswdModify && ! p . disableResetPassword &&
p . configuration . Implementation != schema . LDAPImplementationActiveDirectory {
2021-11-23 09:45:38 +00:00
p . log . Warn ( "Your LDAP server implementation may not support a method for password hashing " +
2021-09-17 09:53:59 +00:00
"known to Authelia, it's strongly recommended you ensure your directory server hashes the password " +
"attribute when users reset their password via Authelia." )
}
2021-08-05 04:17:07 +00:00
return nil
}
func ( p * LDAPUserProvider ) parseDynamicUsersConfiguration ( ) {
p . configuration . UsersFilter = strings . ReplaceAll ( p . configuration . UsersFilter , "{username_attribute}" , p . configuration . UsernameAttribute )
p . configuration . UsersFilter = strings . ReplaceAll ( p . configuration . UsersFilter , "{mail_attribute}" , p . configuration . MailAttribute )
p . configuration . UsersFilter = strings . ReplaceAll ( p . configuration . UsersFilter , "{display_name_attribute}" , p . configuration . DisplayNameAttribute )
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "Dynamically generated users filter is %s" , p . configuration . UsersFilter )
2021-08-05 04:17:07 +00:00
p . usersAttributes = [ ] string {
p . configuration . DisplayNameAttribute ,
p . configuration . MailAttribute ,
p . configuration . UsernameAttribute ,
}
if p . configuration . AdditionalUsersDN != "" {
p . usersBaseDN = p . configuration . AdditionalUsersDN + "," + p . configuration . BaseDN
} else {
p . usersBaseDN = p . configuration . BaseDN
}
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "Dynamically generated users BaseDN is %s" , p . usersBaseDN )
2021-08-05 04:17:07 +00:00
if strings . Contains ( p . configuration . UsersFilter , ldapPlaceholderInput ) {
p . usersFilterReplacementInput = true
}
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "Detected user filter replacements that need to be resolved per lookup are: %s=%v" ,
2021-08-05 04:17:07 +00:00
ldapPlaceholderInput , p . usersFilterReplacementInput )
}
func ( p * LDAPUserProvider ) parseDynamicGroupsConfiguration ( ) {
p . groupsAttributes = [ ] string {
p . configuration . GroupNameAttribute ,
}
if p . configuration . AdditionalGroupsDN != "" {
p . groupsBaseDN = ldap . EscapeFilter ( p . configuration . AdditionalGroupsDN + "," + p . configuration . BaseDN )
} else {
p . groupsBaseDN = p . configuration . BaseDN
}
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "Dynamically generated groups BaseDN is %s" , p . groupsBaseDN )
2021-08-05 04:17:07 +00:00
if strings . Contains ( p . configuration . GroupsFilter , ldapPlaceholderInput ) {
p . groupsFilterReplacementInput = true
}
if strings . Contains ( p . configuration . GroupsFilter , ldapPlaceholderUsername ) {
p . groupsFilterReplacementUsername = true
}
if strings . Contains ( p . configuration . GroupsFilter , ldapPlaceholderDistinguishedName ) {
p . groupsFilterReplacementDN = true
}
2021-11-23 09:45:38 +00:00
p . log . Tracef ( "Detected group filter replacements that need to be resolved per lookup are: input=%v, username=%v, dn=%v" , p . groupsFilterReplacementInput , p . groupsFilterReplacementUsername , p . groupsFilterReplacementDN )
2021-08-05 04:17:07 +00:00
}