author | Alberto Bertogli
<albertito@blitiri.com.ar> 2021-05-29 23:32:54 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2021-05-29 23:39:24 UTC |
parent | fa651e74e370fb788a79d1ae11ec804e77179d7e |
internal/smtpsrv/conn.go | +11 | -8 |
internal/smtpsrv/server_test.go | +19 | -1 |
diff --git a/internal/smtpsrv/conn.go b/internal/smtpsrv/conn.go index 31d754d..f3d76cb 100644 --- a/internal/smtpsrv/conn.go +++ b/internal/smtpsrv/conn.go @@ -578,7 +578,14 @@ func (c *Conn) RCPT(params string) (code int, msg string) { return 550, "5.1.3 Destination address is invalid" } - if !c.userExists(addr) { + ok, err := c.userExists(addr) + if err != nil { + c.tr.Errorf("error checking if user %q exists: %v", addr, err) + maillog.Rejected(c.remoteAddr, c.mailFrom, []string{addr}, + fmt.Sprintf("error checking if user exists: %v", err)) + return 451, "4.4.3 Temporary error checking address" + } + if !ok { maillog.Rejected(c.remoteAddr, c.mailFrom, []string{addr}, "local user does not exist") return 550, "5.1.1 Destination address is unknown (user does not exist)" @@ -1081,11 +1088,11 @@ func (c *Conn) resetEnvelope() { c.spfError = nil } -func (c *Conn) userExists(addr string) bool { +func (c *Conn) userExists(addr string) (bool, error) { var ok bool addr, ok = c.aliasesR.Exists(addr) if ok { - return true + return true, nil } // Note we used the address returned by the aliases resolver, which has @@ -1093,11 +1100,7 @@ func (c *Conn) userExists(addr string) bool { // look up "user" in our databases if the domain is local, which is what // we want. user, domain := envelope.Split(addr) - ok, err := c.authr.Exists(user, domain) - if err != nil { - c.tr.Errorf("error checking if user %q exists: %v", addr, err) - } - return ok + return c.authr.Exists(user, domain) } func (c *Conn) readCommand() (cmd, params string, err error) { diff --git a/internal/smtpsrv/server_test.go b/internal/smtpsrv/server_test.go index 381fada..675a658 100644 --- a/internal/smtpsrv/server_test.go +++ b/internal/smtpsrv/server_test.go @@ -308,7 +308,7 @@ func TestTooManyRecipients(t *testing.T) { } } -func TestRcptFailsExistsCheck(t *testing.T) { +func TestRcptBrokenExists(t *testing.T) { c := mustDial(t, ModeSMTP, true) defer c.Close() @@ -320,6 +320,24 @@ func TestRcptFailsExistsCheck(t *testing.T) { if err == nil { t.Errorf("Accepted RCPT with broken Exists") } + expect := "451 4.4.3 Temporary error checking address" + if err.Error() != expect { + t.Errorf("RCPT returned unexpected error %q", err.Error()) + } +} + +func TestRcptUserDoesNotExist(t *testing.T) { + c := mustDial(t, ModeSMTP, true) + defer c.Close() + + if err := c.Mail("from@localhost"); err != nil { + t.Fatalf("Mail: %v", err) + } + + err := c.Rcpt("doesnotexist@localhost") + if err == nil { + t.Errorf("Accepted RCPT for non-existent user") + } expect := "550 5.1.1 Destination address is unknown (user does not exist)" if err.Error() != expect { t.Errorf("RCPT returned unexpected error %q", err.Error())