Home | History | Annotate | Line # | Download | only in local
      1 /*	$NetBSD: local.h,v 1.4 2026/05/09 18:49:17 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     sendopts;			/* 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 	NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
    139 #define BOUNCE_ONE_ATTR(attr) \
    140 	attr.queue_name, attr.queue_id, attr.encoding, attr.sendopts, \
    141 	attr.sender, attr.dsn_envid, attr.dsn_ret, \
    142 	&attr.msg_stats, &attr.rcpt, attr.relay, \
    143 	NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
    144 #define SENT_ATTR(attr) \
    145 	attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
    146 	NO_TLS_STATS, 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