add user/group DNs to config
continuous-integration/drone/push Build is passing

This commit is contained in:
Nathan Coad
2026-04-21 14:24:16 +10:00
parent 14d242c8d1
commit 4fca10795e
5 changed files with 48 additions and 2 deletions
+23 -2
View File
@@ -25,6 +25,8 @@ var (
type LDAPConfig struct {
BindAddress string
BaseDN string
UserBaseDN string
GroupBaseDN string
TrustCertFile string
DisableValidation bool
Insecure bool
@@ -45,6 +47,8 @@ type LDAPIdentity struct {
type LDAPAuthenticator struct {
bindAddress string
baseDN string
userBaseDN string
groupBaseDN string
trustCertFile string
disableValidation bool
insecure bool
@@ -54,6 +58,8 @@ type LDAPAuthenticator struct {
func NewLDAPAuthenticator(cfg LDAPConfig) (*LDAPAuthenticator, error) {
bindAddress := strings.TrimSpace(cfg.BindAddress)
baseDN := strings.TrimSpace(cfg.BaseDN)
userBaseDN := strings.TrimSpace(cfg.UserBaseDN)
groupBaseDN := strings.TrimSpace(cfg.GroupBaseDN)
trustCertFile := strings.TrimSpace(cfg.TrustCertFile)
if bindAddress == "" {
@@ -62,6 +68,12 @@ func NewLDAPAuthenticator(cfg LDAPConfig) (*LDAPAuthenticator, error) {
if baseDN == "" {
return nil, fmt.Errorf("%w: base DN is required", ErrInvalidLDAPConfig)
}
if userBaseDN == "" {
userBaseDN = baseDN
}
if groupBaseDN == "" {
groupBaseDN = baseDN
}
if _, err := url.ParseRequestURI(bindAddress); err != nil {
return nil, fmt.Errorf("%w: bind address must be a valid URL: %v", ErrInvalidLDAPConfig, err)
}
@@ -74,6 +86,8 @@ func NewLDAPAuthenticator(cfg LDAPConfig) (*LDAPAuthenticator, error) {
return &LDAPAuthenticator{
bindAddress: bindAddress,
baseDN: baseDN,
userBaseDN: userBaseDN,
groupBaseDN: groupBaseDN,
trustCertFile: trustCertFile,
disableValidation: cfg.DisableValidation,
insecure: cfg.Insecure,
@@ -119,6 +133,10 @@ func (a *LDAPAuthenticator) AuthenticateAndFetchGroups(ctx context.Context, user
if rewrittenToUPN {
identity.Diagnostics = append(identity.Diagnostics, "bind_username_rewritten_to_upn")
}
identity.Diagnostics = append(identity.Diagnostics,
"user_lookup_base_dn="+a.userBaseDN,
"group_lookup_base_dn="+a.groupBaseDN,
)
if whoami, err := conn.WhoAmI(nil); err != nil {
identity.Diagnostics = append(identity.Diagnostics, fmt.Sprintf("whoami_failed:%v", err))
} else if boundDN := parseWhoAmIDN(whoami.AuthzID); boundDN != "" {
@@ -131,7 +149,7 @@ func (a *LDAPAuthenticator) AuthenticateAndFetchGroups(ctx context.Context, user
}
userLookupStartedAt := time.Now()
entry, lookupStrategy, err := a.lookupUserEntry(conn, bindUsername, identity.UserDN)
entry, lookupStrategy, err := a.lookupUserEntry(conn, inputUsername, identity.UserDN)
identity.UserLookupDuration = time.Since(userLookupStartedAt)
identity.Diagnostics = append(identity.Diagnostics, fmt.Sprintf("user_lookup_duration_ms=%d", identity.UserLookupDuration.Milliseconds()))
if err != nil {
@@ -329,6 +347,9 @@ func (a *LDAPAuthenticator) lookupUserEntry(conn *ldap.Conn, username string, us
if entry != nil {
return entry, "principal_upn", nil
}
// For UPN principals, avoid fallback attribute probes that are unlikely to match
// and can be expensive on large directory trees.
continue
}
entry, err := a.searchUserByAttribute(conn, "sAMAccountName", principal)
@@ -359,7 +380,7 @@ func (a *LDAPAuthenticator) searchUserByAttribute(conn *ldap.Conn, attribute str
}
searchRes, err := conn.Search(ldap.NewSearchRequest(
a.baseDN,
a.userBaseDN,
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
2,