Esempio n. 1
0
int     main(int argc, char **argv)
{
    VSTRING *buffer = vstring_alloc(100);
    MAPS   *path;
    ARGV   *result;

    /*
     * Parse JCL.
     */
    if (argc != 2)
	msg_fatal("usage: %s database", argv[0]);

    /*
     * Initialize.
     */
#define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); }

    mail_conf_read();
    msg_verbose = 1;
    if (chdir(var_queue_dir) < 0)
	msg_fatal("chdir %s: %m", var_queue_dir);
    path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
    while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
	msg_info("=== Address extension on, extension propagation on ===");
	UPDATE(var_rcpt_delim, "+");
	if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
	    argv_free(result);
	msg_info("=== Address extension on, extension propagation off ===");
	if ((result = mail_addr_map(path, STR(buffer), 0)) != 0)
	    argv_free(result);
	msg_info("=== Address extension off ===");
	UPDATE(var_rcpt_delim, "");
	if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
	    argv_free(result);
    }
    vstring_free(buffer);
    maps_free(path);
    return (0);
}
Esempio n. 2
0
int     cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
			               MAPS *maps, int propagate)
{
    int     count;
    int     expand_to_self;
    ARGV   *new_addr;
    char   *saved_addr;
    int     did_rewrite = 0;

    /*
     * Produce sensible output even in the face of a recoverable error. This
     * simplifies error recovery considerably because we can do delayed error
     * checking in one place, instead of having error handling code all over
     * the place.
     */
    for (count = 0; count < MAX_RECURSION; count++) {
	if ((new_addr = mail_addr_map(maps, STR(addr), propagate)) != 0) {
	    if (new_addr->argc > 1)
		msg_warn("%s: multi-valued %s entry for %s",
			 state->queue_id, maps->title, STR(addr));
	    saved_addr = mystrdup(STR(addr));
	    did_rewrite |= strcmp(new_addr->argv[0], STR(addr));
	    vstring_strcpy(addr, new_addr->argv[0]);
	    expand_to_self = !strcasecmp_utf8(saved_addr, STR(addr));
	    myfree(saved_addr);
	    argv_free(new_addr);
	    if (expand_to_self)
		return (did_rewrite);
	} else if (maps->error != 0) {
	    msg_warn("%s: %s map lookup problem for %s -- "
		     "message not accepted, try again later",
		     state->queue_id, maps->title, STR(addr));
	    state->errs |= CLEANUP_STAT_WRITE;
	    return (did_rewrite);
	} else {
	    return (did_rewrite);
	}
    }
    msg_warn("%s: unreasonable %s map nesting for %s -- "
	     "message not accepted, try again later",
	     state->queue_id, maps->title, STR(addr));
    return (did_rewrite);
}
Esempio n. 3
0
int     smtp_map11_external(VSTRING *addr, MAPS *maps, int propagate)
{
    const char *myname = "smtp_map11_external";
    ARGV   *new_addr;
    const char *result;

    if ((new_addr = mail_addr_map(maps, STR(addr), propagate)) != 0) {
	if (new_addr->argc > 1)
	    msg_warn("multi-valued %s result for %s", maps->title, STR(addr));
	result = new_addr->argv[0];
	if (msg_verbose)
	    msg_info("%s: %s -> %s", myname, STR(addr), result);
	vstring_strcpy(addr, result);
	argv_free(new_addr);
	return (1);
    } else {
	if (maps->error != 0)
	    msg_fatal("%s map lookup problem for %s", maps->title, STR(addr));
	if (msg_verbose)
	    msg_info("%s: %s not found", myname, STR(addr));
	return (0);
    }
}
Esempio n. 4
0
ARGV   *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
			               MAPS *maps, int propagate)
{
    ARGV   *argv;
    ARGV   *lookup;
    int     count;
    int     i;
    int     arg;
    BH_TABLE *been_here;
    char   *saved_lhs;

    /*
     * Initialize.
     */
    argv = argv_alloc(1);
    argv_add(argv, addr, ARGV_END);
    argv_terminate(argv);
    been_here = been_here_init(0, BH_FLAG_FOLD);

    /*
     * Rewrite the address vector in place. With each map lookup result,
     * split it into separate addresses, then rewrite and flatten each
     * address, and repeat the process. Beware: argv is being changed, so we
     * must index the array explicitly, instead of running along it with a
     * pointer.
     */
#define UPDATE(ptr,new)	do { \
	if (ptr) myfree(ptr); ptr = mystrdup(new); \
    } while (0)
#define STR	vstring_str
#define RETURN(x) do { \
	been_here_free(been_here); return (x); \
    } while (0)
#define UNEXPAND(argv, addr) do { \
	argv_truncate((argv), 0); argv_add((argv), (addr), (char *) 0); \
    } while (0)

    for (arg = 0; arg < argv->argc; arg++) {
	if (argv->argc > var_virt_expan_limit) {
	    msg_warn("%s: unreasonable %s map expansion size for %s -- "
		     "message not accepted, try again later",
		     state->queue_id, maps->title, addr);
	    state->errs |= CLEANUP_STAT_DEFER;
	    UPDATE(state->reason, "4.6.0 Alias expansion error");
	    UNEXPAND(argv, addr);
	    RETURN(argv);
	}
	for (count = 0; /* void */ ; count++) {

	    /*
	     * Don't expand an address that already expanded into itself.
	     */
	    if (been_here_check_fixed(been_here, argv->argv[arg]) != 0)
		break;
	    if (count >= var_virt_recur_limit) {
		msg_warn("%s: unreasonable %s map nesting for %s -- "
			 "message not accepted, try again later",
			 state->queue_id, maps->title, addr);
		state->errs |= CLEANUP_STAT_DEFER;
		UPDATE(state->reason, "4.6.0 Alias expansion error");
		UNEXPAND(argv, addr);
		RETURN(argv);
	    }
	    quote_822_local(state->temp1, argv->argv[arg]);
	    if ((lookup = mail_addr_map(maps, STR(state->temp1), propagate)) != 0) {
		saved_lhs = mystrdup(argv->argv[arg]);
		for (i = 0; i < lookup->argc; i++) {
		    unquote_822_local(state->temp1, lookup->argv[i]);
		    if (i == 0) {
			UPDATE(argv->argv[arg], STR(state->temp1));
		    } else {
			argv_add(argv, STR(state->temp1), ARGV_END);
			argv_terminate(argv);
		    }

		    /*
		     * Allow an address to expand into itself once.
		     */
		    if (strcasecmp(saved_lhs, STR(state->temp1)) == 0)
			been_here_fixed(been_here, saved_lhs);
		}
		myfree(saved_lhs);
		argv_free(lookup);
	    } else if (maps->error != 0) {
		msg_warn("%s: %s map lookup problem for %s -- "
			 "message not accepted, try again later",
			 state->queue_id, maps->title, addr);
		state->errs |= CLEANUP_STAT_WRITE;
		UPDATE(state->reason, "4.6.0 Alias expansion error");
		UNEXPAND(argv, addr);
		RETURN(argv);
	    } else {
		break;
	    }
	}
    }
    RETURN(argv);
}