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