masqmail

view src/masqmail.h @ 378:5781ba87df95

Removed ident. This had been discussed on the mailing list in Oct 2011. Ident is hardly useful in typical setups for masqmail. Probably Oliver had used it in his setup; that would make sense. Now, I know of nobody who needs it.
author markus schnalke <meillo@marmaro.de>
date Sat, 14 Jan 2012 21:36:58 +0100
parents b27f66555ba8
children a408411ff8df
line source
1 /*
2 ** MasqMail
3 ** Copyright (C) 1999-2001 Oliver Kurth
4 ** Copyright (C) 2010 markus schnalke <meillo@marmaro.de>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 #include <config.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <time.h>
34 #include <sys/time.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <netdb.h>
38 #include <syslog.h>
39 #include <signal.h>
40 #include <fcntl.h>
42 #include <glib.h>
44 #include "lookup.h"
46 typedef struct _interface {
47 gchar *address;
48 gint port;
49 } interface;
51 #define ADDR_FLAG_DELIVERED 0x01
52 #define ADDR_FLAG_DEFERED 0x02
53 #define ADDR_FLAG_FAILED 0x04
54 #define ADDR_FLAG_LAST_ROUTE 0x40
56 typedef struct _address {
57 gchar *address;
58 gchar *local_part;
59 gchar *domain;
60 gint flags;
61 GList *children;
62 struct _address *parent;
63 } address;
65 #define addr_mark_delivered(addr) { addr->flags |= ADDR_FLAG_DELIVERED; }
66 #define addr_unmark_delivered(addr) { addr->flags &= ~ADDR_FLAG_DELIVERED; }
67 #define addr_is_delivered(addr) ((addr->flags & ADDR_FLAG_DELIVERED) != 0 )
69 #define addr_mark_defered(addr) { addr->flags |= ADDR_FLAG_DEFERED; }
70 #define addr_unmark_defered(addr) { addr->flags &= ~ADDR_FLAG_DEFERED; }
71 #define addr_is_defered(addr) ((addr->flags & ADDR_FLAG_DEFERED) != 0 )
73 #define addr_mark_failed(addr) { addr->flags |= ADDR_FLAG_FAILED; }
74 #define addr_unmark_failed(addr) { addr->flags &= ~ADDR_FLAG_FAILED; }
75 #define addr_is_failed(addr) ((addr->flags & ADDR_FLAG_FAILED) != 0 )
77 typedef struct _connect_route {
78 gchar *name;
79 gchar *filename;
81 gboolean is_perma;
82 gboolean last_route;
84 GList *allowed_senders;
85 GList *denied_senders;
86 GList *allowed_recipients;
87 GList *denied_recipients;
89 interface *mail_host;
90 gboolean connect_error_fail;
91 GList *resolve_list;
92 gchar *helo_name;
93 gboolean do_correct_helo;
94 gboolean instant_helo;
95 gboolean do_pipelining;
96 gchar *auth_name;
97 gchar *auth_login;
98 gchar *auth_secret;
99 gchar *wrapper;
101 gchar *set_h_from_domain;
102 gchar *set_h_reply_to_domain;
103 gchar *set_return_path_domain;
104 GList *map_h_from_addresses;
105 GList *map_h_reply_to_addresses;
106 GList *map_h_mail_followup_to_addresses;
107 GList *map_return_path_addresses;
108 gboolean expand_h_sender_domain;
109 gboolean expand_h_sender_address;
111 gchar *pipe;
112 gboolean pipe_fromline;
113 gboolean pipe_fromhack;
114 } connect_route;
116 typedef struct _masqmail_conf {
117 gint mail_uid;
118 gint mail_gid;
120 gint orig_uid;
121 gint orig_gid;
123 gboolean run_as_user;
125 gchar *mail_dir;
126 gchar *lock_dir;
127 gchar *spool_dir;
128 gchar *log_dir;
130 gint debug_level;
131 gboolean use_syslog;
132 guint log_max_pri;
134 gchar *host_name;
135 GList *local_hosts;
136 GList *local_addresses;
137 GList *not_local_addresses;
138 GList *listen_addresses;
140 /*
141 ** ANSI C defines unsigned long to be at least 32bit
142 ** i.e. ca. 4GB max; that should be enough.
143 */
144 gulong max_msg_size;
146 gboolean do_save_envelope_to;
148 gboolean defer_all;
149 gboolean do_relay;
151 gboolean do_queue;
153 gboolean do_verbose;
155 gchar *mbox_default;
156 GList *mbox_users;
157 GList *mda_users;
159 gchar *mda;
160 gboolean mda_fromline;
161 gboolean mda_fromhack;
163 gboolean pipe_fromline;
164 gboolean pipe_fromhack;
166 gchar *alias_file;
167 int (*localpartcmp) (const char *, const char *);
169 GList *perma_routes;
170 GList *query_routes; /* list of pairs which point to lists */
172 gchar *online_query;
174 gchar *errmsg_file;
175 gchar *warnmsg_file;
176 GList *warn_intervals;
177 gint max_defer_time;
179 gchar *log_user;
180 } masqmail_conf;
182 extern masqmail_conf conf;
184 typedef struct _table_pair {
185 gchar *key;
186 gpointer *value;
187 } table_pair;
190 /* must match the contents of prot_names[] in accept.c */
191 typedef enum _prot_id {
192 PROT_LOCAL = 0,
193 PROT_SMTP,
194 PROT_ESMTP,
195 PROT_NUM
196 } prot_id;
198 extern gchar *prot_names[];
200 typedef enum _header_id {
201 HEAD_FROM = 0,
202 HEAD_SENDER,
203 HEAD_TO,
204 HEAD_CC,
205 HEAD_BCC,
206 HEAD_DATE,
207 HEAD_MESSAGE_ID,
208 HEAD_REPLY_TO,
209 HEAD_SUBJECT,
210 HEAD_RETURN_PATH,
211 HEAD_ENVELOPE_TO,
212 HEAD_RECEIVED,
213 HEAD_NUM_IDS,
214 HEAD_STATUS,
215 HEAD_UNKNOWN = HEAD_NUM_IDS,
216 HEAD_NONE = -1,
217 } header_id;
219 typedef struct _header_name {
220 gchar *header;
221 header_id id;
222 } header_name;
224 typedef struct _header {
225 header_id id;
226 gchar *header;
227 gchar *value;
228 } header;
231 typedef struct _message {
232 gchar *uid;
234 gchar *received_host;
235 prot_id received_prot;
236 gchar *ident;
237 gint transfer_id; /* for multiple messages per transfer */
239 address *return_path;
240 GList *rcpt_list;
241 GList *non_rcpt_list;
243 GList *hdr_list;
244 GList *data_list;
246 gint data_size;
247 time_t received_time;
248 time_t warned_time;
250 gchar *full_sender_name;
251 } message;
253 typedef struct _msg_out {
254 message *msg;
256 address *return_path;
257 GList *rcpt_list;
259 GList *hdr_list;
260 GList *xtra_hdr_list; /* rewritten headers */
261 } msg_out;
263 typedef struct _msgout_perhost {
264 gchar *host;
265 GList *msgout_list;
266 } msgout_perhost;
268 /* flags for accept() */
269 #define ACC_RCPT_FROM_HEAD 0x08 /* -t option, get rcpts from headers */
270 #define ACC_DOT_IGNORE 0x10 /* a dot on a line itself does not end the message (-oi option) */
271 #define ACC_MAIL_FROM_HEAD 0x40 /* get return path from header */
272 #define ACC_NODOT_RELAX 0x80 /* do not be picky if message ist not terminated by a dot on a line */
273 #define ACC_SAVE_ENVELOPE_TO 0x0100 /* save an existent Envelope-to header as X-Orig-Envelope-to */
275 #define DLVR_LOCAL 0x01
276 #define DLVR_ONLINE 0x02
277 #define DLVR_ALL (DLVR_LOCAL|DLVR_ONLINE)
279 /* transport flags */
280 #define MSGSTR_FROMLINE 0x01
281 #define MSGSTR_FROMHACK 0x02
283 typedef enum _accept_error {
284 AERR_OK = 0,
285 AERR_TIMEOUT,
286 AERR_EOF,
287 AERR_OVERFLOW,
288 AERR_SYNTAX,
289 AERR_NOSPOOL,
290 AERR_NORCPT,
291 AERR_SIZE, /* max msg size exeeded (SMTP SIZE) */
292 AERR_UNKNOWN
293 } accept_error;
295 #define BUF_LEN 1024
296 #define MAX_ADDRESS 256
297 #define MAX_DATALINE 4096
299 typedef enum _smtp_cmd_id {
300 SMTP_HELO = 0,
301 SMTP_EHLO,
302 SMTP_MAIL_FROM,
303 SMTP_RCPT_TO,
304 SMTP_DATA,
305 SMTP_QUIT,
306 SMTP_RSET,
307 SMTP_NOOP,
308 SMTP_HELP,
309 SMTP_NUM_IDS,
310 SMTP_EOF = -1,
311 SMTP_ERROR = -2,
312 } smtp_cmd_id;
314 typedef struct _smtp_cmd {
315 smtp_cmd_id id;
316 gchar *cmd;
317 } smtp_cmd;
319 typedef struct _smtp_connection {
320 gchar *remote_host;
322 prot_id prot;
323 gint next_id;
325 gboolean helo_seen;
326 gboolean from_seen;
327 gboolean rcpt_seen;
329 message *msg;
330 } smtp_connection;
332 /* alias.c*/
333 gboolean addr_is_local(address *addr);
334 GList *alias_expand(GList *alias_table, GList *rcpt_list, GList *non_rcpt_list);
336 /* child.c */
337 int child(const char *command);
339 /* conf.c */
340 void init_conf();
341 gboolean read_conf(gchar *filename);
342 connect_route *read_route(gchar *filename, gboolean is_perma);
343 GList *read_route_list(GList *rf_list, gboolean is_perma);
344 void destroy_route(connect_route *r);
345 void destroy_route_list(GList *list);
347 /* expand.c */
348 GList *var_table_rcpt(GList *var_table, address *rcpt);
349 GList *var_table_msg(GList *var_table, message *msg);
350 GList *var_table_conf(GList *var_table);
351 gint expand(GList *var_list, gchar *format, gchar *result, gint result_len);
353 /* message.c */
354 message *create_message(void);
355 void destroy_message(message *msg);
356 void destroy_msg_list(GList *msg_list);
357 void msg_free_data(message *msg);
358 gint msg_calc_size(message *msg, gboolean is_smtp);
360 msg_out *create_msg_out(message *msg);
361 msg_out *clone_msg_out(msg_out *msgout_orig);
362 void destroy_msg_out(msg_out *msgout);
363 void destroy_msg_out_list(GList *msgout_list);
365 /* address.c */
366 address *create_address(gchar *path, gboolean is_rfc821);
367 address *create_address_qualified(gchar *path, gboolean is_rfc821, gchar *domain);
368 address *create_address_pipe(gchar *path);
369 void destroy_address(address *addr);
370 address *copy_modify_address(const address *orig, gchar *l_part, gchar *dom);
371 #define copy_address(addr) copy_modify_address(addr, NULL, NULL)
372 gboolean addr_isequal(address *addr1, address *addr2, int (*cmpfunc) (const char*, const char*));
373 gboolean addr_isequal_parent(address *addr1, address *addr2, int (*cmpfunc) (const char*, const char*));
374 address *addr_find_ancestor(address *addr);
375 gboolean addr_is_delivered_children(address *addr);
376 gboolean addr_is_finished_children(address *addr);
377 gchar *addr_string(address *addr);
379 /* accept.c */
380 accept_error accept_message(FILE *in, message *msg, guint flags);
381 accept_error accept_message_prepare(message *msg, guint flags);
383 /* header.c */
384 gchar *rec_timestamp();
385 GList *find_header(GList *hdr_list, header_id id, gchar *hdr_str);
386 void header_unfold(header *hdr);
387 void header_fold(header *hdr, unsigned int maxlen);
388 header *create_header(header_id id, gchar *fmt, ...);
389 void destroy_header(header *hdr);
390 header *copy_header(header *hdr);
391 header *get_header(gchar *line);
393 /* smtp_in.c */
394 void smtp_in(FILE *in, FILE *out, gchar *remote_host, gchar *ident);
396 /* listen.c */
397 void listen_port(GList *addr_list, gint qival, char *argv[]);
399 /* parse.c */
400 gboolean split_address(const gchar *path, gchar **local_part, gchar **domain, gboolean is_rfc821);
401 gboolean parse_address_rfc822(gchar *string, gchar **local_begin, gchar **local_end, gchar **domain_begin, gchar **domain_end, gchar **address_end);
402 gboolean parse_address_rfc821(gchar *string, gchar **local_begin, gchar **local_end, gchar **domain_begin, gchar **domain_end, gchar **address_end);
403 address *_create_address(gchar *string, gchar **end, gboolean is_rfc821);
404 address *create_address_rfc821(gchar *string, gchar **end);
405 address *create_address_rfc822(gchar *string, gchar **end);
406 GList *addr_list_append_rfc822(GList *addr_list, gchar *string, gchar *domain);
408 /* connect.c */
409 mxip_addr *connect_hostlist(int *psockfd, gchar *host, guint port, GList *addr_list);
410 mxip_addr *connect_resolvelist(int *psockfd, gchar *host, guint port, GList *res_funcs);
412 /* deliver.c */
413 void msg_rcptlist_local(GList *rcpt_list, GList **, GList **);
414 gboolean deliver_local(msg_out *msgout);
415 gboolean deliver_msglist_host(connect_route *route, GList *msg_list, gchar *host, GList *res_list);
416 gboolean deliver_route_msgout_list(connect_route *route, GList *msgout_list);
417 gboolean deliver_route_msg_list(connect_route *route, GList *msgout_list);
418 gboolean deliver_finish(msg_out *msgout);
419 gboolean deliver_msg_list(GList *msg_list, guint flags);
420 gboolean deliver(message *msg);
422 /* fail_msg.c */
423 gboolean fail_msg(message *msg, gchar *template, GList *failed_rcpts, gchar *err_fmt, va_list args);
424 gboolean warn_msg(message *msg, gchar *template, GList *failed_rcpts, gchar *err_fmt, va_list args);
426 /* interface.c */
427 gboolean init_sockaddr(struct sockaddr_in *name, interface *iface);
428 int make_server_socket(interface *iface);
430 /* local.c */
431 gboolean append_file(message *msg, GList *hdr_list, gchar *user);
432 gboolean pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags);
434 /* log.c */
435 gchar *ext_strerror(int err);
436 gboolean logopen(void);
437 void logclose(void);
438 void vlogwrite(int pri, const char *fmt, va_list args);
439 void logwrite(int pri, const char *fmt, ...);
440 void debugf(const char *fmt, ...);
441 void vdebugf(const char *fmt, va_list args);
442 void maillog(const char *fmt, ...);
444 /* spool.c */
445 gboolean spool_read_data(message *msg);
446 message *msg_spool_read(gchar *uid);
447 gboolean spool_write(message *msg, gboolean do_writedata);
448 gboolean spool_lock(gchar *uid);
449 gboolean spool_unlock(gchar *uid);
450 gboolean spool_delete_all(message *msg);
452 /* queue.c */
453 GList *read_queue(void);
454 gboolean queue_run(void);
455 gboolean queue_run_online(void);
456 void queue_list(void);
457 gboolean queue_delete(gchar *uid);
459 /* online.c */
460 gchar *online_query();
462 /* permissions.c */
463 gboolean is_ingroup(uid_t uid, gid_t gid);
464 void set_euidgid(gint uid, gint gid, uid_t *old_uid, gid_t *old_gid);
465 void set_identity(uid_t old_uid, gchar *task_name);
467 /* rewrite.c */
468 gboolean set_address_header_domain(header *hdr, gchar *domain);
469 gboolean map_address_header(header *hdr, GList *table);
471 /* route.c */
472 msgout_perhost *create_msgout_perhost(gchar *host);
473 void destroy_msgout_perhost(msgout_perhost *mo_ph);
474 void rewrite_headers(msg_out *msgout, connect_route *route);
475 void split_rcpts(GList *rcpt_list, GList *localnets, GList **rl_local, GList **rl_localnet, GList **rl_others);
476 GList *local_rcpts(GList *rcpt_list);
477 GList *remote_rcpts(GList *rcpt_list);
478 gboolean route_strip_msgout(connect_route *route, msg_out *msgout);
479 msg_out *route_prepare_msgout(connect_route *route, msg_out *msgout);
480 GList *route_msgout_list(connect_route *route, GList *msgout_list);
481 gboolean route_sender_is_allowed(connect_route *route, address *ret_path);
482 void route_split_rcpts(connect_route *route, GList *rcpt_list, GList **p_rcpt_list, GList **p_non_rcpt_list);
484 /* tables.c */
485 table_pair *create_pair(gchar *key, gpointer value);
486 table_pair *create_pair_string(gchar *key, gpointer value);
487 table_pair *parse_table_pair(gchar *line, char delim);
488 gpointer *table_find_func(GList *table_list, gchar *key, int (*cmp_func) (const char *, const char *));
489 gpointer *table_find(GList *table_list, gchar *key);
490 gpointer *table_find_case(GList *table_list, gchar *key);
491 gpointer *table_find_fnmatch(GList *table_list, gchar *key);
492 GList *table_read(gchar *fname, gchar delim);
493 void destroy_table(GList *table);
495 /* timeival.c */
496 gint time_interval(gchar *str);
498 /* permissions.c */
499 gboolean is_privileged_user(uid_t uid);
501 /* other things */
503 #define foreach(list, node)\
504 for((node) = g_list_first(list);\
505 (node);\
506 (node) = g_list_next(node))
508 #ifdef ENABLE_DEBUG
509 #define DEBUG(level) if(level <= conf.debug_level)
510 #else
511 /* hopefully the compiler optmizes this away... */
512 #define DEBUG(level) if(0)
513 #endif
515 #define LOG_VERBOSE 0x100
517 #ifndef HAVE_GETLINE
518 #define getline(buf, size, file) getdelim(buf, size, '\n', file)
519 #endif
521 #ifndef HAVE_FDATASYNC
522 #define fdatasync(fd) fsync(fd)
523 #endif
525 #ifndef CONF_DIR
526 #define CONF_DIR "/etc/masqmail"
527 #endif
529 #define CONF_FILE CONF_DIR"/masqmail.conf"
531 #define PIDFILEDIR "/var/run/masqmail/"
533 #ifndef va_copy
534 #ifdef __va_copy
535 #define va_copy(ap1, ap2) __va_copy(ap1, ap2)
536 #else
537 #define va_copy(ap1, ap2) G_VA_COPY(ap1, ap2)
538 #endif
539 #endif
541 /* *BSD needs this: */
542 extern char **environ;