1/*++ 2/* NAME 3/* local_expand 3 4/* SUMMARY 5/* set up attribute list for $name expansion 6/* SYNOPSIS 7/* #include "local.h" 8/* 9/* int local_expand(result, pattern, state, usr_attr, filter) 10/* VSTRING *result; 11/* const char *pattern; 12/* LOCAL_STATE state; 13/* USER_ATTR usr_attr; 14/* const char *filter; 15/* DESCRIPTION 16/* local_expand() performs conditional and unconditional $name 17/* expansion based on message delivery attributes. 18/* The result is the bitwise OR or zero or more of the following: 19/* .IP LOCAL_EXP_EXTENSION_MATCHED 20/* The result of expansion contains the $extension attribute. 21/* .IP MAC_PARSE_XXX 22/* See mac_parse(3). 23/* .PP 24/* Attributes: 25/* .IP client_address 26/* The client network address. 27/* .IP client_helo 28/* The client HELO command parameter. 29/* .IP client_hostname 30/* The client hostname. 31/* .IP client_protocol 32/* The client protocol. 33/* .IP domain 34/* The recipient address domain. 35/* .IP extension 36/* The recipient address extension. 37/* .IP home 38/* The recipient home directory. 39/* .IP local 40/* The entire recipient address localpart. 41/* .IP recipient 42/* The entire recipient address. 43/* .IP recipient_delimiter 44/* The recipient delimiter. 45/* .IP shell 46/* The recipient shell program. 47/* .IP sasl_method 48/* The SASL authentication method. 49/* .IP sasl_sender 50/* The SASL MAIL FROM address. 51/* .IP sasl_username 52/* The SASL login name. 53/* .IP user 54/* The recipient user name. 55/* .PP 56/* Arguments: 57/* .IP result 58/* Storage for the result of expansion. The buffer is truncated 59/* upon entry. 60/* .IP pattern 61/* The string with unconditional and conditional macro expansions. 62/* .IP state 63/* Message delivery attributes (sender, recipient etc.). 64/* Attributes describing alias, include or forward expansion. 65/* A table with the results from expanding aliases or lists. 66/* A table with delivered-to: addresses taken from the message. 67/* .IP usr_attr 68/* Attributes describing user rights and environment. 69/* .IP filter 70/* A null pointer, or a string of allowed characters in $name 71/* expansions. Illegal characters are replaced by underscores. 72/* DIAGNOSTICS 73/* Fatal errors: out of memory. 74/* SEE ALSO 75/* mac_expand(3) macro expansion 76/* LICENSE 77/* .ad 78/* .fi 79/* The Secure Mailer license must be distributed with this software. 80/* AUTHOR(S) 81/* Wietse Venema 82/* IBM T.J. Watson Research 83/* P.O. Box 704 84/* Yorktown Heights, NY 10598, USA 85/*--*/ 86 87/* System library. */ 88 89#include <sys_defs.h> 90#include <string.h> 91 92/* Utility library. */ 93 94#include <vstring.h> 95#include <mac_expand.h> 96 97/* Global library */ 98 99#include <mail_params.h> 100 101/* Application-specific. */ 102 103#include "local.h" 104 105typedef struct { 106 LOCAL_STATE *state; 107 USER_ATTR *usr_attr; 108 int status; 109} LOCAL_EXP; 110 111/* local_expand_lookup - mac_expand() lookup routine */ 112 113static const char *local_expand_lookup(const char *name, int mode, char *ptr) 114{ 115 LOCAL_EXP *local = (LOCAL_EXP *) ptr; 116 static char rcpt_delim[2]; 117 118#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) 119 120 if (STREQ(name, "user")) { 121 return (local->state->msg_attr.user); 122 } else if (STREQ(name, "home")) { 123 return (local->usr_attr->home); 124 } else if (STREQ(name, "shell")) { 125 return (local->usr_attr->shell); 126 } else if (STREQ(name, "domain")) { 127 return (local->state->msg_attr.domain); 128 } else if (STREQ(name, "local")) { 129 return (local->state->msg_attr.local); 130 } else if (STREQ(name, "mailbox")) { 131 return (local->state->msg_attr.local); 132 } else if (STREQ(name, "recipient")) { 133 return (local->state->msg_attr.rcpt.address); 134 } else if (STREQ(name, "extension")) { 135 if (mode == MAC_EXP_MODE_USE) 136 local->status |= LOCAL_EXP_EXTENSION_MATCHED; 137 return (local->state->msg_attr.extension); 138 } else if (STREQ(name, "recipient_delimiter")) { 139 rcpt_delim[0] = 140 local->state->msg_attr.local[strlen(local->state->msg_attr.user)]; 141 rcpt_delim[1] = 0; 142 return (rcpt_delim[0] ? rcpt_delim : 0); 143#if 0 144 } else if (STREQ(name, "client_hostname")) { 145 return (local->state->msg_attr.request->client_name); 146 } else if (STREQ(name, "client_address")) { 147 return (local->state->msg_attr.request->client_addr); 148 } else if (STREQ(name, "client_protocol")) { 149 return (local->state->msg_attr.request->client_proto); 150 } else if (STREQ(name, "client_helo")) { 151 return (local->state->msg_attr.request->client_helo); 152 } else if (STREQ(name, "sasl_method")) { 153 return (local->state->msg_attr.request->sasl_method); 154 } else if (STREQ(name, "sasl_sender")) { 155 return (local->state->msg_attr.request->sasl_sender); 156 } else if (STREQ(name, "sasl_username")) { 157 return (local->state->msg_attr.request->sasl_username); 158#endif 159 } else { 160 return (0); 161 } 162} 163 164/* local_expand - expand message delivery attributes */ 165 166int local_expand(VSTRING *result, const char *pattern, 167 LOCAL_STATE *state, USER_ATTR *usr_attr, const char *filter) 168{ 169 LOCAL_EXP local; 170 int expand_status; 171 172 local.state = state; 173 local.usr_attr = usr_attr; 174 local.status = 0; 175 expand_status = mac_expand(result, pattern, MAC_EXP_FLAG_NONE, 176 filter, local_expand_lookup, (char *) &local); 177 return (local.status | expand_status); 178} 179