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