/* $NetBSD: local_expand.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */
/*++
/* NAME
/* local_expand 3
/* SUMMARY
/* set up attribute list for $name expansion
/* SYNOPSIS
/* #include "local.h"
/*
/* int local_expand(result, pattern, state, usr_attr, filter)
/* VSTRING *result;
/* const char *pattern;
/* LOCAL_STATE state;
/* USER_ATTR usr_attr;
/* const char *filter;
/* DESCRIPTION
/* local_expand() performs conditional and unconditional $name
/* expansion based on message delivery attributes.
/* The result is the bitwise OR or zero or more of the following:
/* .IP LOCAL_EXP_EXTENSION_MATCHED
/* The result of expansion contains the $extension attribute.
/* .IP MAC_PARSE_XXX
/* See mac_parse(3).
/* .PP
/* Attributes:
/* .IP client_address
/* The client network address.
/* .IP client_helo
/* The client HELO command parameter.
/* .IP client_hostname
/* The client hostname.
/* .IP client_protocol
/* The client protocol.
/* .IP domain
/* The recipient address domain.
/* .IP extension
/* The recipient address extension.
/* .IP home
/* The recipient home directory.
/* .IP local
/* The entire recipient address localpart.
/* .IP recipient
/* The entire recipient address.
/* .IP recipient_delimiter
/* The recipient delimiter.
/* .IP shell
/* The recipient shell program.
/* .IP sasl_method
/* The SASL authentication method.
/* .IP sasl_sender
/* The SASL MAIL FROM address.
/* .IP sasl_username
/* The SASL login name.
/* .IP user
/* The recipient user name.
/* .PP
/* Arguments:
/* .IP result
/* Storage for the result of expansion. The buffer is truncated
/* upon entry.
/* .IP pattern
/* The string with unconditional and conditional macro expansions.
/* .IP state
/* Message delivery attributes (sender, recipient etc.).
/* Attributes describing alias, include or forward expansion.
/* A table with the results from expanding aliases or lists.
/* A table with delivered-to: addresses taken from the message.
/* .IP usr_attr
/* Attributes describing user rights and environment.
/* .IP filter
/* A null pointer, or a string of allowed characters in $name
/* expansions. Illegal characters are replaced by underscores.
/* DIAGNOSTICS
/* Fatal errors: out of memory.
/* SEE ALSO
/* mac_expand(3) macro expansion
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <string.h>
/* Utility library. */
#include <vstring.h>
#include <mac_expand.h>
/* Global library */
#include <mail_params.h>
/* Application-specific. */
#include "local.h"
typedef struct {
LOCAL_STATE *state;
USER_ATTR *usr_attr;
int status;
} LOCAL_EXP;
/* local_expand_lookup - mac_expand() lookup routine */
static const char *local_expand_lookup(const char *name, int mode, void *ptr)
{
LOCAL_EXP *local = (LOCAL_EXP *) ptr;
static char rcpt_delim[2];
#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
if (STREQ(name, "user")) {
return (local->state->msg_attr.user);
} else if (STREQ(name, "home")) {
return (local->usr_attr->home);
} else if (STREQ(name, "shell")) {
return (local->usr_attr->shell);
} else if (STREQ(name, "domain")) {
return (local->state->msg_attr.domain);
} else if (STREQ(name, "local")) {
return (local->state->msg_attr.local);
} else if (STREQ(name, "mailbox")) {
return (local->state->msg_attr.local);
} else if (STREQ(name, "recipient")) {
return (local->state->msg_attr.rcpt.address);
} else if (STREQ(name, "extension")) {
if (mode == MAC_EXP_MODE_USE)
local->status |= LOCAL_EXP_EXTENSION_MATCHED;
return (local->state->msg_attr.extension);
} else if (STREQ(name, "recipient_delimiter")) {
rcpt_delim[0] =
local->state->msg_attr.local[strlen(local->state->msg_attr.user)];
rcpt_delim[1] = 0;
return (rcpt_delim[0] ? rcpt_delim : 0);
#if 0
} else if (STREQ(name, "client_hostname")) {
return (local->state->msg_attr.request->client_name);
} else if (STREQ(name, "client_address")) {
return (local->state->msg_attr.request->client_addr);
} else if (STREQ(name, "client_protocol")) {
return (local->state->msg_attr.request->client_proto);
} else if (STREQ(name, "client_helo")) {
return (local->state->msg_attr.request->client_helo);
} else if (STREQ(name, "sasl_method")) {
return (local->state->msg_attr.request->sasl_method);
} else if (STREQ(name, "sasl_sender")) {
return (local->state->msg_attr.request->sasl_sender);
} else if (STREQ(name, "sasl_username")) {
return (local->state->msg_attr.request->sasl_username);
#endif
} else {
return (0);
}
}
/* local_expand - expand message delivery attributes */
int local_expand(VSTRING *result, const char *pattern,
LOCAL_STATE *state, USER_ATTR *usr_attr, const char *filter)
{
LOCAL_EXP local;
int expand_status;
local.state = state;
local.usr_attr = usr_attr;
local.status = 0;
expand_status = mac_expand(result, pattern, MAC_EXP_FLAG_NONE,
filter, local_expand_lookup, (void *) &local);
return (local.status | expand_status);
}