1 /*	$NetBSD: trace.c,v 1.3 2022/10/08 16:12:45 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	trace 3
6 /* SUMMARY
7 /*	user requested delivery tracing
8 /* SYNOPSIS
9 /*	#include <trace.h>
10 /*
11 /*	int	trace_append(flags, id, stats, rcpt, relay, dsn)
12 /*	int	flags;
13 /*	const char *id;
14 /*	MSG_STATS *stats;
15 /*	RECIPIENT *rcpt;
16 /*	const char *relay;
17 /*	DSN	*dsn;
18 /*
19 /*	int     trace_flush(flags, queue, id, encoding, sender,
20 /*				dsn_envid, dsn_ret)
21 /*	int     flags;
22 /*	const char *queue;
23 /*	const char *id;
24 /*	const char *encoding;
25 /*	const char *sender;
26 /*	const char *dsn_envid;
27 /*	int	dsn_ret;
28 /* DESCRIPTION
29 /*	trace_append() updates the message delivery record that is
30 /*	mailed back to the originator. In case of a trace-only
31 /*	message, the recipient status is also written to the
32 /*	mailer logfile.
33 /*
34 /*	trace_flush() returns the specified message to the specified
35 /*	sender, including the message delivery record log that was built
36 /*	with vtrace_append().
37 /*
38 /*	Arguments:
39 /* .IP flags
40 /*	The bitwise OR of zero or more of the following (specify
41 /*	BOUNCE_FLAG_NONE to request no special processing):
42 /* .RS
43 /* .IP BOUNCE_FLAG_CLEAN
44 /*	Delete the logfile in case of an error (as in: pretend
45 /*	that we never even tried to deliver this message).
46 /* .RE
47 /* .IP queue
48 /*	The message queue name of the original message file.
49 /* .IP id
50 /*	The message queue id.
51 /* .IP encoding
52 /*	The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
53 /* .IP sender
54 /*	The sender envelope address.
55 /* .IP dsn_envid
56 /*	Optional DSN envelope ID.
57 /* .IP dsn_ret
58 /*	Optional DSN return full/headers option.
59 /* .IP stats
60 /*	Time stamps from different message delivery stages
61 /*	and session reuse count.
62 /* .IP rcpt
63 /*	Recipient information. See recipient_list(3).
64 /* .IP relay
65 /*	The host we sent the mail to.
66 /* .IP dsn
67 /*	Delivery status information. See dsn(3).
68 /* DIAGNOSTICS
69 /*	A non-zero result means the operation failed.
70 /*
71 /*	Fatal: out of memory.
72 /* BUGS
73 /*	Should be replaced by routines with an attribute-value based
74 /*	interface instead of an interface that uses a rigid argument list.
75 /* LICENSE
76 /* .ad
77 /* .fi
78 /*	The Secure Mailer license must be distributed with this software.
79 /* AUTHOR(S)
80 /*	Wietse Venema
81 /*	IBM T.J. Watson Research
82 /*	P.O. Box 704
83 /*	Yorktown Heights, NY 10598, USA
84 /*
85 /*	Wietse Venema
86 /*	Google, Inc.
87 /*	111 8th Avenue
88 /*	New York, NY 10011, USA
89 /*--*/
90 
91 /* System library. */
92 
93 #include <sys_defs.h>
94 #include <stdio.h>
95 #include <string.h>
96 
97 /* Utility library. */
98 
99 #include <msg.h>
100 #include <vstring.h>
101 
102 /* Global library. */
103 
104 #include <mail_params.h>
105 #include <mail_proto.h>
106 #include <log_adhoc.h>
107 #include <rcpt_print.h>
108 #include <dsn_print.h>
109 #include <trace.h>
110 
111 /* trace_append - append to message delivery record */
112 
trace_append(int flags,const char * id,MSG_STATS * stats,RECIPIENT * rcpt,const char * relay,DSN * dsn)113 int     trace_append(int flags, const char *id, MSG_STATS *stats,
114 		             RECIPIENT *rcpt, const char *relay,
115 		             DSN *dsn)
116 {
117     VSTRING *why = vstring_alloc(100);
118     DSN     my_dsn = *dsn;
119     int     req_stat;
120 
121     /*
122      * User-requested address verification, verbose delivery, or DSN SUCCESS
123      * notification.
124      */
125     if (strcmp(relay, NO_RELAY_AGENT) != 0)
126 	vstring_sprintf(why, "delivery via %s: ", relay);
127     vstring_strcat(why, my_dsn.reason);
128     my_dsn.reason = vstring_str(why);
129 
130     if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
131 			    MAIL_ATTR_PROTO_BOUNCE,
132 			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
133 			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
134 			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
135 			    SEND_ATTR_FUNC(rcpt_print, (const void *) rcpt),
136 			  SEND_ATTR_FUNC(dsn_print, (const void *) &my_dsn),
137 			    ATTR_TYPE_END) != 0) {
138 	msg_warn("%s: %s service failure", id, var_trace_service);
139 	req_stat = -1;
140     } else {
141 	if (flags & DEL_REQ_FLAG_USR_VRFY)
142 	    log_adhoc(id, stats, rcpt, relay, dsn, my_dsn.action);
143 	req_stat = 0;
144     }
145     vstring_free(why);
146     return (req_stat);
147 }
148 
149 /* trace_flush - deliver delivery record to the sender */
150 
trace_flush(int flags,const char * queue,const char * id,const char * encoding,const char * sender,const char * dsn_envid,int dsn_ret)151 int     trace_flush(int flags, const char *queue, const char *id,
152 		            const char *encoding, const char *sender,
153 		            const char *dsn_envid, int dsn_ret)
154 {
155     if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
156 			    MAIL_ATTR_PROTO_BOUNCE,
157 			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_TRACE),
158 			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
159 			    SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
160 			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
161 			    SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
162 			    SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
163 			    SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
164 			    SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
165 			    ATTR_TYPE_END) == 0) {
166 	return (0);
167     } else {
168 	return (-1);
169     }
170 }
171