From 7f8d1e44eeba4156c0a258b6a1af47cb0a7e2d80 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 21 Jul 2021 00:27:43 +0800 Subject: strings in LDAP are case-insensitive (#8) Thank you @wxiaoguang ! * strings in LDAP are case-insensitive * optmize routeFunc (faster, case-insensitive) * small optimiztion to routeFunc * request the directory server to return operational attributes by adding + (the plus sign) in your ldapsearch command. * request the directory server to return operational attributes by adding + (the plus sign) in your ldapsearch command. * request the directory server to return operational attributes by adding + (the plus sign) in your ldapsearch command. * remove operational attributes --- server_search.go | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) (limited to 'server_search.go') diff --git a/server_search.go b/server_search.go index b4f7a5f..12a6caf 100644 --- a/server_search.go +++ b/server_search.go @@ -46,6 +46,7 @@ func HandleSearchRequest(req *ber.Packet, controls *[]Control, messageID uint64, } i := 0 + searchReqBaseDNLower := strings.ToLower(searchReq.BaseDN) for _, entry := range searchResp.Entries { if server.EnforceLDAP { // filter @@ -61,25 +62,24 @@ func HandleSearchRequest(req *ber.Packet, controls *[]Control, messageID uint64, switch searchReq.Scope { case ScopeWholeSubtree: // The scope is constrained to the entry named by baseObject and to all its subordinates. case ScopeBaseObject: // The scope is constrained to the entry named by baseObject. - if entry.DN != searchReq.BaseDN { + if strings.ToLower(entry.DN) != searchReqBaseDNLower { continue } case ScopeSingleLevel: // The scope is constrained to the immediate subordinates of the entry named by baseObject. - parts := strings.Split(entry.DN, ",") - if len(parts) < 2 && entry.DN != searchReq.BaseDN { + entryDNLower := strings.ToLower(entry.DN) + parts := strings.Split(entryDNLower, ",") + if len(parts) < 2 && entryDNLower != searchReqBaseDNLower { continue } - if dn := strings.Join(parts[1:], ","); dn != searchReq.BaseDN { + if dnSuffix := strings.Join(parts[1:], ","); dnSuffix != searchReqBaseDNLower { continue } } - // attributes - if len(searchReq.Attributes) > 1 || (len(searchReq.Attributes) == 1 && len(searchReq.Attributes[0]) > 0) { - entry, err = filterAttributes(entry, searchReq.Attributes) - if err != nil { - return NewError(LDAPResultOperationsError, err) - } + // filter attributes + entry, err = filterAttributes(entry, searchReq.Attributes) + if err != nil { + return NewError(LDAPResultOperationsError, err) } // size limit @@ -160,9 +160,30 @@ func filterAttributes(entry *Entry, attributes []string) (*Entry, error) { // only return requested attributes newAttributes := []*EntryAttribute{} - for _, attr := range entry.Attributes { - for _, requested := range attributes { - if requested == "*" || strings.ToLower(attr.Name) == strings.ToLower(requested) { + if len(attributes) > 1 || (len(attributes) == 1 && len(attributes[0]) > 0) { + for _, attr := range entry.Attributes { + attrNameLower := strings.ToLower(attr.Name) + for _, requested := range attributes { + requestedLower := strings.ToLower(requested) + // You can request the directory server to return operational attributes by adding + (the plus sign) in your ldapsearch command. + // "+supportedControl" is treated as an operational attribute + if strings.HasPrefix(attrNameLower, "+") { + if requestedLower == "+" || attrNameLower == "+"+requestedLower { + newAttributes = append(newAttributes, &EntryAttribute{attr.Name[1:], attr.Values}) + break + } + } else { + if requested == "*" || attrNameLower == requestedLower { + newAttributes = append(newAttributes, attr) + break + } + } + } + } + } else { + // remove operational attributes + for _, attr := range entry.Attributes { + if !strings.HasPrefix(attr.Name, "+") { newAttributes = append(newAttributes, attr) } } -- cgit v1.2.3