1 /* $NetBSD: local_expand.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */ 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 107 typedef 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 115 static const char *local_expand_lookup(const char *name, int mode, void *ptr) 116 { 117 LOCAL_EXP *local = (LOCAL_EXP *) ptr; 118 static char rcpt_delim[2]; 119 120 #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) 121 122 if (STREQ(name, "user")) { 123 return (local->state->msg_attr.user); 124 } else if (STREQ(name, "home")) { 125 return (local->usr_attr->home); 126 } else if (STREQ(name, "shell")) { 127 return (local->usr_attr->shell); 128 } else if (STREQ(name, "domain")) { 129 return (local->state->msg_attr.domain); 130 } else if (STREQ(name, "local")) { 131 return (local->state->msg_attr.local); 132 } else if (STREQ(name, "mailbox")) { 133 return (local->state->msg_attr.local); 134 } else if (STREQ(name, "recipient")) { 135 return (local->state->msg_attr.rcpt.address); 136 } else if (STREQ(name, "extension")) { 137 if (mode == MAC_EXP_MODE_USE) 138 local->status |= LOCAL_EXP_EXTENSION_MATCHED; 139 return (local->state->msg_attr.extension); 140 } else if (STREQ(name, "recipient_delimiter")) { 141 rcpt_delim[0] = 142 local->state->msg_attr.local[strlen(local->state->msg_attr.user)]; 143 rcpt_delim[1] = 0; 144 return (rcpt_delim[0] ? rcpt_delim : 0); 145 #if 0 146 } else if (STREQ(name, "client_hostname")) { 147 return (local->state->msg_attr.request->client_name); 148 } else if (STREQ(name, "client_address")) { 149 return (local->state->msg_attr.request->client_addr); 150 } else if (STREQ(name, "client_protocol")) { 151 return (local->state->msg_attr.request->client_proto); 152 } else if (STREQ(name, "client_helo")) { 153 return (local->state->msg_attr.request->client_helo); 154 } else if (STREQ(name, "sasl_method")) { 155 return (local->state->msg_attr.request->sasl_method); 156 } else if (STREQ(name, "sasl_sender")) { 157 return (local->state->msg_attr.request->sasl_sender); 158 } else if (STREQ(name, "sasl_username")) { 159 return (local->state->msg_attr.request->sasl_username); 160 #endif 161 } else { 162 return (0); 163 } 164 } 165 166 /* local_expand - expand message delivery attributes */ 167 168 int local_expand(VSTRING *result, const char *pattern, 169 LOCAL_STATE *state, USER_ATTR *usr_attr, const char *filter) 170 { 171 LOCAL_EXP local; 172 int expand_status; 173 174 local.state = state; 175 local.usr_attr = usr_attr; 176 local.status = 0; 177 expand_status = mac_expand(result, pattern, MAC_EXP_FLAG_NONE, 178 filter, local_expand_lookup, (void *) &local); 179 return (local.status | expand_status); 180 } 181