mirror of
https://github.com/netauth/ldap.git
synced 2026-11-03 11:43:44 -06:00
79 lines
2.7 KiB
Go
79 lines
2.7 KiB
Go
package ldap
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
ldap "github.com/ps78674/ldapserver"
|
|
)
|
|
|
|
// fakeConn stands in for the server's unexported client type so that
|
|
// per-connection bind state can be exercised in tests.
|
|
type fakeConn struct {
|
|
data interface{}
|
|
}
|
|
|
|
func (c *fakeConn) GetAddData() interface{} { return c.data }
|
|
func (c *fakeConn) SetAddData(d interface{}) { c.data = d }
|
|
|
|
func boundTestServer(c naClient) *server {
|
|
fc := &fakeConn{}
|
|
s := &server{l: testLogger(), c: c}
|
|
s.nc = []string{"dc=netauth", "dc=example", "dc=com"}
|
|
s.conn = func(*ldap.Message) connection { return fc }
|
|
return s
|
|
}
|
|
|
|
func TestSearchRequiresBind(t *testing.T) {
|
|
s := boundTestServer(&fakeClient{})
|
|
|
|
w := &recordingWriter{}
|
|
s.handleSearchEntities(w, mustDecode(t, berSearchRequest("ou=entities,dc=netauth,dc=example,dc=com")))
|
|
|
|
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.LDAPResultInsufficientAccessRights {
|
|
t.Errorf("entities: result code is %d, want %d", code, ldap.LDAPResultInsufficientAccessRights)
|
|
}
|
|
|
|
w = &recordingWriter{}
|
|
s.handleSearchGroups(w, mustDecode(t, berSearchRequest("ou=groups,dc=netauth,dc=example,dc=com")))
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultInsufficientAccessRights {
|
|
t.Errorf("groups: result code is %d, want %d", code, ldap.LDAPResultInsufficientAccessRights)
|
|
}
|
|
}
|
|
|
|
func TestSearchAfterBindSucceeds(t *testing.T) {
|
|
s := boundTestServer(&fakeClient{})
|
|
|
|
// A successful bind marks the connection, so a follow-up search
|
|
// is no longer refused for lack of authentication.
|
|
s.handleBind(&recordingWriter{}, mustDecode(t,
|
|
berBindRequest("uid=jsmith,ou=entities,dc=netauth,dc=example,dc=com", "hunter2")))
|
|
|
|
w := &recordingWriter{}
|
|
s.handleSearchEntities(w, mustDecode(t, berSearchRequest("ou=entities,dc=netauth,dc=example,dc=com")))
|
|
if code := resultCode(t, w.responses[len(w.responses)-1]); code == ldap.LDAPResultInsufficientAccessRights {
|
|
t.Errorf("a bound connection was still refused")
|
|
}
|
|
}
|
|
|
|
func TestFailedRebindClearsConnection(t *testing.T) {
|
|
c := &fakeClient{authErr: errors.New("invalid password")}
|
|
s := boundTestServer(c)
|
|
|
|
// Mark the connection bound, then have a rebind fail; RFC 4511
|
|
// requires the connection to drop back to unauthenticated.
|
|
s.markBound(&ldap.Message{})
|
|
w := &recordingWriter{}
|
|
s.handleBind(w, mustDecode(t,
|
|
berBindRequest("uid=jsmith,ou=entities,dc=netauth,dc=example,dc=com", "wrong")))
|
|
if code := resultCode(t, w.responses[0]); code != ldap.LDAPResultInvalidCredentials {
|
|
t.Fatalf("bind result code is %d, want %d", code, ldap.LDAPResultInvalidCredentials)
|
|
}
|
|
if s.bound(&ldap.Message{}) {
|
|
t.Error("connection still marked bound after a failed bind")
|
|
}
|
|
}
|