1 /*        $NetBSD: verify.c,v 1.4 2022/10/08 16:12:45 christos Exp $  */
2 
3 /*++
4 /* NAME
5 /*        verify 3
6 /* SUMMARY
7 /*        update verify database
8 /* SYNOPSIS
9 /*        #include <verify.h>
10 /*
11 /*        int       verify_append(queue_id, stats, recipient, relay, dsn,
12 /*                                      verify_status)
13 /*        const char *queue_id;
14 /*        MSG_STATS *stats;
15 /*        RECIPIENT *recipient;
16 /*        const char *relay;
17 /*        DSN       *dsn;
18 /*        int       verify_status;
19 /* DESCRIPTION
20 /*        This module implements an impedance adaptor between the
21 /*        verify_clnt interface and the interface expected by the
22 /*        bounce/defer/sent modules.
23 /*
24 /*        verify_append() updates the address verification database
25 /*        and logs the action to the mailer logfile.
26 /*
27 /*        Arguments:
28 /* .IP queue_id
29 /*        The message queue id.
30 /* .IP stats
31 /*        Time stamps from different message delivery stages
32 /*        and session reuse count.
33 /* .IP recipient
34 /*        Recipient information. See recipient_list(3).
35 /* .IP relay
36 /*        Name of the host we're talking to.
37 /* .IP dsn
38 /*        Delivery status information. See dsn(3).
39 /*        The action is one of "deliverable" or "undeliverable".
40 /* .IP verify_status
41 /*        One of the following recipient verification status codes:
42 /* .RS
43 /* .IP DEL_REQ_RCPT_STAT_OK
44 /*        Successful delivery.
45 /* .IP DEL_REQ_RCPT_STAT_DEFER
46 /*        Temporary delivery error.
47 /* .IP DEL_REQ_RCPT_STAT_BOUNCE
48 /*        Hard delivery error.
49 /* .RE
50 /* DIAGNOSTICS
51 /*        A non-zero result means the operation failed.
52 /*
53 /*        Fatal: out of memory.
54 /* BUGS
55 /*        Should be replaced by routines with an attribute-value based
56 /*        interface instead of an interface that uses a rigid argument list.
57 /* LICENSE
58 /* .ad
59 /* .fi
60 /*        The Secure Mailer license must be distributed with this software.
61 /* AUTHOR(S)
62 /*        Wietse Venema
63 /*        IBM T.J. Watson Research
64 /*        P.O. Box 704
65 /*        Yorktown Heights, NY 10598, USA
66 /*
67 /*        Wietse Venema
68 /*        Google, Inc.
69 /*        111 8th Avenue
70 /*        New York, NY 10011, USA
71 /*--*/
72 
73 /* System library. */
74 
75 #include <sys_defs.h>
76 #include <string.h>
77 
78 /* Utility library. */
79 
80 #include <msg.h>
81 #include <vstring.h>
82 #include <stringops.h>
83 
84 /* Global library. */
85 
86 #include <mail_params.h>
87 #include <mail_proto.h>
88 #include <verify_clnt.h>
89 #include <log_adhoc.h>
90 #include <verify.h>
91 
92 /* verify_append - update address verification database */
93 
verify_append(const char * queue_id,MSG_STATS * stats,RECIPIENT * recipient,const char * relay,DSN * dsn,int vrfy_stat)94 int     verify_append(const char *queue_id, MSG_STATS *stats,
95                                   RECIPIENT *recipient, const char *relay,
96                                   DSN *dsn, int vrfy_stat)
97 {
98     int     req_stat;
99     DSN     my_dsn = *dsn;
100 
101     /*
102      * Impedance adaptor between bounce/defer/sent and verify_clnt.
103      *
104      * XXX No DSN check; this routine is called from bounce/defer/sent, which
105      * know what the DSN initial digit should look like.
106      *
107      * XXX vrfy_stat is completely redundant because of dsn.
108      */
109     if (var_verify_neg_cache || vrfy_stat == DEL_RCPT_STAT_OK) {
110           if (recipient->orig_addr[0])
111               req_stat = verify_clnt_update(recipient->orig_addr, vrfy_stat,
112                                                     my_dsn.reason);
113           else
114               req_stat = VRFY_STAT_OK;
115           /* Two verify updates for one verify request! */
116           if (req_stat == VRFY_STAT_OK
117               && strcmp(recipient->address, recipient->orig_addr) != 0)
118               req_stat = verify_clnt_update(recipient->address, vrfy_stat,
119                                                     my_dsn.reason);
120     } else {
121           my_dsn.action = "undeliverable-but-not-cached";
122           req_stat = VRFY_STAT_OK;
123     }
124     if (req_stat == VRFY_STAT_OK) {
125           log_adhoc(queue_id, stats, recipient, relay, dsn, my_dsn.action);
126           req_stat = 0;
127     } else {
128           msg_warn("%s: %s service failure", queue_id, var_verify_service);
129           req_stat = -1;
130     }
131     return (req_stat);
132 }
133