diff options
Diffstat (limited to 'src/local/local.h')
-rw-r--r-- | src/local/local.h | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/local/local.h b/src/local/local.h new file mode 100644 index 0000000..4052000 --- /dev/null +++ b/src/local/local.h @@ -0,0 +1,251 @@ +/*++ +/* NAME +/* local 3h +/* SUMMARY +/* local mail delivery +/* SYNOPSIS +/* #include "local.h" +/* DESCRIPTION +/* .nf + + /* + * Utility library. + */ +#include <htable.h> +#include <vstream.h> +#include <vstring.h> + + /* + * Global library. + */ +#include <been_here.h> +#include <tok822.h> +#include <deliver_request.h> +#include <mbox_conf.h> +#include <maps.h> +#include <dsn_buf.h> +#include <dsn.h> +#include <delivered_hdr.h> + + /* + * User attributes: these control the privileges for delivery to external + * commands, external files, or mailboxes, and the initial environment of + * external commands. + */ +typedef struct USER_ATTR { + uid_t uid; /* file/command access */ + gid_t gid; /* file/command access */ + char *home; /* null or home directory */ + char *logname; /* null or login name */ + char *shell; /* null or login shell */ +} USER_ATTR; + + /* + * Critical macros. Not for obscurity, but to ensure consistency. + */ +#define RESET_USER_ATTR(usr_attr, level) { \ + usr_attr.uid = 0; usr_attr.gid = 0; usr_attr.home = 0; \ + usr_attr.logname = 0; usr_attr.shell = 0; \ + if (msg_verbose) \ + msg_info("%s[%d]: reset user_attr", myname, level); \ + } + +#define SET_USER_ATTR(usr_attr, pwd, level) { \ + usr_attr.uid = pwd->pw_uid; usr_attr.gid = pwd->pw_gid; \ + usr_attr.home = pwd->pw_dir; usr_attr.logname = pwd->pw_name; \ + usr_attr.shell = pwd->pw_shell; \ + if (msg_verbose) \ + msg_info("%s[%d]: set user_attr: %s", \ + myname, level, pwd->pw_name); \ + } + + /* + * The delivery attributes are inherited from files, from aliases, and from + * whatnot. Some of the information is changed on the fly. DELIVER_ATTR + * structures are therefore passed by value, so there is no need to undo + * changes. + */ +typedef struct DELIVER_ATTR { + int level; /* recursion level */ + VSTREAM *fp; /* open queue file */ + char *queue_name; /* mail queue id */ + char *queue_id; /* mail queue id */ + long offset; /* data offset */ + char *encoding; /* MIME encoding */ + int smtputf8; /* from delivery request */ + const char *sender; /* taken from envelope */ + char *dsn_envid; /* DSN envelope ID */ + int dsn_ret; /* DSN headers/full */ + RECIPIENT rcpt; /* from delivery request */ + char *domain; /* recipient domain */ + char *local; /* recipient full localpart */ + char *user; /* recipient localpart, base name */ + char *extension; /* recipient localpart, extension */ + char *unmatched; /* unmatched extension */ + const char *owner; /* null or list owner */ + const char *delivered; /* for loop detection */ + char *relay; /* relay host */ + MSG_STATS msg_stats; /* time profile */ + int exp_type; /* expansion type. see below */ + char *exp_from; /* expanded_from */ + DELIVER_REQUEST *request; /* the kitchen sink */ + DSN_BUF *why; /* delivery status */ +} DELIVER_ATTR; + +extern void deliver_attr_init(DELIVER_ATTR *); +extern void deliver_attr_dump(DELIVER_ATTR *); +extern void deliver_attr_free(DELIVER_ATTR *); + +#define EXPAND_TYPE_ALIAS (1<<0) +#define EXPAND_TYPE_FWD (1<<1) +#define EXPAND_TYPE_INCL (1<<2) + + /* + * Rather than schlepping around dozens of arguments, here is one that has + * all. Well, almost. The user attributes are just a bit too sensitive, so + * they are passed around separately. + */ +typedef struct LOCAL_STATE { + int level; /* nesting level, for logging */ + DELIVER_ATTR msg_attr; /* message attributes */ + BH_TABLE *dup_filter; /* internal duplicate filter */ + DELIVERED_HDR_INFO *loop_info; /* external loop filter */ + DELIVER_REQUEST *request; /* as from queue manager */ +} LOCAL_STATE; + +#define RESET_OWNER_ATTR(msg_attr, level) { \ + msg_attr.owner = 0; \ + if (msg_verbose) \ + msg_info("%s[%d]: reset owner attr", myname, level); \ + } + +#define SET_OWNER_ATTR(msg_attr, who, level) { \ + msg_attr.sender = msg_attr.owner = who; \ + if (msg_verbose) \ + msg_info("%s[%d]: set owner attr: %s", \ + myname, level, who); \ + } + + /* + * Bundle up some often-user attributes. + */ +#define BOUNCE_FLAGS(request) DEL_REQ_TRACE_FLAGS((request)->flags) + +#define BOUNCE_ATTR(attr) \ + attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ + DSN_FROM_DSN_BUF(attr.why) +#define BOUNCE_ONE_ATTR(attr) \ + attr.queue_name, attr.queue_id, attr.encoding, attr.smtputf8, \ + attr.sender, attr.dsn_envid, attr.dsn_ret, \ + &attr.msg_stats, &attr.rcpt, attr.relay, \ + DSN_FROM_DSN_BUF(attr.why) +#define SENT_ATTR(attr) \ + attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \ + DSN_FROM_DSN_BUF(attr.why) +#define OPENED_ATTR(attr) \ + attr.queue_id, attr.sender +#define COPY_ATTR(attr) \ + attr.sender, attr.rcpt.orig_addr, attr.delivered, attr.fp + +#define MSG_LOG_STATE(m, p) \ + msg_info("%s[%d]: local %s recip %s exten %s deliver %s exp_from %s", \ + m, \ + p.level, \ + p.msg_attr.local ? p.msg_attr.local : "" , \ + p.msg_attr.rcpt.address ? p.msg_attr.rcpt.address : "", \ + p.msg_attr.extension ? p.msg_attr.extension : "", \ + p.msg_attr.delivered ? p.msg_attr.delivered : "", \ + p.msg_attr.exp_from ? p.msg_attr.exp_from : "") + + /* + * "inner" nodes of the delivery graph. + */ +extern int deliver_recipient(LOCAL_STATE, USER_ATTR); +extern int deliver_alias(LOCAL_STATE, USER_ATTR, char *, int *); +extern int deliver_dotforward(LOCAL_STATE, USER_ATTR, int *); +extern int deliver_include(LOCAL_STATE, USER_ATTR, char *); +extern int deliver_token(LOCAL_STATE, USER_ATTR, TOK822 *); +extern int deliver_token_string(LOCAL_STATE, USER_ATTR, char *, int *); +extern int deliver_token_stream(LOCAL_STATE, USER_ATTR, VSTREAM *, int *); +extern int deliver_resolve_tree(LOCAL_STATE, USER_ATTR, TOK822 *); +extern int deliver_resolve_addr(LOCAL_STATE, USER_ATTR, char *); + + /* + * "leaf" nodes of the delivery graph. + */ +extern int deliver_mailbox(LOCAL_STATE, USER_ATTR, int *); +extern int deliver_command(LOCAL_STATE, USER_ATTR, const char *); +extern int deliver_file(LOCAL_STATE, USER_ATTR, char *); +extern int deliver_indirect(LOCAL_STATE); +extern int deliver_maildir(LOCAL_STATE, USER_ATTR, char *); +extern int deliver_unknown(LOCAL_STATE, USER_ATTR); + + /* + * Restrictions on delivery to sensitive destinations. + */ +extern int local_file_deliver_mask; +extern int local_cmd_deliver_mask; + + /* + * Restrictions on extension propagation. + */ +extern int local_ext_prop_mask; + + /* + * Mailbox lock protocol. + */ +extern int local_mbox_lock_mask; + + /* + * When to prepend a Delivered-To: header upon external delivery. + */ +#define DELIVER_HDR_CMD (1<<0) +#define DELIVER_HDR_FILE (1<<1) +#define DELIVER_HDR_FWD (1<<2) + +extern int local_deliver_hdr_mask; + + /* + * forward.c + */ +extern int forward_init(void); +extern int forward_append(DELIVER_ATTR); +extern int forward_finish(DELIVER_REQUEST *, DELIVER_ATTR, int); + + /* + * feature.c + */ +extern int feature_control(const char *); + + /* + * local_expand.c + */ +int local_expand(VSTRING *, const char *, LOCAL_STATE *, USER_ATTR *, const char *); + +#define LOCAL_EXP_EXTENSION_MATCHED (1<<MAC_PARSE_USER) + + /* + * alias.c + */ +extern MAPS *alias_maps; + + /* + * Silly little macros. + */ +#define STR(s) vstring_str(s) + + /* + * bounce_workaround.c + */ +int bounce_workaround(LOCAL_STATE); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ |