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 ) {
2022-05-02 01:51:38 +00:00
var (
conn LDAPConnection
searchResult * ldap . SearchResult
)
if conn , err = p . connect ( ) ; err != nil {
2021-08-05 04:17:07 +00:00
return err
}
defer conn . Close ( )
searchRequest := ldap . NewSearchRequest ( "" , ldap . ScopeBaseObject , ldap . NeverDerefAliases ,
1 , 0 , false , "(objectClass=*)" , [ ] string { ldapSupportedExtensionAttribute } , nil )
2022-05-02 01:51:38 +00:00
if searchResult , err = conn . Search ( searchRequest ) ; err != nil {
2021-08-05 04:17:07 +00:00
return err
}
2022-05-02 01:51:38 +00:00
if len ( searchResult . Entries ) != 1 {
2021-08-05 04:17:07 +00:00
return nil
}
// Iterate the attribute values to see what the server supports.
2022-05-02 01:51:38 +00:00
for _ , attr := range searchResult . Entries [ 0 ] . Attributes {
2021-08-05 04:17:07 +00:00
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
}
}
}
}
2021-09-17 09:53:59 +00:00
if ! p . supportExtensionPasswdModify && ! p . disableResetPassword &&
2022-05-02 01:51:38 +00:00
p . config . 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 ( ) {
2022-05-02 01:51:38 +00:00
p . config . UsersFilter = strings . ReplaceAll ( p . config . UsersFilter , "{username_attribute}" , p . config . UsernameAttribute )
p . config . UsersFilter = strings . ReplaceAll ( p . config . UsersFilter , "{mail_attribute}" , p . config . MailAttribute )
p . config . UsersFilter = strings . ReplaceAll ( p . config . UsersFilter , "{display_name_attribute}" , p . config . DisplayNameAttribute )
2021-08-05 04:17:07 +00:00
2022-05-02 01:51:38 +00:00
p . log . Tracef ( "Dynamically generated users filter is %s" , p . config . UsersFilter )
2021-08-05 04:17:07 +00:00
p . usersAttributes = [ ] string {
2022-05-02 01:51:38 +00:00
p . config . DisplayNameAttribute ,
p . config . MailAttribute ,
p . config . UsernameAttribute ,
2021-08-05 04:17:07 +00:00
}
2022-05-02 01:51:38 +00:00
if p . config . AdditionalUsersDN != "" {
p . usersBaseDN = p . config . AdditionalUsersDN + "," + p . config . BaseDN
2021-08-05 04:17:07 +00:00
} else {
2022-05-02 01:51:38 +00:00
p . usersBaseDN = p . config . BaseDN
2021-08-05 04:17:07 +00:00
}
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
2022-05-02 01:51:38 +00:00
if strings . Contains ( p . config . UsersFilter , ldapPlaceholderInput ) {
2021-08-05 04:17:07 +00:00
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 {
2022-05-02 01:51:38 +00:00
p . config . GroupNameAttribute ,
2021-08-05 04:17:07 +00:00
}
2022-05-02 01:51:38 +00:00
if p . config . AdditionalGroupsDN != "" {
p . groupsBaseDN = ldap . EscapeFilter ( p . config . AdditionalGroupsDN + "," + p . config . BaseDN )
2021-08-05 04:17:07 +00:00
} else {
2022-05-02 01:51:38 +00:00
p . groupsBaseDN = p . config . BaseDN
2021-08-05 04:17:07 +00:00
}
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
2022-05-02 01:51:38 +00:00
if strings . Contains ( p . config . GroupsFilter , ldapPlaceholderInput ) {
2021-08-05 04:17:07 +00:00
p . groupsFilterReplacementInput = true
}
2022-05-02 01:51:38 +00:00
if strings . Contains ( p . config . GroupsFilter , ldapPlaceholderUsername ) {
2021-08-05 04:17:07 +00:00
p . groupsFilterReplacementUsername = true
}
2022-05-02 01:51:38 +00:00
if strings . Contains ( p . config . GroupsFilter , ldapPlaceholderDistinguishedName ) {
2021-08-05 04:17:07 +00:00
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
}