1 /*++ 2 /* NAME 3 /* local 3h 4 /* SUMMARY 5 /* local mail delivery 6 /* SYNOPSIS 7 /* #include "local.h" 8 /* DESCRIPTION 9 /* .nf 10 11 /* 12 * Utility library. 13 */ 14 #include <htable.h> 15 #include <vstream.h> 16 #include <vstring.h> 17 18 /* 19 * Global library. 20 */ 21 #include <been_here.h> 22 #include <tok822.h> 23 #include <deliver_request.h> 24 #include <mbox_conf.h> 25 #include <maps.h> 26 #include <dsn_buf.h> 27 #include <dsn.h> 28 #include <delivered_hdr.h> 29 30 /* 31 * User attributes: these control the privileges for delivery to external 32 * commands, external files, or mailboxes, and the initial environment of 33 * external commands. 34 */ 35 typedef struct USER_ATTR { 36 uid_t uid; /* file/command access */ 37 gid_t gid; /* file/command access */ 38 char *home; /* null or home directory */ 39 char *logname; /* null or login name */ 40 char *shell; /* null or login shell */ 41 } USER_ATTR; 42 43 /* 44 * Critical macros. Not for obscurity, but to ensure consistency. 45 */ 46 #define RESET_USER_ATTR(usr_attr, level) { \ 47 usr_attr.uid = 0; usr_attr.gid = 0; usr_attr.home = 0; \ 48 usr_attr.logname = 0; usr_attr.shell = 0; \ 49 if (msg_verbose) \ 50 msg_info("%s[%d]: reset user_attr", myname, level); \ 51 } 52 53 #define SET_USER_ATTR(usr_attr, pwd, level) { \ 54 usr_attr.uid = pwd->pw_uid; usr_attr.gid = pwd->pw_gid; \ 55 usr_attr.home = pwd->pw_dir; usr_attr.logname = pwd->pw_name; \ 56 usr_attr.shell = pwd->pw_shell; \ 57 if (msg_verbose) \ 58 msg_info("%s[%d]: set user_attr: %s", \ 59 myname, level, pwd->pw_name); \ 60 } 61 62 /* 63 * The delivery attributes are inherited from files, from aliases, and from 64 * whatnot. Some of the information is changed on the fly. DELIVER_ATTR 65 * structures are therefore passed by value, so there is no need to undo 66 * changes. 67 */ 68 typedef struct DELIVER_ATTR { 69 int level; /* recursion level */ 70 VSTREAM *fp; /* open queue file */ 71 char *queue_name; /* mail queue id */ 72 char *queue_id; /* mail queue id */ 73 long offset; /* data offset */ 74 char *encoding; /* MIME encoding */ 75 int smtputf8; /* from delivery request */ 76 const char *sender; /* taken from envelope */ 77 char *dsn_envid; /* DSN envelope ID */ 78 int dsn_ret; /* DSN headers/full */ 79 RECIPIENT rcpt; /* from delivery request */ 80 char *domain; /* recipient domain */ 81 char *local; /* recipient full localpart */ 82 char *user; /* recipient localpart, base name */ 83 char *extension; /* recipient localpart, extension */ 84 char *unmatched; /* unmatched extension */ 85 const char *owner; /* null or list owner */ 86 const char *delivered; /* for loop detection */ 87 char *relay; /* relay host */ 88 MSG_STATS msg_stats; /* time profile */ 89 int exp_type; /* expansion type. see below */ 90 char *exp_from; /* expanded_from */ 91 DELIVER_REQUEST *request; /* the kitchen sink */ 92 DSN_BUF *why; /* delivery status */ 93 } DELIVER_ATTR; 94 95 extern void deliver_attr_init(DELIVER_ATTR *); 96 extern void deliver_attr_dump(DELIVER_ATTR *); 97 extern void deliver_attr_free(DELIVER_ATTR *); 98 99 #define EXPAND_TYPE_ALIAS (1<<0) 100 #define EXPAND_TYPE_FWD (1<<1) 101 #define EXPAND_TYPE_INCL (1<<2) 102 103 /* 104 * Rather than schlepping around dozens of arguments, here is one that has 105 * all. Well, almost. The user attributes are just a bit too sensitive, so 106 * they are passed around separately. 107 */ 108 typedef struct LOCAL_STATE { 109 int level; /* nesting level, for logging */ 110 DELIVER_ATTR msg_attr; /* message attributes */ 111 BH_TABLE *dup_filter; /* internal duplicate filter */ 112 DELIVERED_HDR_INFO *loop_info; /* external loop filter */ 113 DELIVER_REQUEST *request; /* as from queue manager */ 114 } LOCAL_STATE; 115 116 #define RESET_OWNER_ATTR(msg_attr, level) { \ 117 msg_attr.owner = 0; \ 118 if (msg_verbose) \ 119 msg_info("%s[%d]: reset owner attr", myname, level); \ 120 } 121 122 #define SET_OWNER_ATTR(msg_attr, who, level) { \ 123 msg_attr.sender = msg_attr.owner = who; \ 124 if (msg_verbose) \ 125 msg_info("%s[%d]: set owner attr: %s", \ 126 myname, level, who); \ 127 } 128 129 /* 130 * Bundle up some often-user attributes. 131 */ 132 #define BOUNCE_FLAGS(request) DEL_REQ_TRACE_FLAGS((request)->flags) 133 134 #define BOUNCE_ATTR(attr) \ 135 attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ 136 DSN_FROM_DSN_BUF(attr.why) 137 #define BOUNCE_ONE_ATTR(attr) \ 138 attr.queue_name, attr.queue_id, attr.encoding, attr.smtputf8, \ 139 attr.sender, attr.dsn_envid, attr.dsn_ret, \ 140 &attr.msg_stats, &attr.rcpt, attr.relay, \ 141 DSN_FROM_DSN_BUF(attr.why) 142 #define SENT_ATTR(attr) \ 143 attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ 144 DSN_FROM_DSN_BUF(attr.why) 145 #define OPENED_ATTR(attr) \ 146 attr.queue_id, attr.sender 147 #define COPY_ATTR(attr) \ 148 attr.sender, attr.rcpt.orig_addr, attr.delivered, attr.fp 149 150 #define MSG_LOG_STATE(m, p) \ 151 msg_info("%s[%d]: local %s recip %s exten %s deliver %s exp_from %s", \ 152 m, \ 153 p.level, \ 154 p.msg_attr.local ? p.msg_attr.local : "" , \ 155 p.msg_attr.rcpt.address ? p.msg_attr.rcpt.address : "", \ 156 p.msg_attr.extension ? p.msg_attr.extension : "", \ 157 p.msg_attr.delivered ? p.msg_attr.delivered : "", \ 158 p.msg_attr.exp_from ? p.msg_attr.exp_from : "") 159 160 /* 161 * "inner" nodes of the delivery graph. 162 */ 163 extern int deliver_recipient(LOCAL_STATE, USER_ATTR); 164 extern int deliver_alias(LOCAL_STATE, USER_ATTR, char *, int *); 165 extern int deliver_dotforward(LOCAL_STATE, USER_ATTR, int *); 166 extern int deliver_include(LOCAL_STATE, USER_ATTR, char *); 167 extern int deliver_token(LOCAL_STATE, USER_ATTR, TOK822 *); 168 extern int deliver_token_string(LOCAL_STATE, USER_ATTR, char *, int *); 169 extern int deliver_token_stream(LOCAL_STATE, USER_ATTR, VSTREAM *, int *); 170 extern int deliver_resolve_tree(LOCAL_STATE, USER_ATTR, TOK822 *); 171 extern int deliver_resolve_addr(LOCAL_STATE, USER_ATTR, char *); 172 173 /* 174 * "leaf" nodes of the delivery graph. 175 */ 176 extern int deliver_mailbox(LOCAL_STATE, USER_ATTR, int *); 177 extern int deliver_command(LOCAL_STATE, USER_ATTR, const char *); 178 extern int deliver_file(LOCAL_STATE, USER_ATTR, char *); 179 extern int deliver_indirect(LOCAL_STATE); 180 extern int deliver_maildir(LOCAL_STATE, USER_ATTR, char *); 181 extern int deliver_unknown(LOCAL_STATE, USER_ATTR); 182 183 /* 184 * Restrictions on delivery to sensitive destinations. 185 */ 186 extern int local_file_deliver_mask; 187 extern int local_cmd_deliver_mask; 188 189 /* 190 * Restrictions on extension propagation. 191 */ 192 extern int local_ext_prop_mask; 193 194 /* 195 * Mailbox lock protocol. 196 */ 197 extern int local_mbox_lock_mask; 198 199 /* 200 * When to prepend a Delivered-To: header upon external delivery. 201 */ 202 #define DELIVER_HDR_CMD (1<<0) 203 #define DELIVER_HDR_FILE (1<<1) 204 #define DELIVER_HDR_FWD (1<<2) 205 206 extern int local_deliver_hdr_mask; 207 208 /* 209 * forward.c 210 */ 211 extern int forward_init(void); 212 extern int forward_append(DELIVER_ATTR); 213 extern int forward_finish(DELIVER_REQUEST *, DELIVER_ATTR, int); 214 215 /* 216 * feature.c 217 */ 218 extern int feature_control(const char *); 219 220 /* 221 * local_expand.c 222 */ 223 int local_expand(VSTRING *, const char *, LOCAL_STATE *, USER_ATTR *, const char *); 224 225 #define LOCAL_EXP_EXTENSION_MATCHED (1<<MAC_PARSE_USER) 226 227 /* 228 * alias.c 229 */ 230 extern MAPS *alias_maps; 231 232 /* 233 * Silly little macros. 234 */ 235 #define STR(s) vstring_str(s) 236 237 /* 238 * bounce_workaround.c 239 */ 240 int bounce_workaround(LOCAL_STATE); 241 242 /* LICENSE 243 /* .ad 244 /* .fi 245 /* The Secure Mailer license must be distributed with this software. 246 /* AUTHOR(S) 247 /* Wietse Venema 248 /* IBM T.J. Watson Research 249 /* P.O. Box 704 250 /* Yorktown Heights, NY 10598, USA 251 /*--*/ 252