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 */ 35typedef 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 */ 68typedef 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 const char *sender; /* taken from envelope */ 76 char *dsn_envid; /* DSN envelope ID */ 77 int dsn_ret; /* DSN headers/full */ 78 RECIPIENT rcpt; /* from delivery request */ 79 char *domain; /* recipient domain */ 80 char *local; /* recipient full localpart */ 81 char *user; /* recipient localpart, base name */ 82 char *extension; /* recipient localpart, extension */ 83 char *unmatched; /* unmatched extension */ 84 const char *owner; /* null or list owner */ 85 const char *delivered; /* for loop detection */ 86 char *relay; /* relay host */ 87 MSG_STATS msg_stats; /* time profile */ 88 int exp_type; /* expansion type. see below */ 89 char *exp_from; /* expanded_from */ 90 DELIVER_REQUEST *request; /* the kitchen sink */ 91 DSN_BUF *why; /* delivery status */ 92} DELIVER_ATTR; 93 94extern void deliver_attr_init(DELIVER_ATTR *); 95extern void deliver_attr_dump(DELIVER_ATTR *); 96extern void deliver_attr_free(DELIVER_ATTR *); 97 98#define EXPAND_TYPE_ALIAS (1<<0) 99#define EXPAND_TYPE_FWD (1<<1) 100#define EXPAND_TYPE_INCL (1<<2) 101 102 /* 103 * Rather than schlepping around dozens of arguments, here is one that has 104 * all. Well, almost. The user attributes are just a bit too sensitive, so 105 * they are passed around separately. 106 */ 107typedef struct LOCAL_STATE { 108 int level; /* nesting level, for logging */ 109 DELIVER_ATTR msg_attr; /* message attributes */ 110 BH_TABLE *dup_filter; /* internal duplicate filter */ 111 DELIVERED_HDR_INFO *loop_info; /* external loop filter */ 112 DELIVER_REQUEST *request; /* as from queue manager */ 113} LOCAL_STATE; 114 115#define RESET_OWNER_ATTR(msg_attr, level) { \ 116 msg_attr.owner = 0; \ 117 if (msg_verbose) \ 118 msg_info("%s[%d]: reset owner attr", myname, level); \ 119 } 120 121#define SET_OWNER_ATTR(msg_attr, who, level) { \ 122 msg_attr.sender = msg_attr.owner = who; \ 123 if (msg_verbose) \ 124 msg_info("%s[%d]: set owner attr: %s", \ 125 myname, level, who); \ 126 } 127 128 /* 129 * Bundle up some often-user attributes. 130 */ 131#define BOUNCE_FLAGS(request) DEL_REQ_TRACE_FLAGS((request)->flags) 132 133#define BOUNCE_ATTR(attr) \ 134 attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ 135 DSN_FROM_DSN_BUF(attr.why) 136#define BOUNCE_ONE_ATTR(attr) \ 137 attr.queue_name, attr.queue_id, attr.encoding, \ 138 attr.sender, attr.dsn_envid, attr.dsn_ret, \ 139 &attr.msg_stats, &attr.rcpt, attr.relay, \ 140 DSN_FROM_DSN_BUF(attr.why) 141#define SENT_ATTR(attr) \ 142 attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ 143 DSN_FROM_DSN_BUF(attr.why) 144#define OPENED_ATTR(attr) \ 145 attr.queue_id, attr.sender 146#define COPY_ATTR(attr) \ 147 attr.sender, attr.rcpt.orig_addr, attr.delivered, attr.fp 148 149#define MSG_LOG_STATE(m, p) \ 150 msg_info("%s[%d]: local %s recip %s exten %s deliver %s exp_from %s", \ 151 m, \ 152 p.level, \ 153 p.msg_attr.local ? p.msg_attr.local : "" , \ 154 p.msg_attr.rcpt.address ? p.msg_attr.rcpt.address : "", \ 155 p.msg_attr.extension ? p.msg_attr.extension : "", \ 156 p.msg_attr.delivered ? p.msg_attr.delivered : "", \ 157 p.msg_attr.exp_from ? p.msg_attr.exp_from : "") 158 159 /* 160 * "inner" nodes of the delivery graph. 161 */ 162extern int deliver_recipient(LOCAL_STATE, USER_ATTR); 163extern int deliver_alias(LOCAL_STATE, USER_ATTR, char *, int *); 164extern int deliver_dotforward(LOCAL_STATE, USER_ATTR, int *); 165extern int deliver_include(LOCAL_STATE, USER_ATTR, char *); 166extern int deliver_token(LOCAL_STATE, USER_ATTR, TOK822 *); 167extern int deliver_token_string(LOCAL_STATE, USER_ATTR, char *, int *); 168extern int deliver_token_stream(LOCAL_STATE, USER_ATTR, VSTREAM *, int *); 169extern int deliver_resolve_tree(LOCAL_STATE, USER_ATTR, TOK822 *); 170extern int deliver_resolve_addr(LOCAL_STATE, USER_ATTR, char *); 171 172 /* 173 * "leaf" nodes of the delivery graph. 174 */ 175extern int deliver_mailbox(LOCAL_STATE, USER_ATTR, int *); 176extern int deliver_command(LOCAL_STATE, USER_ATTR, const char *); 177extern int deliver_file(LOCAL_STATE, USER_ATTR, char *); 178extern int deliver_indirect(LOCAL_STATE); 179extern int deliver_maildir(LOCAL_STATE, USER_ATTR, char *); 180extern int deliver_unknown(LOCAL_STATE, USER_ATTR); 181 182 /* 183 * Restrictions on delivery to sensitive destinations. 184 */ 185extern int local_file_deliver_mask; 186extern int local_cmd_deliver_mask; 187 188 /* 189 * Restrictions on extension propagation. 190 */ 191extern int local_ext_prop_mask; 192 193 /* 194 * Mailbox lock protocol. 195 */ 196extern int local_mbox_lock_mask; 197 198 /* 199 * When to prepend a Delivered-To: header upon external delivery. 200 */ 201#define DELIVER_HDR_CMD (1<<0) 202#define DELIVER_HDR_FILE (1<<1) 203#define DELIVER_HDR_FWD (1<<2) 204 205extern int local_deliver_hdr_mask; 206 207 /* 208 * forward.c 209 */ 210extern int forward_init(void); 211extern int forward_append(DELIVER_ATTR); 212extern int forward_finish(DELIVER_REQUEST *, DELIVER_ATTR, int); 213 214 /* 215 * feature.c 216 */ 217extern int feature_control(const char *); 218 219 /* 220 * local_expand.c 221 */ 222int local_expand(VSTRING *, const char *, LOCAL_STATE *, USER_ATTR *, const char *); 223 224#define LOCAL_EXP_EXTENSION_MATCHED (1<<MAC_PARSE_USER) 225 226 /* 227 * alias.c 228 */ 229extern MAPS *alias_maps; 230 231 /* 232 * Silly little macros. 233 */ 234#define STR(s) vstring_str(s) 235 236 /* 237 * bounce_workaround.c 238 */ 239int bounce_workaround(LOCAL_STATE); 240 241/* LICENSE 242/* .ad 243/* .fi 244/* The Secure Mailer license must be distributed with this software. 245/* AUTHOR(S) 246/* Wietse Venema 247/* IBM T.J. Watson Research 248/* P.O. Box 704 249/* Yorktown Heights, NY 10598, USA 250/*--*/ 251