package ldapauth import ( "errors" "os" "path/filepath" "testing" ) func TestNewRequiresURIAndBase(t *testing.T) { if _, err := New(Config{SearchBase: "dc=x"}); err == nil { t.Fatal("want error for missing uri") } if _, err := New(Config{URIs: []string{"ldap://x"}}); err == nil { t.Fatal("want error for missing search_base") } } func TestNewAppliesSSSDDefaults(t *testing.T) { a, err := New(Config{URIs: []string{"ldap://x"}, SearchBase: "dc=x"}) if err != nil { t.Fatalf("unexpected error: %v", err) } if a.cfg.UserAttr != "uid" { t.Errorf("UserAttr default = %q, want uid", a.cfg.UserAttr) } if a.cfg.UserObjectClass != "posixAccount" { t.Errorf("UserObjectClass default = %q, want posixAccount", a.cfg.UserObjectClass) } if a.cfg.Timeout <= 0 { t.Errorf("Timeout default not applied: %v", a.cfg.Timeout) } } // Empty passwords must be rejected before any bind: a non-empty DN + empty // password is an "unauthenticated bind" many servers accept as success. func TestAuthenticateRejectsEmptyPasswordWithoutDialing(t *testing.T) { // An unreachable URI guarantees the test fails loudly if it ever tries to dial. a, err := New(Config{URIs: []string{"ldap://127.0.0.1:1"}, SearchBase: "dc=x"}) if err != nil { t.Fatalf("unexpected error: %v", err) } if err := a.Authenticate("alice", ""); !errors.Is(err, ErrInvalidCredentials) { t.Fatalf("want ErrInvalidCredentials for empty password, got %v", err) } } func TestNewRejectsBadCACert(t *testing.T) { dir := t.TempDir() bad := filepath.Join(dir, "ca.pem") if err := os.WriteFile(bad, []byte("not a certificate"), 0o600); err != nil { t.Fatal(err) } if _, err := New(Config{URIs: []string{"ldaps://x"}, SearchBase: "dc=x", CACertFile: bad}); err == nil { t.Fatal("want error for CA file with no certificates") } if _, err := New(Config{URIs: []string{"ldaps://x"}, SearchBase: "dc=x", CACertFile: filepath.Join(dir, "missing.pem")}); err == nil { t.Fatal("want error for missing CA file") } }