diff options
Diffstat (limited to 'usr.sbin/smtpd/smtp.c')
-rw-r--r-- | usr.sbin/smtpd/smtp.c | 115 |
1 files changed, 41 insertions, 74 deletions
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index 4e9a8eba531..4269ccdc6e9 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,9 +1,9 @@ -/* $OpenBSD: smtp.c,v 1.71 2010/05/19 20:57:10 gilles Exp $ */ +/* $OpenBSD: smtp.c,v 1.72 2010/05/31 23:38:56 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> - * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net> + * Copyright (c) 2009-2010 Jacek Masiulaniec <jacekm@dobremiasto.net> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -39,6 +39,7 @@ #include <unistd.h> #include "smtpd.h" +#include "queue_backend.h" void smtp_imsg(struct smtpd *, struct imsgev *, struct imsg *); __dead void smtp_shutdown(void); @@ -46,21 +47,22 @@ void smtp_sig_handler(int, short, void *); void smtp_setup_events(struct smtpd *); void smtp_disable_events(struct smtpd *); void smtp_pause(struct smtpd *); -int smtp_enqueue(struct smtpd *, uid_t *); +int smtp_enqueue(struct smtpd *, uid_t); void smtp_accept(int, short, void *); struct session *smtp_new(struct listener *); -struct session *session_lookup(struct smtpd *, u_int64_t); +struct session *session_lookup(struct smtpd *, u_int32_t); + +u_int32_t smtp_id; void smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg) { - struct session skey; - struct submit_status *ss; struct listener *l; struct session *s; struct auth *auth; struct ssl *ssl; struct dns *dns; + int status, fd; if (iev->proc == PROC_LKA) { switch (imsg->hdr.type) { @@ -81,82 +83,56 @@ smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_MFA) { switch (imsg->hdr.type) { - case IMSG_MFA_RCPT: case IMSG_MFA_MAIL: - log_debug("smtp: got imsg_mfa_mail/rcpt"); - ss = imsg->data; - s = session_lookup(env, ss->id); + case IMSG_MFA_RCPT: + s = session_lookup(env, imsg->hdr.peerid); if (s == NULL) return; - session_pickup(s, ss); + memcpy(&status, imsg->data, sizeof status); + s->s_msg.status |= status; + session_pickup(s); return; } } if (iev->proc == PROC_QUEUE) { - ss = imsg->data; - switch (imsg->hdr.type) { - case IMSG_QUEUE_CREATE_MESSAGE: - log_debug("smtp: imsg_queue_create_message returned"); - s = session_lookup(env, ss->id); + case IMSG_QUEUE_CREATE: + s = session_lookup(env, imsg->hdr.peerid); if (s == NULL) return; - strlcpy(s->s_msg.message_id, ss->u.msgid, - sizeof s->s_msg.message_id); - session_pickup(s, ss); + memcpy(&s->content_id, imsg->data, sizeof s->content_id); + memcpy(&s->queue_id, (u_int64_t *)imsg->data + 1, + sizeof s->queue_id); + if (s->content_id == INVALID_ID) + s->s_msg.status |= S_MESSAGE_TEMPFAILURE; + session_pickup(s); return; - case IMSG_QUEUE_MESSAGE_FILE: - log_debug("smtp: imsg_queue_message_file returned"); - s = session_lookup(env, ss->id); + case IMSG_QUEUE_OPEN: + s = session_lookup(env, imsg->hdr.peerid); if (s == NULL) { close(imsg->fd); return; } - s->datafp = fdopen(imsg->fd, "w"); - if (s->datafp == NULL) { - /* queue may have experienced tempfail. */ - if (ss->code != 421) - fatalx("smtp: fdopen"); - close(imsg->fd); - } - session_pickup(s, ss); - return; - - case IMSG_QUEUE_TEMPFAIL: - log_debug("smtp: got imsg_queue_tempfail"); - skey.s_id = ss->id; - s = SPLAY_FIND(sessiontree, &env->sc_sessions, &skey); - if (s == NULL) - fatalx("smtp: session is gone"); - if (s->s_flags & F_WRITEONLY) - /* session is write-only, must not destroy it. */ - s->s_msg.status |= S_MESSAGE_TEMPFAILURE; - else - fatalx("smtp: corrupt session"); + s->datafp = fdopen(imsg->fd, "a"); + if (s->datafp == NULL) + fatal("smtp: fdopen"); + session_pickup(s); return; - case IMSG_QUEUE_COMMIT_ENVELOPES: - log_debug("smtp: got imsg_queue_commit_envelopes"); - s = session_lookup(env, ss->id); + case IMSG_QUEUE_CLOSE: + s = session_lookup(env, imsg->hdr.peerid); if (s == NULL) return; - session_pickup(s, ss); - return; - - case IMSG_QUEUE_COMMIT_MESSAGE: - log_debug("smtp: got imsg_queue_commit_message"); - s = session_lookup(env, ss->id); - if (s == NULL) - return; - session_pickup(s, ss); + memcpy(&status, imsg->data, sizeof status); + s->s_msg.status |= status; + session_pickup(s); return; case IMSG_SMTP_ENQUEUE: - imsg_compose_event(iev, IMSG_SMTP_ENQUEUE, 0, 0, - smtp_enqueue(env, NULL), imsg->data, - sizeof(struct message)); + fd = smtp_enqueue(env, getuid()); + imsg_compose_event(iev, IMSG_SMTP_ENQUEUE, imsg->hdr.peerid, 0, fd, NULL, 0); return; } } @@ -249,7 +225,7 @@ smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg) s->s_flags &= ~F_AUTHENTICATED; s->s_msg.flags &= ~F_MESSAGE_AUTHENTICATED; } - session_pickup(s, NULL); + session_pickup(s); return; case IMSG_CTL_VERBOSE: @@ -261,9 +237,9 @@ smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_CONTROL) { switch (imsg->hdr.type) { case IMSG_SMTP_ENQUEUE: + fd = smtp_enqueue(env, *(uid_t *)imsg->data); imsg_compose_event(iev, IMSG_SMTP_ENQUEUE, - imsg->hdr.peerid, 0, smtp_enqueue(env, imsg->data), - NULL, 0); + imsg->hdr.peerid, 0, fd, NULL, 0); return; case IMSG_SMTP_PAUSE: @@ -436,7 +412,7 @@ smtp_resume(struct smtpd *env) } int -smtp_enqueue(struct smtpd *env, uid_t *euid) +smtp_enqueue(struct smtpd *env, uid_t uid) { static struct listener local, *l; static struct sockaddr_storage sa; @@ -476,16 +452,8 @@ smtp_enqueue(struct smtpd *env, uid_t *euid) s->s_fd = fd[0]; s->s_ss = sa; - s->s_msg.flags |= F_MESSAGE_ENQUEUED; - - if (euid) - bsnprintf(s->s_hostname, sizeof(s->s_hostname), "%d@localhost", - *euid); - else { - strlcpy(s->s_hostname, "localhost", sizeof(s->s_hostname)); - s->s_msg.flags |= F_MESSAGE_BOUNCE; - } + bsnprintf(s->s_hostname, sizeof(s->s_hostname), "%d@localhost", uid); strlcpy(s->s_msg.session_hostname, s->s_hostname, sizeof(s->s_msg.session_hostname)); @@ -515,7 +483,6 @@ smtp_accept(int fd, short event, void *p) dns_query_ptr(l->env, &s->s_ss, s->s_id); } - struct session * smtp_new(struct listener *l) { @@ -535,7 +502,7 @@ smtp_new(struct listener *l) if ((s = calloc(1, sizeof(*s))) == NULL) fatal(NULL); - s->s_id = generate_uid(); + s->s_id = smtp_id++; s->s_env = env; s->s_l = l; strlcpy(s->s_msg.tag, l->tag, sizeof(s->s_msg.tag)); @@ -551,7 +518,7 @@ smtp_new(struct listener *l) * Helper function for handling IMSG replies. */ struct session * -session_lookup(struct smtpd *env, u_int64_t id) +session_lookup(struct smtpd *env, u_int32_t id) { struct session key; struct session *s; |