diff options
Diffstat (limited to 'src/local/local_expand.c')
-rw-r--r-- | src/local/local_expand.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/local/local_expand.c b/src/local/local_expand.c new file mode 100644 index 0000000..ff9c3d6 --- /dev/null +++ b/src/local/local_expand.c @@ -0,0 +1,180 @@ +/*++ +/* 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)]; + if (rcpt_delim[0] == 0) + rcpt_delim[0] = var_rcpt_delim[0]; + 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); +} |