diff --git a/internal/ldap/ldap.go b/internal/ldap/ldap.go index 3b3924b..281417f 100644 --- a/internal/ldap/ldap.go +++ b/internal/ldap/ldap.go @@ -55,18 +55,9 @@ func (s *server) ServeTLS(bind, keypath, certpath string) error { } func (s *server) handleNotFound(w ldap.ResponseWriter, r *ldap.Message) { - switch r.ProtocolOpType() { - case ldap.ApplicationBindRequest: - res := ldap.NewBindResponse(ldap.LDAPResultSuccess) - res.SetDiagnosticMessage("Default binding behavior set to return Success") - - w.Write(res) - - default: - res := ldap.NewResponse(ldap.LDAPResultUnwillingToPerform) - res.SetDiagnosticMessage("Operation not implemented by server") - w.Write(res) - } + res := ldap.NewResponse(ldap.LDAPResultUnwillingToPerform) + res.SetDiagnosticMessage("Operation not implemented by server") + w.Write(res) } func (s *server) handleAbandon(w ldap.ResponseWriter, m *ldap.Message) { diff --git a/internal/ldap/ldap_test.go b/internal/ldap/ldap_test.go new file mode 100644 index 0000000..dc7fc47 --- /dev/null +++ b/internal/ldap/ldap_test.go @@ -0,0 +1,26 @@ +package ldap + +import ( + "testing" + + ldap "github.com/ps78674/ldapserver" +) + +// The router has a catch-all NotFound handler. Even if a bind somehow +// reaches it (for example if a future routing change lets an +// authentication choice slip past handleBind), it must fail closed +// rather than reporting success. +func TestNotFoundRefusesBind(t *testing.T) { + s := &server{l: testLogger()} + s.nc = []string{"dc=netauth", "dc=example", "dc=com"} + + w := &recordingWriter{} + s.handleNotFound(w, mustDecode(t, berBindRequest("", ""))) + + if len(w.responses) != 1 { + t.Fatalf("got %d responses, want exactly 1", len(w.responses)) + } + if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultUnwillingToPerform { + t.Errorf("result code is %d, want %d", code, ldap.LDAPResultUnwillingToPerform) + } +}