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 336