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