From 9485f0b8cc742fabf9d8e6561c7f1fde752c67eb Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 7 May 2021 11:46:26 +0200 Subject: [PATCH] outpost/ldap: make users and groups OU instead of CN Signed-off-by: Jens Langhammer --- authentik/outposts/models.py | 2 +- outpost/pkg/ldap/api.go | 4 ++-- outpost/pkg/ldap/bind.go | 2 ++ outpost/pkg/ldap/instance_bind.go | 8 +++++--- website/docs/outposts/ldap.md | 6 ++++-- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/authentik/outposts/models.py b/authentik/outposts/models.py index 88ee2b183..9e502ad6f 100644 --- a/authentik/outposts/models.py +++ b/authentik/outposts/models.py @@ -357,7 +357,7 @@ class Outpost(models.Model): LOGGER.warning("permission doesn't exist", perm=model_or_perm) continue user.user_permissions.add(permission.first()) - LOGGER.debug("Updated service account's permissions") + LOGGER.debug("Updated service account's permissions", perms=UserObjectPermission.objects.filter(user=user)) return user @property diff --git a/outpost/pkg/ldap/api.go b/outpost/pkg/ldap/api.go index 3b7717651..473958952 100644 --- a/outpost/pkg/ldap/api.go +++ b/outpost/pkg/ldap/api.go @@ -20,8 +20,8 @@ func (ls *LDAPServer) Refresh() error { } providers := make([]*ProviderInstance, len(outposts.Payload.Results)) for idx, provider := range outposts.Payload.Results { - userDN := strings.ToLower(fmt.Sprintf("cn=users,%s", provider.BaseDn)) - groupDN := strings.ToLower(fmt.Sprintf("cn=groups,%s", provider.BaseDn)) + userDN := strings.ToLower(fmt.Sprintf("ou=users,%s", provider.BaseDn)) + groupDN := strings.ToLower(fmt.Sprintf("ou=groups,%s", provider.BaseDn)) providers[idx] = &ProviderInstance{ BaseDN: provider.BaseDn, GroupDN: groupDN, diff --git a/outpost/pkg/ldap/bind.go b/outpost/pkg/ldap/bind.go index 8ebdabcd6..1fcc6e781 100644 --- a/outpost/pkg/ldap/bind.go +++ b/outpost/pkg/ldap/bind.go @@ -12,6 +12,8 @@ func (ls *LDAPServer) Bind(bindDN string, bindPW string, conn net.Conn) (ldap.LD username, err := instance.getUsername(bindDN) if err == nil { return instance.Bind(username, bindPW, conn) + } else { + ls.log.WithError(err).Debug("Username not for instance") } } ls.log.WithField("boundDN", bindDN).WithField("request", "bind").Warning("No provider found for request") diff --git a/outpost/pkg/ldap/instance_bind.go b/outpost/pkg/ldap/instance_bind.go index ea1f7b7a3..905f3060c 100644 --- a/outpost/pkg/ldap/instance_bind.go +++ b/outpost/pkg/ldap/instance_bind.go @@ -29,7 +29,7 @@ type PasswordResponse struct { } func (pi *ProviderInstance) getUsername(dn string) (string, error) { - if !strings.HasSuffix(dn, pi.BaseDN) { + if !strings.HasSuffix(strings.ToLower(dn), strings.ToLower(pi.BaseDN)) { return "", errors.New("invalid base DN") } dns, err := goldap.ParseDN(dn) @@ -38,12 +38,12 @@ func (pi *ProviderInstance) getUsername(dn string) (string, error) { } for _, part := range dns.RDNs { for _, attribute := range part.Attributes { - if attribute.Type == "DN" { + if strings.ToLower(attribute.Type) == "cn" { return attribute.Value, nil } } } - return "", errors.New("failed to find dn") + return "", errors.New("failed to find cn") } func (pi *ProviderInstance) Bind(username string, bindPW string, conn net.Conn) (ldap.LDAPResultCode, error) { @@ -150,6 +150,8 @@ func (pi *ProviderInstance) solveFlowChallenge(bindDN string, password string, c responseParams.Data = &UIDResponse{UIDFIeld: bindDN} case "ak-stage-password": responseParams.Data = &PasswordResponse{Password: password} + case "ak-stage-access-denied": + return false, errors.New("got ak-stage-access-denied") default: return false, fmt.Errorf("unsupported challenge type: %s", challenge.Payload.Component) } diff --git a/website/docs/outposts/ldap.md b/website/docs/outposts/ldap.md index c3fc75988..e9b0b6012 100644 --- a/website/docs/outposts/ldap.md +++ b/website/docs/outposts/ldap.md @@ -14,7 +14,9 @@ Binding against the LDAP Server uses a flow in the background. This allows you t You can configure under which base DN the information should be available. For this documentation we'll use the default of `DC=ldap,DC=goauthentik,DC=io`. -Users are available under `cn=users,` and groups under `cn=groups,`. +Users are available under `ou=users,` and groups under `ou=groups,`. + +You can bind using the DN `cn=,ou=users,`. The following fields are currently sent for users: @@ -36,7 +38,7 @@ The following fields are current set for groups: - cn: The group's name - uid: Unique group identifier - objectClass: A list of these strings: - - "user" + - "group" - "goauthentik.io/ldap/group" **Additionally**, for both users and groups, any attributes you set are also present as LDAP Attributes.