@ -42,10 +42,10 @@ type Source struct {
AttributesInBind bool // fetch attributes in bind context (not user)
Filter string // Query filter to validate entry
AdminFilter string // Query filter to check if user is admin
Groups Enabled bool // if the group checking is enabled
GroupEnabled bool // if the group checking is enabled
GroupDN string // Group Search Base
GroupFilter string // Group Name Filter
GroupMemberUid string // Group Attribute containing array of UserUID
GroupMemberUID string // Group Attribute containing array of UserUID
UserUID string // User Attribute listed in Group
Enabled bool // if this source is disabled
}
@ -54,7 +54,7 @@ func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
// See http://tools.ietf.org/search/rfc4515
badCharacters := "\x00()*\\"
if strings . ContainsAny ( username , badCharacters ) {
log . Trace ( "Username contains invalid query characters: %s" , username )
log . Trace ( "LDAP: Username contains invalid query characters: %s" , username )
return "" , false
}
@ -65,7 +65,7 @@ func (ls *Source) sanitizedUserDN(username string) (string, bool) {
// See http://tools.ietf.org/search/rfc4514: "special characters"
badCharacters := "\x00()*\\,='\"#+;<>"
if strings . ContainsAny ( username , badCharacters ) || strings . HasPrefix ( username , " " ) || strings . HasSuffix ( username , " " ) {
log . Trace ( "Username contains invalid query characters: %s" , username )
log . Trace ( "LDAP: Username contains invalid query characters: %s" , username )
return "" , false
}
@ -76,7 +76,7 @@ func (ls *Source) sanitizedGroupFilter(group string) (string, bool) {
// See http://tools.ietf.org/search/rfc4515
badCharacters := "\x00*\\"
if strings . ContainsAny ( group , badCharacters ) {
log . Trace ( "Group filter invalid query characters: %s" , group )
log . Trace ( "LDAP: Group filter invalid query characters: %s" , group )
return "" , false
}
@ -87,7 +87,7 @@ func (ls *Source) sanitizedGroupDN(groupDn string) (string, bool) {
// See http://tools.ietf.org/search/rfc4514: "special characters"
badCharacters := "\x00()*\\'\"#+;<>"
if strings . ContainsAny ( groupDn , badCharacters ) || strings . HasPrefix ( groupDn , " " ) || strings . HasSuffix ( groupDn , " " ) {
log . Trace ( "Group DN contains invalid query characters: %s" , groupDn )
log . Trace ( "LDAP: Group DN contains invalid query characters: %s" , groupDn )
return "" , false
}
@ -99,12 +99,12 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
if ls . BindDN != "" && ls . BindPassword != "" {
err := l . Bind ( ls . BindDN , ls . BindPassword )
if err != nil {
log . Trace ( "Failed to bind as BindDN '%s': %v" , ls . BindDN , err )
log . Trace ( "LDAP: Failed to bind as BindDN '%s': %v" , ls . BindDN , err )
return "" , false
}
log . Trace ( "Bound as BindDN: %s" , ls . BindDN )
log . Trace ( "LDAP: Bound as BindDN: %s" , ls . BindDN )
} else {
log . Trace ( "Proceeding with anonymous LDAP search" )
log . Trace ( "LDAP: Proceeding with anonymous LDAP search" )
}
// A search for the user.
@ -113,7 +113,7 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
return "" , false
}
log . Trace ( "Searching for DN using filter '%s' and base '%s'" , userFilter , ls . UserBase )
log . Trace ( "LDAP: Searching for DN using filter '%s' and base '%s'" , userFilter , ls . UserBase )
search := ldap . NewSearchRequest (
ls . UserBase , ldap . ScopeWholeSubtree , ldap . NeverDerefAliases , 0 , 0 ,
false , userFilter , [ ] string { } , nil )
@ -121,16 +121,16 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
// Ensure we found a user
sr , err := l . Search ( search )
if err != nil || len ( sr . Entries ) < 1 {
log . Trace ( "Failed search using filter '%s': %v" , userFilter , err )
log . Trace ( "LDAP: Failed search using filter '%s': %v" , userFilter , err )
return "" , false
} else if len ( sr . Entries ) > 1 {
log . Trace ( "Filter '%s' returned more than one user" , userFilter )
log . Trace ( "LDAP: Filter '%s' returned more than one user" , userFilter )
return "" , false
}
userDN := sr . Entries [ 0 ] . DN
if userDN == "" {
log . Error ( 4 , "LDAP s earch was successful, but found no DN!")
log . Error ( 2 , "LDAP: S earch was successful, but found no DN!")
return "" , false
}
@ -138,7 +138,7 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
}
func dial ( ls * Source ) ( * ldap . Conn , error ) {
log . Trace ( "Dialing LDAP with security protocol '%v' without verifying: %v" , ls . SecurityProtocol , ls . SkipVerify )
log . Trace ( "LDAP: Dialing with security protocol '%v' without verifying: %v" , ls . SecurityProtocol , ls . SkipVerify )
tlsCfg := & tls . Config {
ServerName : ls . Host ,
@ -183,7 +183,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
}
l , err := dial ( ls )
if err != nil {
log . Error ( 4 , "LDAP connect failed for '%s': %v" , ls . Host , err )
log . Error ( 2 , "LDAP connect failed for '%s': %v" , ls . Host , err )
ls . Enabled = false
return "" , "" , "" , "" , false , false
}
@ -221,7 +221,8 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
return "" , "" , "" , "" , false , false
}
log . Trace ( "Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter '%s' and base '%s'" , ls . AttributeUsername , ls . AttributeName , ls . AttributeSurname , ls . AttributeMail , ls . UserUID , userFilter , userDN )
log . Trace ( "Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter '%s' and base '%s'" ,
ls . AttributeUsername , ls . AttributeName , ls . AttributeSurname , ls . AttributeMail , ls . UserUID , userFilter , userDN )
search := ldap . NewSearchRequest (
userDN , ldap . ScopeWholeSubtree , ldap . NeverDerefAliases , 0 , 0 , false , userFilter ,
[ ] string { ls . AttributeUsername , ls . AttributeName , ls . AttributeSurname , ls . AttributeMail , ls . UserUID } ,
@ -229,13 +230,13 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
sr , err := l . Search ( search )
if err != nil {
log . Error ( 4 , "LDAP u ser search failed: %v", err )
log . Error ( 2 , "LDAP: U ser search failed: %v", err )
return "" , "" , "" , "" , false , false
} else if len ( sr . Entries ) < 1 {
if directBind {
log . Error ( 4 , " User filter inhibited user login")
log . Trace ( "LDAP: User filter inhibited user login")
} else {
log . Error ( 4 , "LDAP search failed: 0 entries")
log . Trace ( "LDAP: User search failed: 0 entries")
}
return "" , "" , "" , "" , false , false
@ -248,7 +249,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
uid := sr . Entries [ 0 ] . GetAttributeValue ( ls . UserUID )
// Check group membership
if ls . Groups Enabled {
if ls . GroupEnabled {
groupFilter , ok := ls . sanitizedGroupFilter ( ls . GroupFilter )
if ! ok {
return "" , "" , "" , "" , false , false
@ -258,24 +259,24 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
return "" , "" , "" , "" , false , false
}
log . Trace ( "Fetching groups '%v' with filter '%s' and base '%s'" , ls . GroupMemberUid , groupFilter , groupDN )
log . Trace ( "LDAP: Fetching groups '%v' with filter '%s' and base '%s'" , ls . GroupMemberUID , groupFilter , groupDN )
groupSearch := ldap . NewSearchRequest (
groupDN , ldap . ScopeWholeSubtree , ldap . NeverDerefAliases , 0 , 0 , false , groupFilter ,
[ ] string { ls . GroupMemberUid } ,
[ ] string { ls . GroupMemberUID } ,
nil )
srg , err := l . Search ( groupSearch )
if err != nil {
log . Error ( 4 , "LDAP g roup search failed: %v", err )
log . Error ( 2 , "LDAP: G roup search failed: %v", err )
return "" , "" , "" , "" , false , false
} else if len ( sr . Entries ) < 1 {
log . Error ( 4 , "LDAP g roup search failed: 0 entries")
log . Error ( 2 , "LDAP: G roup search failed: 0 entries")
return "" , "" , "" , "" , false , false
}
isMember := false
for _ , group := range srg . Entries {
for _ , member := range group . GetAttributeValues ( ls . GroupMemberUid ) {
for _ , group := range srg . Entries {
for _ , member := range group . GetAttributeValues ( ls . GroupMemberUID ) {
if member == uid {
isMember = true
}
@ -283,7 +284,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
}
if ! isMember {
log . Error ( 4 , "LDAP group membership test failed" )
log . Trace ( "LDAP: Group membership test failed [username: %s, group_member_uid: %s, user_uid: %s" , username , ls . GroupMemberUID , uid )
return "" , "" , "" , "" , false , false
}
}
@ -298,9 +299,9 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
sr , err = l . Search ( search )
if err != nil {
log . Error ( 4 , "LDAP a dmin search failed: %v", err )
log . Error ( 2 , "LDAP: A dmin search failed: %v", err )
} else if len ( sr . Entries ) < 1 {
log . Error ( 4 , "LDAP a dmin search failed: 0 entries")
log . Error ( 2 , "LDAP: A dmin search failed: 0 entries")
} else {
isAdmin = true
}