|
@@ -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
|
|
|
- GroupsEnabled 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 search was successful, but found no DN!")
|
|
|
+ log.Error(2, "LDAP: Search 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 user search failed: %v", err)
|
|
|
+ log.Error(2, "LDAP: User 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.GroupsEnabled {
|
|
|
+ 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 group search failed: %v", err)
|
|
|
+ log.Error(2, "LDAP: Group search failed: %v", err)
|
|
|
return "", "", "", "", false, false
|
|
|
} else if len(sr.Entries) < 1 {
|
|
|
- log.Error(4, "LDAP group search failed: 0 entries")
|
|
|
+ log.Error(2, "LDAP: Group 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 admin search failed: %v", err)
|
|
|
+ log.Error(2, "LDAP: Admin search failed: %v", err)
|
|
|
} else if len(sr.Entries) < 1 {
|
|
|
- log.Error(4, "LDAP admin search failed: 0 entries")
|
|
|
+ log.Error(2, "LDAP: Admin search failed: 0 entries")
|
|
|
} else {
|
|
|
isAdmin = true
|
|
|
}
|