Exemplo n.º 1
0
int     flush_add(const char *site, const char *queue_id)
{
    const char *myname = "flush_add";
    int     status;

    if (msg_verbose)
	msg_info("%s: site %s id %s", myname, site, queue_id);

    /*
     * Don't bother the server if the service is turned off, or if the site
     * is not eligible.
     */
    if (flush_domains == 0)
	msg_panic("missing flush client initialization");
    if (domain_list_match(flush_domains, site) != 0)
	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
				ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_ADD,
				     ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
				 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
				     ATTR_TYPE_END);
    else if (flush_domains->error == 0)
	status = FLUSH_STAT_DENY;
    else
	status = FLUSH_STAT_FAIL;

    if (msg_verbose)
	msg_info("%s: site %s id %s status %d", myname, site, queue_id,
		 status);

    return (status);
}
Exemplo n.º 2
0
int     bounce_flush_verp(int flags, const char *queue, const char *id,
			          const char *encoding, const char *sender,
			          const char *dsn_envid, int dsn_ret,
			          const char *verp_delims)
{

    /*
     * When we're pretending that we can't bounce, don't send a bounce
     * message.
     */
    if (var_soft_bounce)
	return (-1);
    if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
			    ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_VERP,
			    ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
			    ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
			    ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
			    ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
			    ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
			    ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
			    ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
			    ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
			    ATTR_TYPE_END) == 0) {
	return (0);
    } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
	msg_info("%s: status=deferred (bounce failed)", id);
	return (-1);
    } else {
	return (-1);
    }
}
Exemplo n.º 3
0
int     trace_append(int flags, const char *id, MSG_STATS *stats,
                     RECIPIENT *rcpt, const char *relay,
                     DSN *dsn)
{
    VSTRING *why = vstring_alloc(100);
    DSN     my_dsn = *dsn;
    int     req_stat;

    /*
     * User-requested address verification, verbose delivery, or DSN SUCCESS
     * notification.
     */
    if (strcmp(relay, NO_RELAY_AGENT) != 0)
        vstring_sprintf(why, "delivery via %s: ", relay);
    vstring_strcat(why, my_dsn.reason);
    my_dsn.reason = vstring_str(why);

    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
                            ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND,
                            ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
                            ATTR_TYPE_FUNC, rcpt_print, (void *) rcpt,
                            ATTR_TYPE_FUNC, dsn_print, (void *) &my_dsn,
                            ATTR_TYPE_END) != 0) {
        msg_warn("%s: %s service failure", id, var_trace_service);
        req_stat = -1;
    } else {
        if (flags & DEL_REQ_FLAG_USR_VRFY)
            log_adhoc(id, stats, rcpt, relay, dsn, my_dsn.action);
        req_stat = 0;
    }
    vstring_free(why);
    return (req_stat);
}
Exemplo n.º 4
0
int     defer_warn(int flags, const char *queue, const char *id,
		         const char *sender, const char *envid, int dsn_ret)
{
    if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
			    ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
			    ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
			    ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
			    ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
			    ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
			    ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, envid,
			    ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
			    ATTR_TYPE_END) == 0) {
	return (0);
    } else {
	return (-1);
    }
}
Exemplo n.º 5
0
int     trace_flush(int flags, const char *queue, const char *id,
                    const char *encoding, const char *sender,
                    const char *dsn_envid, int dsn_ret)
{
    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
                            ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_TRACE,
                            ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
                            ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
                            ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
                            ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
                            ATTR_TYPE_END) == 0) {
        return (0);
    } else {
        return (-1);
    }
}
Exemplo n.º 6
0
int     flush_send_file(const char *queue_id)
{
    const char *myname = "flush_send_file";
    int     status;

    if (msg_verbose)
	msg_info("%s: queue_id %s", myname, queue_id);

    /*
     * Require that the service is turned on.
     */
    status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
			  ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_SEND_FILE,
				 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
				 ATTR_TYPE_END);

    if (msg_verbose)
	msg_info("%s: queue_id %s status %d", myname, queue_id, status);

    return (status);
}
Exemplo n.º 7
0
int     flush_refresh(void)
{
    const char *myname = "flush_refresh";
    int     status;

    if (msg_verbose)
	msg_info("%s", myname);

    /*
     * Don't bother the server if the service is turned off.
     */
    if (*var_fflush_domains == 0)
	status = FLUSH_STAT_DENY;
    else
	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
			    ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_REFRESH,
				     ATTR_TYPE_END);

    if (msg_verbose)
	msg_info("%s: status %d", myname, status);

    return (status);
}
Exemplo n.º 8
0
int     defer_append(int flags, const char *id, MSG_STATS *stats,
		             RECIPIENT *rcpt, const char *relay,
		             DSN *dsn)
{
    const char *rcpt_domain;
    DSN     my_dsn = *dsn;
    int     status;

    /*
     * Sanity check.
     */
    if (my_dsn.status[0] != '4' || !dsn_valid(my_dsn.status)) {
	msg_warn("defer_append: ignoring dsn code \"%s\"", my_dsn.status);
	my_dsn.status = "4.0.0";
    }

    /*
     * MTA-requested address verification information is stored in the verify
     * service database.
     */
    if (flags & DEL_REQ_FLAG_MTA_VRFY) {
	my_dsn.action = "undeliverable";
	status = verify_append(id, stats, rcpt, relay, &my_dsn,
			       DEL_RCPT_STAT_DEFER);
	return (status);
    }

    /*
     * User-requested address verification information is logged and mailed
     * to the requesting user.
     */
    if (flags & DEL_REQ_FLAG_USR_VRFY) {
	my_dsn.action = "undeliverable";
	status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
	return (status);
    }

    /*
     * Normal mail delivery. May also send a delivery record to the user.
     * 
     * XXX DSN We write all deferred recipients to the defer logfile regardless
     * of DSN NOTIFY options, because those options don't apply to mailq(1)
     * reports or to postmaster notifications.
     */
    else {

	/*
	 * Supply default action.
	 */
	my_dsn.action = "delayed";

	if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
			   ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND,
				ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
				ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
				ATTR_TYPE_FUNC, rcpt_print, (void *) rcpt,
				ATTR_TYPE_FUNC, dsn_print, (void *) &my_dsn,
				ATTR_TYPE_END) != 0)
	    msg_warn("%s: %s service failure", id, var_defer_service);
	log_adhoc(id, stats, rcpt, relay, &my_dsn, "deferred");

	/*
	 * Traced delivery.
	 */
	if (flags & DEL_REQ_FLAG_RECORD)
	    if (trace_append(flags, id, stats, rcpt, relay, &my_dsn) != 0)
		msg_warn("%s: %s service failure", id, var_trace_service);

	/*
	 * Notify the fast flush service. XXX Should not this belong in the
	 * bounce/defer daemon? Well, doing it here is more robust.
	 */
	if ((rcpt_domain = strrchr(rcpt->address, '@')) != 0
	    && *++rcpt_domain != 0)
	    switch (flush_add(rcpt_domain, id)) {
	    case FLUSH_STAT_OK:
	    case FLUSH_STAT_DENY:
		break;
	    default:
		msg_warn("%s: %s service failure", id, var_flush_service);
		break;
	    }
	return (-1);
    }
}
Exemplo n.º 9
0
int     bounce_one_intern(int flags, const char *queue, const char *id,
			          const char *encoding, const char *sender,
			          const char *dsn_envid, int dsn_ret,
			          MSG_STATS *stats, RECIPIENT *rcpt,
			          const char *relay, DSN *dsn)
{
    DSN     my_dsn = *dsn;
    int     status;

    /*
     * MTA-requested address verification information is stored in the verify
     * service database.
     */
    if (flags & DEL_REQ_FLAG_MTA_VRFY) {
	my_dsn.action = "undeliverable";
	status = verify_append(id, stats, rcpt, relay, &my_dsn,
			       DEL_RCPT_STAT_BOUNCE);
	return (status);
    }

    /*
     * User-requested address verification information is logged and mailed
     * to the requesting user.
     */
    if (flags & DEL_REQ_FLAG_USR_VRFY) {
	my_dsn.action = "undeliverable";
	status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
	return (status);
    }

    /*
     * When we're not bouncing, then use the standard multi-recipient logfile
     * based procedure.
     */
    else if (var_soft_bounce) {
	return (bounce_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
    }

    /*
     * Normal mail delivery. May also send a delivery record to the user.
     * 
     * XXX DSN We send all recipients regardless of DSN NOTIFY options, because
     * those options don't apply to postmaster notifications.
     */
    else {

	/*
	 * Supply default action.
	 */
	my_dsn.action = "failed";

	if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
			      ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_ONE,
				ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
				ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
				ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
				ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
				ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
			      ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
				ATTR_TYPE_INT, MAIL_ATTR_DSN_RET, dsn_ret,
				ATTR_TYPE_FUNC, rcpt_print, (void *) rcpt,
				ATTR_TYPE_FUNC, dsn_print, (void *) &my_dsn,
				ATTR_TYPE_END) == 0
	    && ((flags & DEL_REQ_FLAG_RECORD) == 0
		|| trace_append(flags, id, stats, rcpt, relay,
				&my_dsn) == 0)) {
	    log_adhoc(id, stats, rcpt, relay, &my_dsn, "bounced");
	    status = 0;
	} else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
	    VSTRING *junk = vstring_alloc(100);

	    my_dsn.status = "4.3.0";
	    vstring_sprintf(junk, "%s or %s service failure",
			    var_bounce_service, var_trace_service);
	    my_dsn.reason = vstring_str(junk);
	    status = defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn);
	    vstring_free(junk);
	} else {
	    status = -1;
	}
	return (status);
    }
}
Exemplo n.º 10
0
int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
			             RECIPIENT *rcpt, const char *relay,
			             DSN *dsn)
{
    DSN     my_dsn = *dsn;
    int     status;

    /*
     * MTA-requested address verification information is stored in the verify
     * service database.
     */
    if (flags & DEL_REQ_FLAG_MTA_VRFY) {
	my_dsn.action = "undeliverable";
	status = verify_append(id, stats, rcpt, relay, &my_dsn,
			       DEL_RCPT_STAT_BOUNCE);
	return (status);
    }

    /*
     * User-requested address verification information is logged and mailed
     * to the requesting user.
     */
    if (flags & DEL_REQ_FLAG_USR_VRFY) {
	my_dsn.action = "undeliverable";
	status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
	return (status);
    }

    /*
     * Normal (well almost) delivery. When we're pretending that we can't
     * bounce, don't create a defer log file when we wouldn't keep the bounce
     * log file. That's a lot of negatives in one sentence.
     */
    else if (var_soft_bounce && (flags & BOUNCE_FLAG_CLEAN)) {
	return (-1);
    }

    /*
     * Normal mail delivery. May also send a delivery record to the user.
     * 
     * XXX DSN We write all recipients to the bounce logfile regardless of DSN
     * NOTIFY options, because those options don't apply to postmaster
     * notifications.
     */
    else {
	char   *my_status = mystrdup(my_dsn.status);
	const char *log_status = var_soft_bounce ? "SOFTBOUNCE" : "bounced";

	/*
	 * Supply default action.
	 */
	my_dsn.status = my_status;
	if (var_soft_bounce) {
	    my_status[0] = '4';
	    my_dsn.action = "delayed";
	} else {
	    my_dsn.action = "failed";
	}

	if (mail_command_client(MAIL_CLASS_PRIVATE, var_soft_bounce ?
				var_defer_service : var_bounce_service,
			   ATTR_TYPE_INT, MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND,
				ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
				ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
				ATTR_TYPE_FUNC, rcpt_print, (void *) rcpt,
				ATTR_TYPE_FUNC, dsn_print, (void *) &my_dsn,
				ATTR_TYPE_END) == 0
	    && ((flags & DEL_REQ_FLAG_RECORD) == 0
		|| trace_append(flags, id, stats, rcpt, relay,
				&my_dsn) == 0)) {
	    log_adhoc(id, stats, rcpt, relay, &my_dsn, log_status);
	    status = (var_soft_bounce ? -1 : 0);
	} else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
	    VSTRING *junk = vstring_alloc(100);

	    my_dsn.status = "4.3.0";
	    vstring_sprintf(junk, "%s or %s service failure",
			    var_bounce_service, var_trace_service);
	    my_dsn.reason = vstring_str(junk);
	    status = defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn);
	    vstring_free(junk);
	} else {
	    status = -1;
	}
	myfree(my_status);
	return (status);
    }
}