internal/ldap: Support more LDAP filters
This commit is contained in:
parent
c4dd12c378
commit
1b2e59b9be
57
internal/ldap/bleve_mapper.go
Normal file
57
internal/ldap/bleve_mapper.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ps78674/goldap/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *server) buildBleveQuery(f message.Filter) (string, error) {
|
||||||
|
s.l.Trace("Building search expression", "filter", fmt.Sprintf("%#v", f))
|
||||||
|
var err error
|
||||||
|
var etmp string
|
||||||
|
var expr []string
|
||||||
|
switch f := f.(type) {
|
||||||
|
case message.FilterEqualityMatch:
|
||||||
|
etmp, err = mapToBleveStringQuery(string(f.AttributeDesc()), "=", string(f.AssertionValue()))
|
||||||
|
expr = append(expr, etmp)
|
||||||
|
case message.FilterOr:
|
||||||
|
for _, subf := range f {
|
||||||
|
s, err := s.buildBleveQuery(subf)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
expr = append(expr, s)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s.l.Warn("Unsupported search filter", "filter", fmt.Sprintf("%#v", f))
|
||||||
|
err = errors.New("unsupported search filter")
|
||||||
|
}
|
||||||
|
return strings.Join(expr, " "), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapToBleveStringQuery(attr, op, val string) (string, error) {
|
||||||
|
var predicate, operator string
|
||||||
|
|
||||||
|
switch attr {
|
||||||
|
case "uid":
|
||||||
|
predicate = "ID"
|
||||||
|
case "cn":
|
||||||
|
predicate = "Name"
|
||||||
|
default:
|
||||||
|
return "", errors.New("search attribute is unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch op {
|
||||||
|
case "=":
|
||||||
|
operator = ":"
|
||||||
|
val = strconv.Quote(val)
|
||||||
|
default:
|
||||||
|
return "", errors.New("search comparison is unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return predicate + operator + val, nil
|
||||||
|
}
|
|
@ -2,8 +2,6 @@ package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -35,21 +33,7 @@ func (s *server) handleSearchEntities(w ldap.ResponseWriter, m *ldap.Message) {
|
||||||
s.l.Debug("Search Entities")
|
s.l.Debug("Search Entities")
|
||||||
|
|
||||||
r := m.GetSearchRequest()
|
r := m.GetSearchRequest()
|
||||||
|
expr, err := s.buildBleveQuery(r.Filter())
|
||||||
// This switch performs stage one of mapping from an ldap
|
|
||||||
// search expression to a NetAuth search expression. The
|
|
||||||
// second phase of the mapping happens in another function.
|
|
||||||
var expr string
|
|
||||||
var err error
|
|
||||||
switch r.Filter().(type) {
|
|
||||||
case message.FilterEqualityMatch:
|
|
||||||
f := r.Filter().(message.FilterEqualityMatch)
|
|
||||||
expr, err = entitySearchExprHelper(string(f.AttributeDesc()), "=", string(f.AssertionValue()))
|
|
||||||
default:
|
|
||||||
s.l.Warn("Unsupported entity search filter", "type", fmt.Sprintf("%T", r.Filter()))
|
|
||||||
s.l.Debug("Unsupported search filter", "filter", r.FilterString())
|
|
||||||
err = errors.New("unsupported filter type")
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If err is non-nil at this point it must mean that
|
// If err is non-nil at this point it must mean that
|
||||||
// the above match didn't find a supported filter.
|
// the above match didn't find a supported filter.
|
||||||
|
@ -109,49 +93,13 @@ func (s *server) entitySearchResult(ctx context.Context, e *pb.Entity, dn messag
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// entitySearchExprHelper helps in mapping ldap search expressions to
|
|
||||||
// search expressions that NetAuth understands.
|
|
||||||
func entitySearchExprHelper(attr, op, val string) (string, error) {
|
|
||||||
var predicate, operator string
|
|
||||||
|
|
||||||
switch attr {
|
|
||||||
case "uid":
|
|
||||||
predicate = "ID"
|
|
||||||
default:
|
|
||||||
return "", errors.New("search attribute is unsupported")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch op {
|
|
||||||
case "=":
|
|
||||||
operator = ":"
|
|
||||||
val = strconv.Quote(val)
|
|
||||||
default:
|
|
||||||
return "", errors.New("search comparison is unsupported")
|
|
||||||
}
|
|
||||||
|
|
||||||
return predicate + operator + val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *server) handleSearchGroups(w ldap.ResponseWriter, m *ldap.Message) {
|
func (s *server) handleSearchGroups(w ldap.ResponseWriter, m *ldap.Message) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
s.l.Debug("Search Groups")
|
s.l.Debug("Search Groups")
|
||||||
|
|
||||||
r := m.GetSearchRequest()
|
r := m.GetSearchRequest()
|
||||||
|
|
||||||
// This switch performs stage one of mapping from an ldap
|
expr, err := s.buildBleveQuery(r.Filter())
|
||||||
// search expression to a NetAuth search expression. The
|
|
||||||
// second phase of the mapping happens in another function.
|
|
||||||
var expr string
|
|
||||||
var err error
|
|
||||||
switch r.Filter().(type) {
|
|
||||||
case message.FilterEqualityMatch:
|
|
||||||
f := r.Filter().(message.FilterEqualityMatch)
|
|
||||||
expr, err = groupSearchExprHelper(string(f.AttributeDesc()), "=", string(f.AssertionValue()))
|
|
||||||
default:
|
|
||||||
s.l.Warn("Unsupported group search filter", "type", fmt.Sprintf("%T", r.Filter()))
|
|
||||||
s.l.Debug("Unsupported search filter", "filter", r.FilterString())
|
|
||||||
err = errors.New("unsupported filter type")
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If err is non-nil at this point it must mean that
|
// If err is non-nil at this point it must mean that
|
||||||
// the above match didn't find a supported filter.
|
// the above match didn't find a supported filter.
|
||||||
|
@ -208,26 +156,3 @@ func (s *server) groupSearchResult(ctx context.Context, g *pb.Group, dn message.
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// groupSearchExprHelper helps in mapping ldap search expressions to
|
|
||||||
// search expressions that NetAuth understands.
|
|
||||||
func groupSearchExprHelper(attr, op, val string) (string, error) {
|
|
||||||
var predicate, operator string
|
|
||||||
|
|
||||||
switch attr {
|
|
||||||
case "cn":
|
|
||||||
predicate = "Name"
|
|
||||||
default:
|
|
||||||
return "", errors.New("search attribute is unsupported")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch op {
|
|
||||||
case "=":
|
|
||||||
operator = ":"
|
|
||||||
val = strconv.Quote(val)
|
|
||||||
default:
|
|
||||||
return "", errors.New("search comparison is unsupported")
|
|
||||||
}
|
|
||||||
|
|
||||||
return predicate + operator + val, nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue