outposts/ldap: Rework/improve LDAP search logic. (#1687)

* outposts/ldap: Refactor searching so we key primarily off base dn

* docs: Updating guides on sssd and the ldap outpost.
This commit is contained in:
Ilya Kogan
2021-12-02 09:28:58 -05:00
committed by GitHub
parent fdd5211253
commit 40404ff41d
13 changed files with 597 additions and 219 deletions

View File

@ -2,14 +2,20 @@ package ldap
import (
"crypto/tls"
"fmt"
"strings"
"sync"
"github.com/go-openapi/strfmt"
"github.com/nmcclain/ldap"
log "github.com/sirupsen/logrus"
"goauthentik.io/api"
"goauthentik.io/internal/constants"
"goauthentik.io/internal/outpost/ldap/bind"
ldapConstants "goauthentik.io/internal/outpost/ldap/constants"
"goauthentik.io/internal/outpost/ldap/flags"
"goauthentik.io/internal/outpost/ldap/search"
"goauthentik.io/internal/outpost/ldap/utils"
)
type ProviderInstance struct {
@ -50,6 +56,10 @@ func (pi *ProviderInstance) GetBaseGroupDN() string {
return pi.GroupDN
}
func (pi *ProviderInstance) GetBaseVirtualGroupDN() string {
return pi.VirtualGroupDN
}
func (pi *ProviderInstance) GetBaseUserDN() string {
return pi.UserDN
}
@ -82,3 +92,77 @@ func (pi *ProviderInstance) GetFlowSlug() string {
func (pi *ProviderInstance) GetSearchAllowedGroups() []*strfmt.UUID {
return pi.searchAllowedGroups
}
func (pi *ProviderInstance) GetBaseEntry() *ldap.Entry {
return &ldap.Entry{
DN: pi.GetBaseDN(),
Attributes: []*ldap.EntryAttribute{
{
Name: "distinguishedName",
Values: []string{pi.GetBaseDN()},
},
{
Name: "objectClass",
Values: []string{ldapConstants.OCTop, ldapConstants.OCDomain},
},
{
Name: "supportedLDAPVersion",
Values: []string{"3"},
},
{
Name: "namingContexts",
Values: []string{
pi.GetBaseDN(),
pi.GetBaseUserDN(),
pi.GetBaseGroupDN(),
pi.GetBaseVirtualGroupDN(),
},
},
{
Name: "vendorName",
Values: []string{"goauthentik.io"},
},
{
Name: "vendorVersion",
Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s (build %s)", constants.VERSION, constants.BUILD())},
},
},
}
}
func (pi *ProviderInstance) GetNeededObjects(scope int, baseDN string, filterOC string) (bool, bool) {
needUsers := false
needGroups := false
// We only want to load users/groups if we're actually going to be asked
// for at least one user or group based on the search's base DN and scope.
//
// If our requested base DN doesn't match any of the container DNs, then
// we're probably loading a user or group. If it does, then make sure our
// scope will eventually take us to users or groups.
if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.UserDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetUserOCs()) {
if baseDN != pi.UserDN && baseDN != pi.BaseDN ||
baseDN == pi.BaseDN && scope > 1 ||
baseDN == pi.UserDN && scope > 0 {
needUsers = true
}
}
if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.GroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetGroupOCs()) {
if baseDN != pi.GroupDN && baseDN != pi.BaseDN ||
baseDN == pi.BaseDN && scope > 1 ||
baseDN == pi.GroupDN && scope > 0 {
needGroups = true
}
}
if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.VirtualGroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetVirtualGroupOCs()) {
if baseDN != pi.VirtualGroupDN && baseDN != pi.BaseDN ||
baseDN == pi.BaseDN && scope > 1 ||
baseDN == pi.VirtualGroupDN && scope > 0 {
needUsers = true
}
}
return needUsers, needGroups
}