int delivery_mode;
int message_originated_locally;
int is_lmtp;
+ int is_unfiltered;
int is_msa;
};
}
+/*
+ * We also have an unfiltered LMTP socket that bypasses spam filters.
+ */
+void lmtp_unfiltered_greeting(void) {
+ smtp_greeting();
+ SMTP->is_lmtp = 1;
+ SMTP->is_unfiltered = 1;
+}
+
+
/*
* Login greeting common to all auth methods
*/
*/
void smtp_rset(int do_response) {
int is_lmtp;
+ int is_unfiltered;
/*
* Our entire SMTP state is discarded when a RSET command is issued,
* we save it for later.
*/
is_lmtp = SMTP->is_lmtp;
+ is_unfiltered = SMTP->is_unfiltered;
memset(SMTP, 0, sizeof(struct citsmtp));
* Reinstate this little piece of information we saved (see above).
*/
SMTP->is_lmtp = is_lmtp;
+ SMTP->is_unfiltered = is_unfiltered;
if (do_response) {
cprintf("250 2.0.0 Zap!\r\n");
}
/* Otherwise, make sure outsiders aren't trying to forge mail from
- * this system.
+ * this system (unless, of course, c_allow_spoofing is enabled)
*/
- else {
+ else if (config.c_allow_spoofing == 0) {
process_rfc822_addr(SMTP->from, user, node, name);
if (CtdlHostAlias(node) != hostalias_nomatch) {
cprintf("550 5.1.8 "
}
valid = validate_recipients(recp);
- if (valid->num_error > 0) {
+ if (valid->num_error != 0) {
cprintf("599 5.1.1 Error: %s\r\n", valid->errormsg);
free(valid);
return;
* submission (such as virus checkers or spam filters), call them now
* and give them an opportunity to reject the message.
*/
- scan_errors = PerformMessageHooks(msg, EVT_SMTPSCAN);
+ if (SMTP->is_unfiltered) {
+ scan_errors = 0;
+ }
+ else {
+ scan_errors = PerformMessageHooks(msg, EVT_SMTPSCAN);
+ }
if (scan_errors > 0) { /* We don't want this message! */
time(&CC->lastcmd);
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
- lprintf(CTDL_CRIT, "SMTP socket is broken. Ending session.\n");
+ lprintf(CTDL_CRIT, "Client disconnected: ending session.\n");
CC->kill_me = 1;
return;
}
CC->redirect_buffer = malloc(SIZ);
CC->redirect_len = 0;
CC->redirect_alloc = SIZ;
- CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1);
+ CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL);
msgtext = CC->redirect_buffer;
msg_size = CC->redirect_len;
CC->redirect_buffer = NULL;
}
/* MAIL succeeded, now try the RCPT To: command */
- snprintf(buf, sizeof buf, "RCPT To: <%s>\r\n", addr);
+ snprintf(buf, sizeof buf, "RCPT To: <%s@%s>\r\n", user, node);
lprintf(CTDL_DEBUG, ">%s", buf);
sock_write(sock, buf, strlen(buf));
if (ml_sock_gets(sock, buf) < 0) {
* message and the message message.
*/
if (incomplete_deliveries_remaining <= 0) {
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "");
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "", 0);
}
* instructions and replace with the updated ones.
*/
if (incomplete_deliveries_remaining > 0) {
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
msg = malloc(sizeof(struct CtdlMessage));
memset(msg, 0, sizeof(struct CtdlMessage));
msg->cm_magic = CTDLMESSAGE_MAGIC;
NULL);
CtdlRegisterServiceHook(0, /* local LMTP */
- "lmtp.socket",
- lmtp_greeting,
- smtp_command_loop,
- NULL);
+#ifndef HAVE_RUN_DIR
+ "."
+#else
+ RUN_DIR
+#endif
+ "/lmtp.socket",
+ lmtp_greeting,
+ smtp_command_loop,
+ NULL);
+
+ CtdlRegisterServiceHook(0, /* local LMTP */
+#ifndef HAVE_RUN_DIR
+ "."
+#else
+ RUN_DIR
+#endif
+ "/lmtp-unfiltered.socket",
+ lmtp_unfiltered_greeting,
+ smtp_command_loop,
+ NULL);
smtp_init_spoolout();
CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER);