Skip to content

Commit

Permalink
Allow to set LDAP substring filter type
Browse files Browse the repository at this point in the history
Introduce new settings for the user- and groupproviders to allow
configuring the LDAP filter type for substring search. Possible values
are: "initial", "final" and "any" to do either prefix, suffix or full
substring searches.
  • Loading branch information
rhafer committed Jul 19, 2022
1 parent 08f504f commit ec21fec
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/cfg-ldap-substring-filter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Allow to set LDAP substring filter type

We introduced new settings for the user- and groupproviders to allow
configuring the LDAP filter type for substring search. Possible values are:
"initial", "final" and "any" to do either prefix, suffix or full substring
searches.

https://github.com/cs3org/reva/pull/3087
78 changes: 62 additions & 16 deletions pkg/utils/ldap/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,25 @@ type Identity struct {
}

type userConfig struct {
BaseDN string `mapstructure:"user_base_dn"`
Scope string `mapstructure:"user_search_scope"`
scopeVal int
Filter string `mapstructure:"user_filter"`
Objectclass string `mapstructure:"user_objectclass"`
Schema userSchema `mapstructure:"user_schema"`
BaseDN string `mapstructure:"user_base_dn"`
Scope string `mapstructure:"user_search_scope"`
scopeVal int
Filter string `mapstructure:"user_filter"`
Objectclass string `mapstructure:"user_objectclass"`
Schema userSchema `mapstructure:"user_schema"`
SubstringFilterType string `mapstructure:"user_substring_filter_type"`
substringFilterVal int
}

type groupConfig struct {
BaseDN string `mapstructure:"group_base_dn"`
Scope string `mapstructure:"group_search_scope"`
scopeVal int
Filter string `mapstructure:"group_filter"`
Objectclass string `mapstructure:"group_objectclass"`
Schema groupSchema `mapstructure:"group_schema"`
BaseDN string `mapstructure:"group_base_dn"`
Scope string `mapstructure:"group_search_scope"`
scopeVal int
Filter string `mapstructure:"group_filter"`
Objectclass string `mapstructure:"group_objectclass"`
Schema groupSchema `mapstructure:"group_schema"`
SubstringFilterType string `mapstructure:"group_substring_filter_type'`
substringFilterVal int
}

type groupSchema struct {
Expand Down Expand Up @@ -99,6 +103,7 @@ var userDefaults = userConfig{
UIDNumber: "uidNumber",
GIDNumber: "gidNumber",
},
SubstringFilterType: "initial",
}

// Default groupConfig (Active Directory)
Expand All @@ -114,6 +119,7 @@ var groupDefaults = groupConfig{
GIDNumber: "gidNumber",
Member: "memberUid",
},
SubstringFilterType: "initial",
}

// New initializes the default config
Expand All @@ -136,6 +142,15 @@ func (i *Identity) Setup() error {
if i.Group.scopeVal, err = stringToScope(i.Group.Scope); err != nil {
return fmt.Errorf("error configuring group scope: %w", err)
}

if i.User.substringFilterVal, err = stringToFilterType(i.User.SubstringFilterType); err != nil {
return fmt.Errorf("error configuring user substring filter type: %w", err)
}

if i.Group.substringFilterVal, err = stringToFilterType(i.Group.SubstringFilterType); err != nil {
return fmt.Errorf("error configuring group substring filter type: %w", err)
}

return nil
}

Expand Down Expand Up @@ -475,9 +490,17 @@ func (i *Identity) getUserFindFilter(query string) string {
i.User.Schema.DisplayName,
i.User.Schema.Username,
}
var filter string
var filter, squery string
switch i.User.substringFilterVal {
case ldap.FilterSubstringsInitial:
squery = fmt.Sprintf("%s*", ldap.EscapeFilter(query))
case ldap.FilterSubstringsAny:
squery = fmt.Sprintf("*%s*", ldap.EscapeFilter(query))
case ldap.FilterSubstringsFinal:
squery = fmt.Sprintf("*%s", ldap.EscapeFilter(query))
}
for _, attr := range searchAttrs {
filter = fmt.Sprintf("%s(%s=%s*)", filter, attr, ldap.EscapeFilter(query))
filter = fmt.Sprintf("%s(%s=%s)", filter, attr, squery)
}
// substring search for UUID is not possible
filter = fmt.Sprintf("%s(%s=%s)", filter, i.User.Schema.ID, ldap.EscapeFilter(query))
Expand All @@ -497,9 +520,17 @@ func (i *Identity) getGroupFindFilter(query string) string {
i.Group.Schema.DisplayName,
i.Group.Schema.Groupname,
}
var filter string
var filter, squery string
switch i.Group.substringFilterVal {
case ldap.FilterSubstringsInitial:
squery = fmt.Sprintf("%s*", ldap.EscapeFilter(query))
case ldap.FilterSubstringsAny:
squery = fmt.Sprintf("*%s*", ldap.EscapeFilter(query))
case ldap.FilterSubstringsFinal:
squery = fmt.Sprintf("*%s", ldap.EscapeFilter(query))
}
for _, attr := range searchAttrs {
filter = fmt.Sprintf("%s(%s=%s*)", filter, attr, ldap.EscapeFilter(query))
filter = fmt.Sprintf("%s(%s=%s)", filter, attr, squery)
}
// substring search for UUID is not possible
filter = fmt.Sprintf("%s(%s=%s)", filter, i.Group.Schema.ID, ldap.EscapeFilter(query))
Expand All @@ -526,6 +557,21 @@ func stringToScope(scope string) (int, error) {
return s, nil
}

func stringToFilterType(t string) (int, error) {
var s int
switch t {
case "initial":
s = ldap.FilterSubstringsInitial
case "any":
s = ldap.FilterSubstringsAny
case "final":
s = ldap.FilterSubstringsFinal
default:
return 0, fmt.Errorf("invalid filter type '%s'", t)
}
return s, nil
}

func (i *Identity) getGroupMemberFilter(memberName string) string {
return fmt.Sprintf("(&%s(objectclass=%s)(%s=%s))",
i.Group.Filter,
Expand Down

0 comments on commit ec21fec

Please sign in to comment.