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