Skip to content

Commit fb65713

Browse files
authored
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.
1 parent cb121cd commit fb65713

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package handler
2+
3+
import (
4+
"context"
5+
"encoding/hex"
6+
"net"
7+
"testing"
8+
9+
"github.com/rs/zerolog"
10+
"go.opentelemetry.io/otel/trace/noop"
11+
"golang.org/x/crypto/bcrypt"
12+
13+
"github.com/glauth/glauth/v2/pkg/config"
14+
"github.com/glauth/ldap"
15+
)
16+
17+
func TestConfigBackendDisabledUserCannotBind(t *testing.T) {
18+
pw := "correct horse"
19+
raw, _ := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.MinCost)
20+
hexHash := hex.EncodeToString(raw)
21+
22+
cfg := &config.Config{}
23+
cfg.Users = []config.User{
24+
{Name: "activeuser", PrimaryGroup: 5501, PassBcrypt: hexHash, Disabled: false},
25+
{Name: "disableduser", PrimaryGroup: 5501, PassBcrypt: hexHash, Disabled: true},
26+
}
27+
28+
logger := zerolog.Nop()
29+
tracer := noop.NewTracerProvider().Tracer("f001")
30+
helper := NewLDAPOpsHelper(tracer)
31+
h := configHandler{
32+
backend: config.Backend{
33+
BaseDN: "dc=example,dc=com",
34+
NameFormatAsArray: []string{"cn"},
35+
GroupFormatAsArray: []string{"ou"},
36+
},
37+
log: &logger,
38+
cfg: cfg,
39+
ldohelper: helper,
40+
tracer: tracer,
41+
}
42+
_, server := net.Pipe()
43+
defer server.Close()
44+
45+
bind := func(dn, pass string) ldap.LDAPResultCode {
46+
code, _ := helper.Bind(context.Background(), h, dn, pass, server)
47+
return code
48+
}
49+
50+
if code := bind("cn=activeuser,dc=example,dc=com", pw); code != ldap.LDAPResultSuccess {
51+
t.Fatalf("active user with correct pw should bind, got %d", code)
52+
}
53+
if code := bind("cn=disableduser,dc=example,dc=com", pw); code != ldap.LDAPResultInvalidCredentials {
54+
t.Errorf("disabled user must be rejected; got code %d, want InvalidCredentials(49)", code)
55+
}
56+
}

‎v2/pkg/handler/ldapopshelper.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ func (l LDAPOpsHelper) Bind(ctx context.Context, h LDAPOpsHandler, bindDN, bindS
102102
return ldapcode, nil
103103
}
104104

105+
// a disabled account must never authenticate, on any backend
106+
if user.Disabled {
107+
h.GetLog().Info().Str("binddn", bindDN).Str("src", conn.RemoteAddr().String()).Msg("Bind attempt on disabled account")
108+
return ldap.LDAPResultInvalidCredentials, nil
109+
}
110+
105111
validotp := false
106112

107113
if len(user.Yubikey) == 0 && len(user.OTPSecret) == 0 {

0 commit comments

Comments
 (0)