1 |
|
|
/* $OpenBSD: smtpd-api.h,v 1.32 2017/09/08 16:51:22 eric 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 |
|
|
struct mailaddr { |
24 |
|
|
char user[SMTPD_MAXLOCALPARTSIZE]; |
25 |
|
|
char domain[SMTPD_MAXDOMAINPARTSIZE]; |
26 |
|
|
}; |
27 |
|
|
|
28 |
|
|
SPLAY_HEAD(_dict, dictentry); |
29 |
|
|
SPLAY_HEAD(_tree, treeentry); |
30 |
|
|
|
31 |
|
|
struct tree { |
32 |
|
|
struct _tree tree; |
33 |
|
|
size_t count; |
34 |
|
|
}; |
35 |
|
|
|
36 |
|
|
struct dict { |
37 |
|
|
struct _dict dict; |
38 |
|
|
size_t count; |
39 |
|
|
}; |
40 |
|
|
|
41 |
|
|
#define PROC_QUEUE_API_VERSION 2 |
42 |
|
|
|
43 |
|
|
enum { |
44 |
|
|
PROC_QUEUE_OK, |
45 |
|
|
PROC_QUEUE_FAIL, |
46 |
|
|
PROC_QUEUE_INIT, |
47 |
|
|
PROC_QUEUE_CLOSE, |
48 |
|
|
PROC_QUEUE_MESSAGE_CREATE, |
49 |
|
|
PROC_QUEUE_MESSAGE_DELETE, |
50 |
|
|
PROC_QUEUE_MESSAGE_COMMIT, |
51 |
|
|
PROC_QUEUE_MESSAGE_FD_R, |
52 |
|
|
PROC_QUEUE_MESSAGE_CORRUPT, |
53 |
|
|
PROC_QUEUE_MESSAGE_UNCORRUPT, |
54 |
|
|
PROC_QUEUE_ENVELOPE_CREATE, |
55 |
|
|
PROC_QUEUE_ENVELOPE_DELETE, |
56 |
|
|
PROC_QUEUE_ENVELOPE_LOAD, |
57 |
|
|
PROC_QUEUE_ENVELOPE_UPDATE, |
58 |
|
|
PROC_QUEUE_ENVELOPE_WALK, |
59 |
|
|
}; |
60 |
|
|
|
61 |
|
|
#define PROC_SCHEDULER_API_VERSION 2 |
62 |
|
|
|
63 |
|
|
struct scheduler_info; |
64 |
|
|
|
65 |
|
|
enum { |
66 |
|
|
PROC_SCHEDULER_OK, |
67 |
|
|
PROC_SCHEDULER_FAIL, |
68 |
|
|
PROC_SCHEDULER_INIT, |
69 |
|
|
PROC_SCHEDULER_INSERT, |
70 |
|
|
PROC_SCHEDULER_COMMIT, |
71 |
|
|
PROC_SCHEDULER_ROLLBACK, |
72 |
|
|
PROC_SCHEDULER_UPDATE, |
73 |
|
|
PROC_SCHEDULER_DELETE, |
74 |
|
|
PROC_SCHEDULER_HOLD, |
75 |
|
|
PROC_SCHEDULER_RELEASE, |
76 |
|
|
PROC_SCHEDULER_BATCH, |
77 |
|
|
PROC_SCHEDULER_MESSAGES, |
78 |
|
|
PROC_SCHEDULER_ENVELOPES, |
79 |
|
|
PROC_SCHEDULER_SCHEDULE, |
80 |
|
|
PROC_SCHEDULER_REMOVE, |
81 |
|
|
PROC_SCHEDULER_SUSPEND, |
82 |
|
|
PROC_SCHEDULER_RESUME, |
83 |
|
|
}; |
84 |
|
|
|
85 |
|
|
enum envelope_flags { |
86 |
|
|
EF_AUTHENTICATED = 0x01, |
87 |
|
|
EF_BOUNCE = 0x02, |
88 |
|
|
EF_INTERNAL = 0x04, /* Internal expansion forward */ |
89 |
|
|
|
90 |
|
|
/* runstate, not saved on disk */ |
91 |
|
|
|
92 |
|
|
EF_PENDING = 0x10, |
93 |
|
|
EF_INFLIGHT = 0x20, |
94 |
|
|
EF_SUSPEND = 0x40, |
95 |
|
|
EF_HOLD = 0x80, |
96 |
|
|
}; |
97 |
|
|
|
98 |
|
|
struct evpstate { |
99 |
|
|
uint64_t evpid; |
100 |
|
|
uint16_t flags; |
101 |
|
|
uint16_t retry; |
102 |
|
|
time_t time; |
103 |
|
|
}; |
104 |
|
|
|
105 |
|
|
enum delivery_type { |
106 |
|
|
D_MDA, |
107 |
|
|
D_MTA, |
108 |
|
|
D_BOUNCE, |
109 |
|
|
}; |
110 |
|
|
|
111 |
|
|
struct scheduler_info { |
112 |
|
|
uint64_t evpid; |
113 |
|
|
enum delivery_type type; |
114 |
|
|
uint16_t retry; |
115 |
|
|
time_t creation; |
116 |
|
|
time_t expire; |
117 |
|
|
time_t lasttry; |
118 |
|
|
time_t lastbounce; |
119 |
|
|
time_t nexttry; |
120 |
|
|
}; |
121 |
|
|
|
122 |
|
|
#define SCHED_REMOVE 0x01 |
123 |
|
|
#define SCHED_EXPIRE 0x02 |
124 |
|
|
#define SCHED_UPDATE 0x04 |
125 |
|
|
#define SCHED_BOUNCE 0x08 |
126 |
|
|
#define SCHED_MDA 0x10 |
127 |
|
|
#define SCHED_MTA 0x20 |
128 |
|
|
|
129 |
|
|
#define PROC_TABLE_API_VERSION 2 |
130 |
|
|
|
131 |
|
|
struct table_open_params { |
132 |
|
|
uint32_t version; |
133 |
|
|
char name[LINE_MAX]; |
134 |
|
|
}; |
135 |
|
|
|
136 |
|
|
enum table_service { |
137 |
|
|
K_NONE = 0x000, |
138 |
|
|
K_ALIAS = 0x001, /* returns struct expand */ |
139 |
|
|
K_DOMAIN = 0x002, /* returns struct destination */ |
140 |
|
|
K_CREDENTIALS = 0x004, /* returns struct credentials */ |
141 |
|
|
K_NETADDR = 0x008, /* returns struct netaddr */ |
142 |
|
|
K_USERINFO = 0x010, /* returns struct userinfo */ |
143 |
|
|
K_SOURCE = 0x020, /* returns struct source */ |
144 |
|
|
K_MAILADDR = 0x040, /* returns struct mailaddr */ |
145 |
|
|
K_ADDRNAME = 0x080, /* returns struct addrname */ |
146 |
|
|
K_MAILADDRMAP = 0x100, /* returns struct maddrmap */ |
147 |
|
|
}; |
148 |
|
|
#define K_ANY 0xfff |
149 |
|
|
|
150 |
|
|
enum { |
151 |
|
|
PROC_TABLE_OK, |
152 |
|
|
PROC_TABLE_FAIL, |
153 |
|
|
PROC_TABLE_OPEN, |
154 |
|
|
PROC_TABLE_CLOSE, |
155 |
|
|
PROC_TABLE_UPDATE, |
156 |
|
|
PROC_TABLE_CHECK, |
157 |
|
|
PROC_TABLE_LOOKUP, |
158 |
|
|
PROC_TABLE_FETCH, |
159 |
|
|
}; |
160 |
|
|
|
161 |
|
|
enum enhanced_status_code { |
162 |
|
|
/* 0.0 */ |
163 |
|
|
ESC_OTHER_STATUS = 00, |
164 |
|
|
|
165 |
|
|
/* 1.x */ |
166 |
|
|
ESC_OTHER_ADDRESS_STATUS = 10, |
167 |
|
|
ESC_BAD_DESTINATION_MAILBOX_ADDRESS = 11, |
168 |
|
|
ESC_BAD_DESTINATION_SYSTEM_ADDRESS = 12, |
169 |
|
|
ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX = 13, |
170 |
|
|
ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS = 14, |
171 |
|
|
ESC_DESTINATION_ADDRESS_VALID = 15, |
172 |
|
|
ESC_DESTINATION_MAILBOX_HAS_MOVED = 16, |
173 |
|
|
ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX = 17, |
174 |
|
|
ESC_BAD_SENDER_SYSTEM_ADDRESS = 18, |
175 |
|
|
|
176 |
|
|
/* 2.x */ |
177 |
|
|
ESC_OTHER_MAILBOX_STATUS = 20, |
178 |
|
|
ESC_MAILBOX_DISABLED = 21, |
179 |
|
|
ESC_MAILBOX_FULL = 22, |
180 |
|
|
ESC_MESSAGE_LENGTH_TOO_LARGE = 23, |
181 |
|
|
ESC_MAILING_LIST_EXPANSION_PROBLEM = 24, |
182 |
|
|
|
183 |
|
|
/* 3.x */ |
184 |
|
|
ESC_OTHER_MAIL_SYSTEM_STATUS = 30, |
185 |
|
|
ESC_MAIL_SYSTEM_FULL = 31, |
186 |
|
|
ESC_SYSTEM_NOT_ACCEPTING_MESSAGES = 32, |
187 |
|
|
ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES = 33, |
188 |
|
|
ESC_MESSAGE_TOO_BIG_FOR_SYSTEM = 34, |
189 |
|
|
ESC_SYSTEM_INCORRECTLY_CONFIGURED = 35, |
190 |
|
|
|
191 |
|
|
/* 4.x */ |
192 |
|
|
ESC_OTHER_NETWORK_ROUTING_STATUS = 40, |
193 |
|
|
ESC_NO_ANSWER_FROM_HOST = 41, |
194 |
|
|
ESC_BAD_CONNECTION = 42, |
195 |
|
|
ESC_DIRECTORY_SERVER_FAILURE = 43, |
196 |
|
|
ESC_UNABLE_TO_ROUTE = 44, |
197 |
|
|
ESC_MAIL_SYSTEM_CONGESTION = 45, |
198 |
|
|
ESC_ROUTING_LOOP_DETECTED = 46, |
199 |
|
|
ESC_DELIVERY_TIME_EXPIRED = 47, |
200 |
|
|
|
201 |
|
|
/* 5.x */ |
202 |
|
|
ESC_INVALID_RECIPIENT = 50, |
203 |
|
|
ESC_INVALID_COMMAND = 51, |
204 |
|
|
ESC_SYNTAX_ERROR = 52, |
205 |
|
|
ESC_TOO_MANY_RECIPIENTS = 53, |
206 |
|
|
ESC_INVALID_COMMAND_ARGUMENTS = 54, |
207 |
|
|
ESC_WRONG_PROTOCOL_VERSION = 55, |
208 |
|
|
|
209 |
|
|
/* 6.x */ |
210 |
|
|
ESC_OTHER_MEDIA_ERROR = 60, |
211 |
|
|
ESC_MEDIA_NOT_SUPPORTED = 61, |
212 |
|
|
ESC_CONVERSION_REQUIRED_AND_PROHIBITED = 62, |
213 |
|
|
ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED = 63, |
214 |
|
|
ESC_CONVERSION_WITH_LOSS_PERFORMED = 64, |
215 |
|
|
ESC_CONVERSION_FAILED = 65, |
216 |
|
|
|
217 |
|
|
/* 7.x */ |
218 |
|
|
ESC_OTHER_SECURITY_STATUS = 70, |
219 |
|
|
ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED = 71, |
220 |
|
|
ESC_MAILING_LIST_EXPANSION_PROHIBITED = 72, |
221 |
|
|
ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE = 73, |
222 |
|
|
ESC_SECURITY_FEATURES_NOT_SUPPORTED = 74, |
223 |
|
|
ESC_CRYPTOGRAPHIC_FAILURE = 75, |
224 |
|
|
ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED = 76, |
225 |
|
|
ESC_MESSAGE_INTEGRITY_FAILURE = 77, |
226 |
|
|
}; |
227 |
|
|
|
228 |
|
|
enum enhanced_status_class { |
229 |
|
|
ESC_STATUS_OK = 2, |
230 |
|
|
ESC_STATUS_TEMPFAIL = 4, |
231 |
|
|
ESC_STATUS_PERMFAIL = 5, |
232 |
|
|
}; |
233 |
|
|
|
234 |
|
|
static inline uint32_t |
235 |
|
|
evpid_to_msgid(uint64_t evpid) |
236 |
|
|
{ |
237 |
|
|
return (evpid >> 32); |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
static inline uint64_t |
241 |
|
|
msgid_to_evpid(uint32_t msgid) |
242 |
|
|
{ |
243 |
|
|
return ((uint64_t)msgid << 32); |
244 |
|
|
} |
245 |
|
|
|
246 |
|
|
/* dict.c */ |
247 |
|
|
#define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0) |
248 |
|
|
#define dict_empty(d) SPLAY_EMPTY(&((d)->dict)) |
249 |
|
|
#define dict_count(d) ((d)->count) |
250 |
|
|
int dict_check(struct dict *, const char *); |
251 |
|
|
void *dict_set(struct dict *, const char *, void *); |
252 |
|
|
void dict_xset(struct dict *, const char *, void *); |
253 |
|
|
void *dict_get(struct dict *, const char *); |
254 |
|
|
void *dict_xget(struct dict *, const char *); |
255 |
|
|
void *dict_pop(struct dict *, const char *); |
256 |
|
|
void *dict_xpop(struct dict *, const char *); |
257 |
|
|
int dict_poproot(struct dict *, void **); |
258 |
|
|
int dict_root(struct dict *, const char **, void **); |
259 |
|
|
int dict_iter(struct dict *, void **, const char **, void **); |
260 |
|
|
int dict_iterfrom(struct dict *, void **, const char *, const char **, void **); |
261 |
|
|
void dict_merge(struct dict *, struct dict *); |
262 |
|
|
|
263 |
|
|
|
264 |
|
|
/* esc.c */ |
265 |
|
|
const char *esc_code(enum enhanced_status_class, enum enhanced_status_code); |
266 |
|
|
const char *esc_description(enum enhanced_status_code); |
267 |
|
|
|
268 |
|
|
|
269 |
|
|
/* queue */ |
270 |
|
|
void queue_api_on_close(int(*)(void)); |
271 |
|
|
void queue_api_on_message_create(int(*)(uint32_t *)); |
272 |
|
|
void queue_api_on_message_commit(int(*)(uint32_t, const char*)); |
273 |
|
|
void queue_api_on_message_delete(int(*)(uint32_t)); |
274 |
|
|
void queue_api_on_message_fd_r(int(*)(uint32_t)); |
275 |
|
|
void queue_api_on_message_corrupt(int(*)(uint32_t)); |
276 |
|
|
void queue_api_on_message_uncorrupt(int(*)(uint32_t)); |
277 |
|
|
void queue_api_on_envelope_create(int(*)(uint32_t, const char *, size_t, uint64_t *)); |
278 |
|
|
void queue_api_on_envelope_delete(int(*)(uint64_t)); |
279 |
|
|
void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t)); |
280 |
|
|
void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t)); |
281 |
|
|
void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t)); |
282 |
|
|
void queue_api_on_message_walk(int(*)(uint64_t *, char *, size_t, |
283 |
|
|
uint32_t, int *, void **)); |
284 |
|
|
void queue_api_no_chroot(void); |
285 |
|
|
void queue_api_set_chroot(const char *); |
286 |
|
|
void queue_api_set_user(const char *); |
287 |
|
|
int queue_api_dispatch(void); |
288 |
|
|
|
289 |
|
|
/* scheduler */ |
290 |
|
|
void scheduler_api_on_init(int(*)(void)); |
291 |
|
|
void scheduler_api_on_insert(int(*)(struct scheduler_info *)); |
292 |
|
|
void scheduler_api_on_commit(size_t(*)(uint32_t)); |
293 |
|
|
void scheduler_api_on_rollback(size_t(*)(uint32_t)); |
294 |
|
|
void scheduler_api_on_update(int(*)(struct scheduler_info *)); |
295 |
|
|
void scheduler_api_on_delete(int(*)(uint64_t)); |
296 |
|
|
void scheduler_api_on_hold(int(*)(uint64_t, uint64_t)); |
297 |
|
|
void scheduler_api_on_release(int(*)(int, uint64_t, int)); |
298 |
|
|
void scheduler_api_on_batch(int(*)(int, int *, size_t *, uint64_t *, int *)); |
299 |
|
|
void scheduler_api_on_messages(size_t(*)(uint32_t, uint32_t *, size_t)); |
300 |
|
|
void scheduler_api_on_envelopes(size_t(*)(uint64_t, struct evpstate *, size_t)); |
301 |
|
|
void scheduler_api_on_schedule(int(*)(uint64_t)); |
302 |
|
|
void scheduler_api_on_remove(int(*)(uint64_t)); |
303 |
|
|
void scheduler_api_on_suspend(int(*)(uint64_t)); |
304 |
|
|
void scheduler_api_on_resume(int(*)(uint64_t)); |
305 |
|
|
void scheduler_api_no_chroot(void); |
306 |
|
|
void scheduler_api_set_chroot(const char *); |
307 |
|
|
void scheduler_api_set_user(const char *); |
308 |
|
|
int scheduler_api_dispatch(void); |
309 |
|
|
|
310 |
|
|
/* table */ |
311 |
|
|
void table_api_on_update(int(*)(void)); |
312 |
|
|
void table_api_on_check(int(*)(int, struct dict *, const char *)); |
313 |
|
|
void table_api_on_lookup(int(*)(int, struct dict *, const char *, char *, size_t)); |
314 |
|
|
void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t)); |
315 |
|
|
int table_api_dispatch(void); |
316 |
|
|
const char *table_api_get_name(void); |
317 |
|
|
|
318 |
|
|
/* tree.c */ |
319 |
|
|
#define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0) |
320 |
|
|
#define tree_empty(t) SPLAY_EMPTY(&((t)->tree)) |
321 |
|
|
#define tree_count(t) ((t)->count) |
322 |
|
|
int tree_check(struct tree *, uint64_t); |
323 |
|
|
void *tree_set(struct tree *, uint64_t, void *); |
324 |
|
|
void tree_xset(struct tree *, uint64_t, void *); |
325 |
|
|
void *tree_get(struct tree *, uint64_t); |
326 |
|
|
void *tree_xget(struct tree *, uint64_t); |
327 |
|
|
void *tree_pop(struct tree *, uint64_t); |
328 |
|
|
void *tree_xpop(struct tree *, uint64_t); |
329 |
|
|
int tree_poproot(struct tree *, uint64_t *, void **); |
330 |
|
|
int tree_root(struct tree *, uint64_t *, void **); |
331 |
|
|
int tree_iter(struct tree *, void **, uint64_t *, void **); |
332 |
|
|
int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **); |
333 |
|
|
void tree_merge(struct tree *, struct tree *); |
334 |
|
|
|
335 |
|
|
#endif |