 ae7ea4dd11
			
		
	
	ae7ea4dd11
	
	
	
		
			
			* outposts/ldap: add tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix missing posixAccount Signed-off-by: Jens Langhammer <jens@goauthentik.io> * attempt to expand attributes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix routing without base DN Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more logging Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove our custom attribute filtering since this is done by the ldap library Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add test for schema Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
		
			
				
	
	
		
			56 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package ldap
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 
 | |
| 	"beryju.io/ldap"
 | |
| 	goldap "github.com/go-ldap/ldap/v3"
 | |
| 	"goauthentik.io/internal/outpost/ldap/constants"
 | |
| 	"goauthentik.io/internal/outpost/ldap/search"
 | |
| )
 | |
| 
 | |
| func (ls *LDAPServer) providerForRequest(req *search.Request) *ProviderInstance {
 | |
| 	parsedBaseDN, err := goldap.ParseDN(strings.ToLower(req.BaseDN))
 | |
| 	if err != nil {
 | |
| 		req.Log().WithError(err).Info("failed to parse base DN")
 | |
| 		return nil
 | |
| 	}
 | |
| 	parsedBindDN, err := goldap.ParseDN(strings.ToLower(req.BindDN))
 | |
| 	if err != nil {
 | |
| 		req.Log().WithError(err).Info("failed to parse bind DN")
 | |
| 		return nil
 | |
| 	}
 | |
| 	var selectedProvider *ProviderInstance
 | |
| 	longestMatch := 0
 | |
| 	for _, provider := range ls.providers {
 | |
| 		providerBase, _ := goldap.ParseDN(strings.ToLower(provider.BaseDN))
 | |
| 		// Try to match the provider primarily based on the search request's base DN
 | |
| 		baseDNMatches := providerBase.AncestorOf(parsedBaseDN) || providerBase.Equal(parsedBaseDN)
 | |
| 		// But also try to match the provider based on the bind DN
 | |
| 		bindDNMatches := providerBase.AncestorOf(parsedBindDN) || providerBase.Equal(parsedBindDN)
 | |
| 		if baseDNMatches || bindDNMatches {
 | |
| 			// Only select the provider if it's a more precise match than previously
 | |
| 			if len(provider.BaseDN) > longestMatch {
 | |
| 				req.Log().WithField("provider", provider.BaseDN).Trace("selecting provider for search request")
 | |
| 				selectedProvider = provider
 | |
| 				longestMatch = len(provider.BaseDN)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return selectedProvider
 | |
| }
 | |
| 
 | |
| func (ls *LDAPServer) searchRoute(req *search.Request, pi *ProviderInstance) (ldap.ServerSearchResult, error) {
 | |
| 	// Route based on the base DN
 | |
| 	if len(req.BaseDN) == 0 {
 | |
| 		req.Log().Trace("routing to base")
 | |
| 		return pi.searcher.SearchBase(req)
 | |
| 	}
 | |
| 	if strings.EqualFold(req.BaseDN, "cn=subschema") || req.FilterObjectClass == constants.OCSubSchema {
 | |
| 		req.Log().Trace("routing to subschema")
 | |
| 		return pi.searcher.SearchSubschema(req)
 | |
| 	}
 | |
| 	req.Log().Trace("routing to default")
 | |
| 	return pi.searcher.Search(req)
 | |
| }
 |