1 /* $OpenBSD: smtpd-api.h,v 1.37 2024/06/09 10:13:05 gilles Exp $ */
2
3 /*
4 * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
5 * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #ifndef _SMTPD_API_H_
21 #define _SMTPD_API_H_
22
23 #include "dict.h"
24 #include "tree.h"
25
26 struct mailaddr {
27 char user[SMTPD_MAXLOCALPARTSIZE];
28 char domain[SMTPD_MAXDOMAINPARTSIZE];
29 };
30
31 #define PROC_QUEUE_API_VERSION 2
32
33 enum {
34 PROC_QUEUE_OK,
35 PROC_QUEUE_FAIL,
36 PROC_QUEUE_INIT,
37 PROC_QUEUE_CLOSE,
38 PROC_QUEUE_MESSAGE_CREATE,
39 PROC_QUEUE_MESSAGE_DELETE,
40 PROC_QUEUE_MESSAGE_COMMIT,
41 PROC_QUEUE_MESSAGE_FD_R,
42 PROC_QUEUE_ENVELOPE_CREATE,
43 PROC_QUEUE_ENVELOPE_DELETE,
44 PROC_QUEUE_ENVELOPE_LOAD,
45 PROC_QUEUE_ENVELOPE_UPDATE,
46 PROC_QUEUE_ENVELOPE_WALK,
47 };
48
49 #define PROC_SCHEDULER_API_VERSION 2
50
51 struct scheduler_info;
52
53 enum {
54 PROC_SCHEDULER_OK,
55 PROC_SCHEDULER_FAIL,
56 PROC_SCHEDULER_INIT,
57 PROC_SCHEDULER_INSERT,
58 PROC_SCHEDULER_COMMIT,
59 PROC_SCHEDULER_ROLLBACK,
60 PROC_SCHEDULER_UPDATE,
61 PROC_SCHEDULER_DELETE,
62 PROC_SCHEDULER_HOLD,
63 PROC_SCHEDULER_RELEASE,
64 PROC_SCHEDULER_BATCH,
65 PROC_SCHEDULER_MESSAGES,
66 PROC_SCHEDULER_ENVELOPES,
67 PROC_SCHEDULER_SCHEDULE,
68 PROC_SCHEDULER_REMOVE,
69 PROC_SCHEDULER_SUSPEND,
70 PROC_SCHEDULER_RESUME,
71 };
72
73 enum envelope_flags {
74 EF_AUTHENTICATED = 0x01,
75 EF_BOUNCE = 0x02,
76 EF_INTERNAL = 0x04, /* Internal expansion forward */
77
78 /* runstate, not saved on disk */
79
80 EF_PENDING = 0x10,
81 EF_INFLIGHT = 0x20,
82 EF_SUSPEND = 0x40,
83 EF_HOLD = 0x80,
84 };
85
86 struct evpstate {
87 uint64_t evpid;
88 uint16_t flags;
89 uint16_t retry;
90 time_t time;
91 };
92
93 enum delivery_type {
94 D_MDA,
95 D_MTA,
96 D_BOUNCE,
97 };
98
99 struct scheduler_info {
100 uint64_t evpid;
101 enum delivery_type type;
102 uint16_t retry;
103 time_t creation;
104 time_t ttl;
105 time_t lasttry;
106 time_t lastbounce;
107 time_t nexttry;
108 };
109
110 #define SCHED_REMOVE 0x01
111 #define SCHED_EXPIRE 0x02
112 #define SCHED_UPDATE 0x04
113 #define SCHED_BOUNCE 0x08
114 #define SCHED_MDA 0x10
115 #define SCHED_MTA 0x20
116
117 #define PROC_TABLE_API_VERSION 2
118
119 struct table_open_params {
120 uint32_t version;
121 char name[LINE_MAX];
122 };
123
124 enum table_service {
125 K_NONE = 0x000,
126 K_ALIAS = 0x001, /* returns struct expand */
127 K_DOMAIN = 0x002, /* returns struct destination */
128 K_CREDENTIALS = 0x004, /* returns struct credentials */
129 K_NETADDR = 0x008, /* returns struct netaddr */
130 K_USERINFO = 0x010, /* returns struct userinfo */
131 K_SOURCE = 0x020, /* returns struct source */
132 K_MAILADDR = 0x040, /* returns struct mailaddr */
133 K_ADDRNAME = 0x080, /* returns struct addrname */
134 K_MAILADDRMAP = 0x100, /* returns struct maddrmap */
135 K_RELAYHOST = 0x200, /* returns struct relayhost */
136 K_STRING = 0x400,
137 K_REGEX = 0x800,
138 K_AUTH = 0x1000,
139 };
140 #define K_ANY 0xffff
141
142 enum {
143 PROC_TABLE_OK,
144 PROC_TABLE_FAIL,
145 PROC_TABLE_OPEN,
146 PROC_TABLE_CLOSE,
147 PROC_TABLE_UPDATE,
148 PROC_TABLE_CHECK,
149 PROC_TABLE_LOOKUP,
150 PROC_TABLE_FETCH,
151 };
152
153 enum enhanced_status_code {
154 /* 0.0 */
155 ESC_OTHER_STATUS = 00,
156
157 /* 1.x */
158 ESC_OTHER_ADDRESS_STATUS = 10,
159 ESC_BAD_DESTINATION_MAILBOX_ADDRESS = 11,
160 ESC_BAD_DESTINATION_SYSTEM_ADDRESS = 12,
161 ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX = 13,
162 ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS = 14,
163 ESC_DESTINATION_ADDRESS_VALID = 15,
164 ESC_DESTINATION_MAILBOX_HAS_MOVED = 16,
165 ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX = 17,
166 ESC_BAD_SENDER_SYSTEM_ADDRESS = 18,
167
168 /* 2.x */
169 ESC_OTHER_MAILBOX_STATUS = 20,
170 ESC_MAILBOX_DISABLED = 21,
171 ESC_MAILBOX_FULL = 22,
172 ESC_MESSAGE_LENGTH_TOO_LARGE = 23,
173 ESC_MAILING_LIST_EXPANSION_PROBLEM = 24,
174
175 /* 3.x */
176 ESC_OTHER_MAIL_SYSTEM_STATUS = 30,
177 ESC_MAIL_SYSTEM_FULL = 31,
178 ESC_SYSTEM_NOT_ACCEPTING_MESSAGES = 32,
179 ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES = 33,
180 ESC_MESSAGE_TOO_BIG_FOR_SYSTEM = 34,
181 ESC_SYSTEM_INCORRECTLY_CONFIGURED = 35,
182
183 /* 4.x */
184 ESC_OTHER_NETWORK_ROUTING_STATUS = 40,
185 ESC_NO_ANSWER_FROM_HOST = 41,
186 ESC_BAD_CONNECTION = 42,
187 ESC_DIRECTORY_SERVER_FAILURE = 43,
188 ESC_UNABLE_TO_ROUTE = 44,
189 ESC_MAIL_SYSTEM_CONGESTION = 45,
190 ESC_ROUTING_LOOP_DETECTED = 46,
191 ESC_DELIVERY_TIME_EXPIRED = 47,
192
193 /* 5.x */
194 ESC_INVALID_RECIPIENT = 50,
195 ESC_INVALID_COMMAND = 51,
196 ESC_SYNTAX_ERROR = 52,
197 ESC_TOO_MANY_RECIPIENTS = 53,
198 ESC_INVALID_COMMAND_ARGUMENTS = 54,
199 ESC_WRONG_PROTOCOL_VERSION = 55,
200
201 /* 6.x */
202 ESC_OTHER_MEDIA_ERROR = 60,
203 ESC_MEDIA_NOT_SUPPORTED = 61,
204 ESC_CONVERSION_REQUIRED_AND_PROHIBITED = 62,
205 ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED = 63,
206 ESC_CONVERSION_WITH_LOSS_PERFORMED = 64,
207 ESC_CONVERSION_FAILED = 65,
208
209 /* 7.x */
210 ESC_OTHER_SECURITY_STATUS = 70,
211 ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED = 71,
212 ESC_MAILING_LIST_EXPANSION_PROHIBITED = 72,
213 ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE = 73,
214 ESC_SECURITY_FEATURES_NOT_SUPPORTED = 74,
215 ESC_CRYPTOGRAPHIC_FAILURE = 75,
216 ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED = 76,
217 ESC_MESSAGE_INTEGRITY_FAILURE = 77,
218 };
219
220 enum enhanced_status_class {
221 ESC_STATUS_OK = 2,
222 ESC_STATUS_TEMPFAIL = 4,
223 ESC_STATUS_PERMFAIL = 5,
224 };
225
226 static inline uint32_t
evpid_to_msgid(uint64_t evpid)227 evpid_to_msgid(uint64_t evpid)
228 {
229 return (evpid >> 32);
230 }
231
232 static inline uint64_t
msgid_to_evpid(uint32_t msgid)233 msgid_to_evpid(uint32_t msgid)
234 {
235 return ((uint64_t)msgid << 32);
236 }
237
238
239 /* esc.c */
240 const char *esc_code(enum enhanced_status_class, enum enhanced_status_code);
241 const char *esc_description(enum enhanced_status_code);
242
243
244 /* queue */
245 void queue_api_on_close(int(*)(void));
246 void queue_api_on_message_create(int(*)(uint32_t *));
247 void queue_api_on_message_commit(int(*)(uint32_t, const char*));
248 void queue_api_on_message_delete(int(*)(uint32_t));
249 void queue_api_on_message_fd_r(int(*)(uint32_t));
250 void queue_api_on_envelope_create(int(*)(uint32_t, const char *, size_t, uint64_t *));
251 void queue_api_on_envelope_delete(int(*)(uint64_t));
252 void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t));
253 void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t));
254 void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t));
255 void queue_api_on_message_walk(int(*)(uint64_t *, char *, size_t,
256 uint32_t, int *, void **));
257 void queue_api_no_chroot(void);
258 void queue_api_set_chroot(const char *);
259 void queue_api_set_user(const char *);
260 int queue_api_dispatch(void);
261
262 /* scheduler */
263 void scheduler_api_on_init(int(*)(void));
264 void scheduler_api_on_insert(int(*)(struct scheduler_info *));
265 void scheduler_api_on_commit(size_t(*)(uint32_t));
266 void scheduler_api_on_rollback(size_t(*)(uint32_t));
267 void scheduler_api_on_update(int(*)(struct scheduler_info *));
268 void scheduler_api_on_delete(int(*)(uint64_t));
269 void scheduler_api_on_hold(int(*)(uint64_t, uint64_t));
270 void scheduler_api_on_release(int(*)(int, uint64_t, int));
271 void scheduler_api_on_batch(int(*)(int, int *, size_t *, uint64_t *, int *));
272 void scheduler_api_on_messages(size_t(*)(uint32_t, uint32_t *, size_t));
273 void scheduler_api_on_envelopes(size_t(*)(uint64_t, struct evpstate *, size_t));
274 void scheduler_api_on_schedule(int(*)(uint64_t));
275 void scheduler_api_on_remove(int(*)(uint64_t));
276 void scheduler_api_on_suspend(int(*)(uint64_t));
277 void scheduler_api_on_resume(int(*)(uint64_t));
278 void scheduler_api_no_chroot(void);
279 void scheduler_api_set_chroot(const char *);
280 void scheduler_api_set_user(const char *);
281 int scheduler_api_dispatch(void);
282
283 /* table */
284 void table_api_on_update(int(*)(void));
285 void table_api_on_check(int(*)(int, struct dict *, const char *));
286 void table_api_on_lookup(int(*)(int, struct dict *, const char *, char *, size_t));
287 void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t));
288 int table_api_dispatch(void);
289 const char *table_api_get_name(void);
290
291 #endif
292