fix: reject disabled users on all backends in Bind (#470)

A user with disabled = true could still bind on the config backend, since
configHandler.FindUser and LDAPOpsHelper.Bind never checked Disabled while the
SQL backends drop such users at lookup. Enforce it in Bind so every backend
behaves the same.
This commit is contained in:
kt
2026-07-19 06:53:08 +09:00
committed by GitHub
parent cb121cdc2c
commit fb65713fbd
2 changed files with 62 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
package handler
import (
"context"
"encoding/hex"
"net"
"testing"
"github.com/rs/zerolog"
"go.opentelemetry.io/otel/trace/noop"
"golang.org/x/crypto/bcrypt"
"github.com/glauth/glauth/v2/pkg/config"
"github.com/glauth/ldap"
)
func TestConfigBackendDisabledUserCannotBind(t *testing.T) {
pw := "correct horse"
raw, _ := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.MinCost)
hexHash := hex.EncodeToString(raw)
cfg := &config.Config{}
cfg.Users = []config.User{
{Name: "activeuser", PrimaryGroup: 5501, PassBcrypt: hexHash, Disabled: false},
{Name: "disableduser", PrimaryGroup: 5501, PassBcrypt: hexHash, Disabled: true},
}
logger := zerolog.Nop()
tracer := noop.NewTracerProvider().Tracer("f001")
helper := NewLDAPOpsHelper(tracer)
h := configHandler{
backend: config.Backend{
BaseDN: "dc=example,dc=com",
NameFormatAsArray: []string{"cn"},
GroupFormatAsArray: []string{"ou"},
},
log: &logger,
cfg: cfg,
ldohelper: helper,
tracer: tracer,
}
_, server := net.Pipe()
defer server.Close()
bind := func(dn, pass string) ldap.LDAPResultCode {
code, _ := helper.Bind(context.Background(), h, dn, pass, server)
return code
}
if code := bind("cn=activeuser,dc=example,dc=com", pw); code != ldap.LDAPResultSuccess {
t.Fatalf("active user with correct pw should bind, got %d", code)
}
if code := bind("cn=disableduser,dc=example,dc=com", pw); code != ldap.LDAPResultInvalidCredentials {
t.Errorf("disabled user must be rejected; got code %d, want InvalidCredentials(49)", code)
}
}
+6
View File
@@ -102,6 +102,12 @@ func (l LDAPOpsHelper) Bind(ctx context.Context, h LDAPOpsHandler, bindDN, bindS
return ldapcode, nil
}
// a disabled account must never authenticate, on any backend
if user.Disabled {
h.GetLog().Info().Str("binddn", bindDN).Str("src", conn.RemoteAddr().String()).Msg("Bind attempt on disabled account")
return ldap.LDAPResultInvalidCredentials, nil
}
validotp := false
if len(user.Yubikey) == 0 && len(user.OTPSecret) == 0 {