| 1 | /************************************************* |
| 2 | * Exim - an Internet mail transport agent * |
| 3 | *************************************************/ |
| 4 | |
| 5 | /* Copyright (c) University of Cambridge 1995 - 2018 */ |
| 6 | /* See the file NOTICE for conditions of use and distribution. */ |
| 7 | |
| 8 | |
| 9 | /* Definitions of various structures. In addition, those that are visible for |
| 10 | the compilation of local_scan() are defined in local_scan.h. These are |
| 11 | |
| 12 | header_line |
| 13 | optionlist |
| 14 | recipient_item |
| 15 | |
| 16 | For those declared here, we have to pre-declare some because of mutually |
| 17 | recursive definitions in the auths, routers, and transports blocks. */ |
| 18 | |
| 19 | struct address_item; |
| 20 | struct auth_info; |
| 21 | struct driver_info; |
| 22 | struct director_info; |
| 23 | struct smtp_inblock; |
| 24 | struct smtp_outblock; |
| 25 | struct transport_info; |
| 26 | struct router_info; |
| 27 | |
| 28 | /* Growable-string */ |
| 29 | typedef struct gstring { |
| 30 | int size; /* Current capacity of string memory */ |
| 31 | int ptr; /* Offset at which to append further chars */ |
| 32 | uschar * s; /* The string memory */ |
| 33 | } gstring; |
| 34 | |
| 35 | /* Structure for remembering macros for the configuration file */ |
| 36 | |
| 37 | typedef struct macro_item { |
| 38 | struct macro_item * next; |
| 39 | BOOL command_line; |
| 40 | unsigned namelen; |
| 41 | unsigned replen; |
| 42 | const uschar * name; |
| 43 | const uschar * replacement; |
| 44 | } macro_item; |
| 45 | |
| 46 | /* Structure for bit tables for debugging and logging */ |
| 47 | |
| 48 | typedef struct bit_table { |
| 49 | uschar *name; |
| 50 | int bit; |
| 51 | } bit_table; |
| 52 | |
| 53 | /* Block for holding a uid and gid, possibly unset, and an initgroups flag. */ |
| 54 | |
| 55 | typedef struct ugid_block { |
| 56 | uid_t uid; |
| 57 | gid_t gid; |
| 58 | BOOL uid_set; |
| 59 | BOOL gid_set; |
| 60 | BOOL initgroups; |
| 61 | } ugid_block; |
| 62 | |
| 63 | typedef enum { CHUNKING_NOT_OFFERED = -1, |
| 64 | CHUNKING_OFFERED, |
| 65 | CHUNKING_ACTIVE, |
| 66 | CHUNKING_LAST} chunking_state_t; |
| 67 | |
| 68 | typedef enum { TFO_NOT_USED = 0, |
| 69 | TFO_ATTEMPTED, |
| 70 | TFO_USED } tfo_state_t; |
| 71 | |
| 72 | /* Structure for holding information about a host for use mainly by routers, |
| 73 | but also used when checking lists of hosts and when transporting. Looking up |
| 74 | host addresses is done using this structure. */ |
| 75 | |
| 76 | typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t; |
| 77 | |
| 78 | typedef struct host_item { |
| 79 | struct host_item *next; |
| 80 | const uschar *name; /* Host name */ |
| 81 | const uschar *address; /* IP address in text form */ |
| 82 | int port; /* port value in host order (if SRV lookup) */ |
| 83 | int mx; /* MX value if found via MX records */ |
| 84 | int sort_key; /* MX*1000 plus random "fraction" */ |
| 85 | int status; /* Usable, unusable, or unknown */ |
| 86 | int why; /* Why host is unusable */ |
| 87 | int last_try; /* Time of last try if known */ |
| 88 | dnssec_status_t dnssec; |
| 89 | } host_item; |
| 90 | |
| 91 | /* Chain of rewrite rules, read from the rewrite config, or parsed from the |
| 92 | rewrite_headers field of a transport. */ |
| 93 | |
| 94 | typedef struct rewrite_rule { |
| 95 | struct rewrite_rule *next; |
| 96 | int flags; |
| 97 | uschar *key; |
| 98 | uschar *replacement; |
| 99 | } rewrite_rule; |
| 100 | |
| 101 | /* This structure is used to pass back configuration data from the smtp |
| 102 | transport to the outside world. It is used during callback processing. If ever |
| 103 | another remote transport were implemented, it could use the same structure. */ |
| 104 | |
| 105 | typedef struct transport_feedback { |
| 106 | uschar *interface; |
| 107 | uschar *port; |
| 108 | uschar *protocol; |
| 109 | uschar *hosts; |
| 110 | uschar *helo_data; |
| 111 | BOOL hosts_override; |
| 112 | BOOL hosts_randomize; |
| 113 | BOOL gethostbyname; |
| 114 | BOOL qualify_single; |
| 115 | BOOL search_parents; |
| 116 | } transport_feedback; |
| 117 | |
| 118 | /* Routers, transports, and authenticators have similar data blocks. Each |
| 119 | driver that is compiled into the code is represented by a xxx_info block; the |
| 120 | active drivers are represented by a chain of xxx_instance blocks. To make it |
| 121 | possible to use the same code for reading the configuration files for all |
| 122 | three, the layout of the start of the blocks is kept the same, and represented |
| 123 | by the generic structures driver_info and driver_instance. */ |
| 124 | |
| 125 | typedef struct driver_instance { |
| 126 | struct driver_instance *next; |
| 127 | uschar *name; /* Instance name */ |
| 128 | struct driver_info *info; /* Points to info for this driver */ |
| 129 | void *options_block; /* Pointer to private options */ |
| 130 | uschar *driver_name; /* All start with this generic option */ |
| 131 | } driver_instance; |
| 132 | |
| 133 | typedef struct driver_info { |
| 134 | uschar *driver_name; /* Name of driver */ |
| 135 | optionlist *options; /* Table of private options names */ |
| 136 | int *options_count; /* -> Number of entries in table */ |
| 137 | void *options_block; /* Points to default private block */ |
| 138 | int options_len; /* Length of same in bytes */ |
| 139 | void (*init)( /* Initialization entry point */ |
| 140 | struct driver_instance *); |
| 141 | } driver_info; |
| 142 | |
| 143 | |
| 144 | /* Structure for holding information about the configured transports. Some |
| 145 | of the generally accessible options are set from the configuration file; others |
| 146 | are set by transport initialization, since they can only be set for certain |
| 147 | transports. They need to be generally accessible, however, as they are used by |
| 148 | the main transport code. */ |
| 149 | |
| 150 | typedef struct transport_instance { |
| 151 | struct transport_instance *next; |
| 152 | uschar *name; /* Instance name */ |
| 153 | struct transport_info *info; /* Info for this driver */ |
| 154 | void *options_block; /* Pointer to private options */ |
| 155 | uschar *driver_name; /* Must be first */ |
| 156 | int (*setup)( /* Setup entry point */ |
| 157 | struct transport_instance *, |
| 158 | struct address_item *, |
| 159 | struct transport_feedback *, /* For passing back config data */ |
| 160 | uid_t, /* The uid that will be used */ |
| 161 | gid_t, /* The gid that will be used */ |
| 162 | uschar **); /* For an error message */ |
| 163 | /**************************************/ |
| 164 | int batch_max; /* ) */ |
| 165 | uschar *batch_id; /* ) */ |
| 166 | uschar *home_dir; /* ) Used only for local transports */ |
| 167 | uschar *current_dir; /* ) */ |
| 168 | /**************************************/ |
| 169 | uschar *expand_multi_domain; /* ) */ |
| 170 | BOOL multi_domain; /* ) */ |
| 171 | BOOL overrides_hosts; /* ) Used only for remote transports */ |
| 172 | int max_addresses; /* ) */ |
| 173 | int connection_max_messages;/* ) */ |
| 174 | /**************************************/ |
| 175 | BOOL deliver_as_creator; /* Used only by pipe at present */ |
| 176 | BOOL disable_logging; /* For very weird requirements */ |
| 177 | BOOL initgroups; /* Initialize groups when setting uid */ |
| 178 | BOOL uid_set; /* uid is set */ |
| 179 | BOOL gid_set; /* gid is set */ |
| 180 | uid_t uid; |
| 181 | gid_t gid; |
| 182 | uschar *expand_uid; /* Variable uid */ |
| 183 | uschar *expand_gid; /* Variable gid */ |
| 184 | uschar *warn_message; /* Used only by appendfile at present */ |
| 185 | uschar *shadow; /* Name of shadow transport */ |
| 186 | uschar *shadow_condition; /* Condition for running it */ |
| 187 | uschar *filter_command; /* For on-the-fly-filtering */ |
| 188 | uschar *add_headers; /* Add these headers */ |
| 189 | uschar *remove_headers; /* Remove these headers */ |
| 190 | uschar *return_path; /* Overriding (rewriting) return path */ |
| 191 | uschar *debug_string; /* Debugging output */ |
| 192 | uschar *max_parallel; /* Number of concurrent instances */ |
| 193 | uschar *message_size_limit; /* Biggest message this transport handles */ |
| 194 | uschar *headers_rewrite; /* Rules for rewriting headers */ |
| 195 | rewrite_rule *rewrite_rules; /* Parsed rewriting rules */ |
| 196 | int rewrite_existflags; /* Bits showing which headers are rewritten */ |
| 197 | int filter_timeout; /* For transport filter timing */ |
| 198 | BOOL body_only; /* Deliver only the body */ |
| 199 | BOOL delivery_date_add; /* Add Delivery-Date header */ |
| 200 | BOOL envelope_to_add; /* Add Envelope-To header */ |
| 201 | BOOL headers_only; /* Deliver only the headers */ |
| 202 | BOOL rcpt_include_affixes; /* TRUE to retain affixes in RCPT commands */ |
| 203 | BOOL return_path_add; /* Add Return-Path header */ |
| 204 | BOOL return_output; /* TRUE if output should always be returned */ |
| 205 | BOOL return_fail_output; /* ditto, but only on failure */ |
| 206 | BOOL log_output; /* Similarly for logging */ |
| 207 | BOOL log_fail_output; |
| 208 | BOOL log_defer_output; |
| 209 | BOOL retry_use_local_part; /* Defaults true for local, false for remote */ |
| 210 | #ifndef DISABLE_EVENT |
| 211 | uschar *event_action; /* String to expand on notable events */ |
| 212 | #endif |
| 213 | } transport_instance; |
| 214 | |
| 215 | |
| 216 | /* Structure for holding information about a type of transport. The first six |
| 217 | fields must match driver_info above. */ |
| 218 | |
| 219 | typedef struct transport_info { |
| 220 | uschar *driver_name; /* Driver name */ |
| 221 | optionlist *options; /* Table of private options names */ |
| 222 | int *options_count; /* -> Number of entries in table */ |
| 223 | void *options_block; /* Points to default private block */ |
| 224 | int options_len; /* Length of same in bytes */ |
| 225 | void (*init)( /* Initialization function */ |
| 226 | struct transport_instance *); |
| 227 | /****/ |
| 228 | BOOL (*code)( /* Main entry point */ |
| 229 | transport_instance *, |
| 230 | struct address_item *); |
| 231 | void (*tidyup)( /* Tidyup function */ |
| 232 | struct transport_instance *); |
| 233 | void (*closedown)( /* For closing down a passed channel */ |
| 234 | struct transport_instance *); |
| 235 | BOOL local; /* TRUE for local transports */ |
| 236 | } transport_info; |
| 237 | |
| 238 | |
| 239 | /* smtp transport datachunk callback */ |
| 240 | |
| 241 | #define tc_reap_prev BIT(0) /* Flags: reap previous SMTP cmd responses */ |
| 242 | #define tc_chunk_last BIT(1) /* annotate chunk SMTP cmd as LAST */ |
| 243 | |
| 244 | struct transport_context; |
| 245 | typedef int (*tpt_chunk_cmd_cb)(struct transport_context *, unsigned, unsigned); |
| 246 | |
| 247 | /* Structure for information about a delivery-in-progress */ |
| 248 | |
| 249 | typedef struct transport_context { |
| 250 | union { /* discriminated by option topt_output_string */ |
| 251 | int fd; /* file descriptor to write message to */ |
| 252 | gstring * msg; /* allocated string with written message */ |
| 253 | } u; |
| 254 | transport_instance * tblock; /* transport */ |
| 255 | struct address_item * addr; |
| 256 | uschar * check_string; /* string replacement */ |
| 257 | uschar * escape_string; |
| 258 | int options; /* output processing topt_* */ |
| 259 | |
| 260 | /* items below only used with option topt_use_bdat */ |
| 261 | tpt_chunk_cmd_cb chunk_cb; /* per-datachunk callback */ |
| 262 | void * smtp_context; |
| 263 | } transport_ctx; |
| 264 | |
| 265 | |
| 266 | |
| 267 | typedef struct { |
| 268 | uschar *request; |
| 269 | uschar *require; |
| 270 | } dnssec_domains; |
| 271 | |
| 272 | /* Structure for holding information about the configured routers. */ |
| 273 | |
| 274 | typedef struct router_instance { |
| 275 | struct router_instance *next; |
| 276 | uschar *name; |
| 277 | struct router_info *info; |
| 278 | void *options_block; /* Pointer to private options */ |
| 279 | uschar *driver_name; /* Must be first */ |
| 280 | |
| 281 | uschar *address_data; /* Arbitrary data */ |
| 282 | #ifdef EXPERIMENTAL_BRIGHTMAIL |
| 283 | uschar *bmi_rule; /* Brightmail AntiSpam rule checking */ |
| 284 | #endif |
| 285 | uschar *cannot_route_message; /* Used when routing fails */ |
| 286 | uschar *condition; /* General condition */ |
| 287 | uschar *current_directory; /* For use during delivery */ |
| 288 | uschar *debug_string; /* Debugging output */ |
| 289 | uschar *domains; /* Specific domains */ |
| 290 | uschar *errors_to; /* Errors address */ |
| 291 | uschar *expand_gid; /* Expanded gid string */ |
| 292 | uschar *expand_uid; /* Expanded uid string */ |
| 293 | uschar *expand_more; /* Expanded more string */ |
| 294 | uschar *expand_unseen; /* Expanded unseen string */ |
| 295 | uschar *extra_headers; /* Additional headers */ |
| 296 | uschar *fallback_hosts; /* For remote transports (text list) */ |
| 297 | uschar *home_directory; /* For use during delivery */ |
| 298 | uschar *ignore_target_hosts; /* Target hosts to ignore */ |
| 299 | uschar *local_parts; /* Specific local parts */ |
| 300 | uschar *pass_router_name; /* Router for passed address */ |
| 301 | uschar *prefix; /* Address prefix */ |
| 302 | uschar *redirect_router_name; /* Router for generated address */ |
| 303 | uschar *remove_headers; /* Removed headers */ |
| 304 | uschar *require_files; /* File checks before router is run */ |
| 305 | uschar *router_home_directory; /* For use while routing */ |
| 306 | uschar *self; /* Text option for handling self reference */ |
| 307 | uschar *senders; /* Specific senders */ |
| 308 | uschar *suffix; /* Address suffix */ |
| 309 | uschar *translate_ip_address; /* IP address translation fudgery */ |
| 310 | uschar *transport_name; /* Transport name */ |
| 311 | |
| 312 | BOOL address_test; /* Use this router when testing addresses */ |
| 313 | #ifdef EXPERIMENTAL_BRIGHTMAIL |
| 314 | BOOL bmi_deliver_alternate; /* TRUE => BMI said that message should be delivered to alternate location */ |
| 315 | BOOL bmi_deliver_default; /* TRUE => BMI said that message should be delivered to default location */ |
| 316 | BOOL bmi_dont_deliver; /* TRUE => BMI said that message should not be delivered at all */ |
| 317 | #endif |
| 318 | BOOL expn; /* Use this router when processing EXPN */ |
| 319 | BOOL caseful_local_part; /* TRUE => don't lowercase */ |
| 320 | BOOL check_local_user; /* TRUE => check local user */ |
| 321 | BOOL disable_logging; /* For very weird requirements */ |
| 322 | BOOL fail_verify_recipient; /* Fail verify if recipient match this router */ |
| 323 | BOOL fail_verify_sender; /* Fail verify if sender match this router */ |
| 324 | BOOL gid_set; /* Flag to indicate gid is set */ |
| 325 | BOOL initgroups; /* TRUE if initgroups is required */ |
| 326 | BOOL log_as_local; /* TRUE logs as a local delivery */ |
| 327 | BOOL more; /* If FALSE, do no more if this one fails */ |
| 328 | BOOL pass_on_timeout; /* Treat timeout DEFERs as fails */ |
| 329 | BOOL prefix_optional; /* Just what it says */ |
| 330 | BOOL repeat_use; /* If FALSE, skip if ancestor used it */ |
| 331 | BOOL retry_use_local_part; /* Just what it says */ |
| 332 | BOOL same_domain_copy_routing; /* TRUE => copy routing for same domain */ |
| 333 | BOOL self_rewrite; /* TRUE to rewrite headers if making local */ |
| 334 | BOOL suffix_optional; /* As it says */ |
| 335 | BOOL verify_only; /* Skip this router if not verifying */ |
| 336 | BOOL verify_recipient; /* Use this router when verifying a recipient*/ |
| 337 | BOOL verify_sender; /* Use this router when verifying a sender */ |
| 338 | BOOL uid_set; /* Flag to indicate uid is set */ |
| 339 | BOOL unseen; /* If TRUE carry on, even after success */ |
| 340 | BOOL dsn_lasthop; /* If TRUE, this router is a DSN endpoint */ |
| 341 | |
| 342 | int self_code; /* Encoded version of "self" */ |
| 343 | uid_t uid; /* Fixed uid value */ |
| 344 | gid_t gid; /* Fixed gid value */ |
| 345 | |
| 346 | host_item *fallback_hostlist; /* For remote transport (block chain) */ |
| 347 | transport_instance *transport; /* Transport block (when found) */ |
| 348 | struct router_instance *pass_router; /* Actual router for passed address */ |
| 349 | struct router_instance *redirect_router; /* Actual router for generated address */ |
| 350 | |
| 351 | dnssec_domains dnssec; |
| 352 | } router_instance; |
| 353 | |
| 354 | |
| 355 | /* Structure for holding information about a type of router. The first six |
| 356 | fields must match driver_info above. */ |
| 357 | |
| 358 | typedef struct router_info { |
| 359 | uschar *driver_name; |
| 360 | optionlist *options; /* Table of private options names */ |
| 361 | int *options_count; /* -> Number of entries in table */ |
| 362 | void *options_block; /* Points to default private block */ |
| 363 | int options_len; /* Length of same in bytes */ |
| 364 | void (*init)( /* Initialization function */ |
| 365 | struct router_instance *); |
| 366 | /****/ |
| 367 | int (*code)( /* Main entry point */ |
| 368 | router_instance *, |
| 369 | struct address_item *, |
| 370 | struct passwd *, |
| 371 | int, |
| 372 | struct address_item **, |
| 373 | struct address_item **, |
| 374 | struct address_item **, |
| 375 | struct address_item **); |
| 376 | void (*tidyup)( /* Tidyup function */ |
| 377 | struct router_instance *); |
| 378 | int ri_flags; /* Descriptive flags */ |
| 379 | } router_info; |
| 380 | |
| 381 | |
| 382 | /* Structure for holding information about a lookup type. */ |
| 383 | |
| 384 | #include "lookupapi.h" |
| 385 | |
| 386 | |
| 387 | /* Structure for holding information about the configured authentication |
| 388 | mechanisms */ |
| 389 | |
| 390 | typedef struct auth_instance { |
| 391 | struct auth_instance *next; |
| 392 | uschar *name; /* Exim instance name */ |
| 393 | struct auth_info *info; /* Pointer to driver info block */ |
| 394 | void *options_block; /* Pointer to private options */ |
| 395 | uschar *driver_name; /* Must be first */ |
| 396 | uschar *advertise_condition; /* Are we going to advertise this?*/ |
| 397 | uschar *client_condition; /* Should the client try this? */ |
| 398 | uschar *public_name; /* Advertised name */ |
| 399 | uschar *set_id; /* String to set when server as authenticated id */ |
| 400 | uschar *set_client_id; /* String to set when client as client_authenticated id */ |
| 401 | uschar *mail_auth_condition; /* Condition for AUTH on MAIL command */ |
| 402 | uschar *server_debug_string; /* Debugging output */ |
| 403 | uschar *server_condition; /* Authorization condition */ |
| 404 | BOOL client; /* TRUE if client option(s) set */ |
| 405 | BOOL server; /* TRUE if server options(s) set */ |
| 406 | BOOL advertised; /* Set TRUE when advertised */ |
| 407 | } auth_instance; |
| 408 | |
| 409 | |
| 410 | /* Structure for holding information about an authentication mechanism. The |
| 411 | first six fields must match driver_info above. */ |
| 412 | |
| 413 | typedef struct auth_info { |
| 414 | uschar *driver_name; /* e.g. "condition" */ |
| 415 | optionlist *options; /* Table of private options names */ |
| 416 | int *options_count; /* -> Number of entries in table */ |
| 417 | void *options_block; /* Points to default private block */ |
| 418 | int options_len; /* Length of same in bytes */ |
| 419 | void (*init)( /* initialization function */ |
| 420 | struct auth_instance *); |
| 421 | /****/ |
| 422 | int (*servercode)( /* server function */ |
| 423 | auth_instance *, /* the instance data */ |
| 424 | uschar *); /* rest of AUTH command */ |
| 425 | int (*clientcode)( /* client function */ |
| 426 | struct auth_instance *, |
| 427 | void *, /* smtp conn, with socket, output and input buffers */ |
| 428 | int, /* command timeout */ |
| 429 | uschar *, /* buffer for reading response */ |
| 430 | int); /* sizeof buffer */ |
| 431 | void (*version_report)( /* diagnostic version reporting */ |
| 432 | FILE *); /* I/O stream to print to */ |
| 433 | } auth_info; |
| 434 | |
| 435 | |
| 436 | /* Structure for holding a single IP address and port; used for the chain of |
| 437 | addresses and ports for the local host. Make the char string large enough to |
| 438 | hold an IPv6 address. */ |
| 439 | |
| 440 | typedef struct ip_address_item { |
| 441 | struct ip_address_item *next; |
| 442 | int port; |
| 443 | BOOL v6_include_v4; /* Used in the daemon */ |
| 444 | uschar address[46]; |
| 445 | } ip_address_item; |
| 446 | |
| 447 | /* Structure for chaining together arbitrary strings. */ |
| 448 | |
| 449 | typedef struct string_item { |
| 450 | struct string_item *next; |
| 451 | uschar *text; |
| 452 | } string_item; |
| 453 | |
| 454 | /* Information about a soft delivery failure, for use when calculating |
| 455 | retry information. It's separate from the address block, because there |
| 456 | can be a chain of them for SMTP deliveries where multiple IP addresses |
| 457 | can be tried. */ |
| 458 | |
| 459 | typedef struct retry_item { |
| 460 | struct retry_item *next; /* for chaining */ |
| 461 | uschar *key; /* string identifying host/address/message */ |
| 462 | int basic_errno; /* error code for this destination */ |
| 463 | int more_errno; /* additional error information */ |
| 464 | uschar *message; /* local error message */ |
| 465 | int flags; /* see below */ |
| 466 | } retry_item; |
| 467 | |
| 468 | /* Retry data flags */ |
| 469 | |
| 470 | #define rf_delete 0x0001 /* retry info is to be deleted */ |
| 471 | #define rf_host 0x0002 /* retry info is for a remote host */ |
| 472 | #define rf_message 0x0004 /* retry info is for a host+message */ |
| 473 | |
| 474 | /* Information about a constructed message that is to be sent using the |
| 475 | autoreply transport. This is pointed to from the address block. */ |
| 476 | |
| 477 | typedef struct reply_item { |
| 478 | uschar *from; /* ) */ |
| 479 | uschar *reply_to; /* ) */ |
| 480 | uschar *to; /* ) */ |
| 481 | uschar *cc; /* ) specific header fields */ |
| 482 | uschar *bcc; /* ) */ |
| 483 | uschar *subject; /* ) */ |
| 484 | uschar *headers; /* misc other headers, concatenated */ |
| 485 | uschar *text; /* text string body */ |
| 486 | uschar *file; /* file body */ |
| 487 | BOOL file_expand; /* expand the body */ |
| 488 | int expand_forbid; /* expansion lockout flags */ |
| 489 | uschar *logfile; /* file to keep a log in */ |
| 490 | uschar *oncelog; /* file to keep records in for once only */ |
| 491 | time_t once_repeat; /* time to repeat "once only" */ |
| 492 | BOOL return_message; /* send back the original message */ |
| 493 | } reply_item; |
| 494 | |
| 495 | |
| 496 | /* The address_item structure contains many fields which are used at various |
| 497 | times while delivering a message. Some are used only for remote deliveries; |
| 498 | some only for local. A particular set of fields is copied whenever a child |
| 499 | address is created. For convenience, we keep those fields in a separate |
| 500 | sub-structure so they can be copied in one go. This also means I won't forget |
| 501 | to edit the various copying places when new to-be-copied fields are added. */ |
| 502 | |
| 503 | typedef struct address_item_propagated { |
| 504 | uschar *address_data; /* arbitrary data to keep with the address */ |
| 505 | uschar *domain_data; /* from "domains" lookup */ |
| 506 | uschar *localpart_data; /* from "local_parts" lookup */ |
| 507 | uschar *errors_address; /* where to send errors (NULL => sender) */ |
| 508 | header_line *extra_headers; /* additional headers */ |
| 509 | uschar *remove_headers; /* list of those to remove */ |
| 510 | |
| 511 | #ifdef EXPERIMENTAL_SRS |
| 512 | uschar *srs_sender; /* Change return path when delivering */ |
| 513 | #endif |
| 514 | BOOL ignore_error:1; /* ignore delivery error */ |
| 515 | #ifdef SUPPORT_I18N |
| 516 | BOOL utf8_msg:1; /* requires SMTPUTF8 processing */ |
| 517 | BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */ |
| 518 | BOOL utf8_downcvt_maybe:1; /* optional downconvert on delivery */ |
| 519 | #endif |
| 520 | } address_item_propagated; |
| 521 | |
| 522 | |
| 523 | /* The main address structure. Note that fields that are to be copied to |
| 524 | generated addresses should be put in the address_item_propagated structure (see |
| 525 | above) rather than directly into the address_item structure. */ |
| 526 | |
| 527 | typedef struct address_item { |
| 528 | struct address_item *next; /* for chaining addresses */ |
| 529 | struct address_item *parent; /* parent address */ |
| 530 | struct address_item *first; /* points to first after group delivery */ |
| 531 | struct address_item *dupof; /* points to address this is a duplicate of */ |
| 532 | |
| 533 | router_instance *start_router; /* generated address starts here */ |
| 534 | router_instance *router; /* the router that routed */ |
| 535 | transport_instance *transport; /* the transport to use */ |
| 536 | |
| 537 | host_item *host_list; /* host data for the transport */ |
| 538 | host_item *host_used; /* host that took delivery or failed hard */ |
| 539 | host_item *fallback_hosts; /* to try if delivery defers */ |
| 540 | |
| 541 | reply_item *reply; /* data for autoreply */ |
| 542 | retry_item *retries; /* chain of retry information */ |
| 543 | |
| 544 | uschar *address; /* address being delivered or routed */ |
| 545 | uschar *unique; /* used for disambiguating */ |
| 546 | uschar *cc_local_part; /* caseful local part */ |
| 547 | uschar *lc_local_part; /* lowercased local part */ |
| 548 | uschar *local_part; /* points to cc or lc version */ |
| 549 | uschar *prefix; /* stripped prefix of local part */ |
| 550 | uschar *suffix; /* stripped suffix of local part */ |
| 551 | const uschar *domain; /* working domain (lower cased) */ |
| 552 | |
| 553 | uschar *address_retry_key; /* retry key including full address */ |
| 554 | uschar *domain_retry_key; /* retry key for domain only */ |
| 555 | |
| 556 | uschar *current_dir; /* current directory for transporting */ |
| 557 | uschar *home_dir; /* home directory for transporting */ |
| 558 | uschar *message; /* error message */ |
| 559 | uschar *user_message; /* error message that can be sent over SMTP |
| 560 | or quoted in bounce message */ |
| 561 | uschar *onetime_parent; /* saved original parent for onetime */ |
| 562 | uschar **pipe_expandn; /* numeric expansions for pipe from filter */ |
| 563 | uschar *return_filename; /* name of return file */ |
| 564 | uschar *self_hostname; /* after self=pass */ |
| 565 | uschar *shadow_message; /* info about shadow transporting */ |
| 566 | |
| 567 | #ifdef SUPPORT_TLS |
| 568 | uschar *cipher; /* Cipher used for transport */ |
| 569 | void *ourcert; /* Certificate offered to peer, binary */ |
| 570 | void *peercert; /* Certificate from peer, binary */ |
| 571 | uschar *peerdn; /* DN of server's certificate */ |
| 572 | int ocsp; /* OCSP status of peer cert */ |
| 573 | #endif |
| 574 | |
| 575 | #ifdef EXPERIMENTAL_DSN_INFO |
| 576 | const uschar *smtp_greeting; /* peer self-identification */ |
| 577 | const uschar *helo_response; /* peer message */ |
| 578 | #endif |
| 579 | |
| 580 | uschar *authenticator; /* auth driver name used by transport */ |
| 581 | uschar *auth_id; /* auth "login" name used by transport */ |
| 582 | uschar *auth_sndr; /* AUTH arg to SMTP MAIL, used by transport */ |
| 583 | |
| 584 | uschar *dsn_orcpt; /* DSN orcpt value */ |
| 585 | int dsn_flags; /* DSN flags */ |
| 586 | int dsn_aware; /* DSN aware flag */ |
| 587 | |
| 588 | uid_t uid; /* uid for transporting */ |
| 589 | gid_t gid; /* gid for transporting */ |
| 590 | |
| 591 | /* flags */ |
| 592 | struct { |
| 593 | BOOL af_allow_file:1; /* allow file in generated address */ |
| 594 | BOOL af_allow_pipe:1; /* allow pipe in generated address */ |
| 595 | BOOL af_allow_reply:1; /* allow autoreply in generated address */ |
| 596 | BOOL af_dr_retry_exists:1; /* router retry record exists */ |
| 597 | BOOL af_expand_pipe:1; /* expand pipe arguments */ |
| 598 | BOOL af_file:1; /* file delivery; always with pfr */ |
| 599 | BOOL af_gid_set:1; /* gid field is set */ |
| 600 | BOOL af_home_expanded:1; /* home_dir is already expanded */ |
| 601 | BOOL af_initgroups:1; /* use initgroups() for local transporting */ |
| 602 | BOOL af_local_host_removed:1; /* local host was backup */ |
| 603 | BOOL af_lt_retry_exists:1; /* local transport retry exists */ |
| 604 | BOOL af_pfr:1; /* pipe or file or reply delivery */ |
| 605 | BOOL af_retry_skipped:1; /* true if retry caused some skipping */ |
| 606 | BOOL af_retry_timedout:1; /* true if retry timed out */ |
| 607 | BOOL af_uid_set:1; /* uid field is set */ |
| 608 | BOOL af_hide_child:1; /* hide child in bounce/defer msgs */ |
| 609 | BOOL af_sverify_told:1; /* sender verify failure notified */ |
| 610 | BOOL af_verify_pmfail:1; /* verify failure was postmaster callout */ |
| 611 | BOOL af_verify_nsfail:1; /* verify failure was null sender callout */ |
| 612 | BOOL af_homonym:1; /* an ancestor has same address */ |
| 613 | BOOL af_verify_routed:1; /* for cached sender verify: routed OK */ |
| 614 | BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */ |
| 615 | BOOL af_include_affixes:1; /* delivered with affixes in RCPT */ |
| 616 | BOOL af_cert_verified:1; /* delivered with verified TLS cert */ |
| 617 | BOOL af_pass_message:1; /* pass message in bounces */ |
| 618 | BOOL af_bad_reply:1; /* filter could not generate autoreply */ |
| 619 | BOOL af_tcp_fastopen_conn:1; /* delivery connection used TCP Fast Open */ |
| 620 | BOOL af_tcp_fastopen:1; /* delivery usefully used TCP Fast Open */ |
| 621 | BOOL af_pipelining:1; /* delivery used (traditional) pipelining */ |
| 622 | #ifndef DISABLE_PRDR |
| 623 | BOOL af_prdr_used:1; /* delivery used SMTP PRDR */ |
| 624 | #endif |
| 625 | BOOL af_chunking_used:1; /* delivery used SMTP CHUNKING */ |
| 626 | BOOL af_force_command:1; /* force_command in pipe transport */ |
| 627 | #ifdef SUPPORT_DANE |
| 628 | BOOL af_dane_verified:1; /* TLS cert verify done with DANE */ |
| 629 | #endif |
| 630 | #ifdef SUPPORT_I18N |
| 631 | BOOL af_utf8_downcvt:1; /* downconvert was done for delivery */ |
| 632 | #endif |
| 633 | } flags; |
| 634 | |
| 635 | unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; |
| 636 | unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; |
| 637 | int mode; /* mode for local transporting to a file */ |
| 638 | int more_errno; /* additional error information */ |
| 639 | /* (may need to hold a timestamp) */ |
| 640 | unsigned int delivery_usec; /* subsecond part of delivery time */ |
| 641 | |
| 642 | short int basic_errno; /* status after failure */ |
| 643 | unsigned short child_count; /* number of child addresses */ |
| 644 | short int return_file; /* fileno of return data file */ |
| 645 | short int special_action; /* ( used when when deferred or failed */ |
| 646 | /* ( also */ |
| 647 | /* ( contains = or - when successful SMTP delivered */ |
| 648 | /* ( also */ |
| 649 | /* ( contains verify rc in sender verify cache */ |
| 650 | short int transport_return; /* result of delivery attempt */ |
| 651 | address_item_propagated prop; /* fields that are propagated to children */ |
| 652 | } address_item; |
| 653 | |
| 654 | /* The table of header names consists of items of this type */ |
| 655 | |
| 656 | typedef struct { |
| 657 | uschar *name; |
| 658 | int len; |
| 659 | BOOL allow_resent; |
| 660 | int htype; |
| 661 | } header_name; |
| 662 | |
| 663 | /* Chain of information about errors (e.g. bad addresses) */ |
| 664 | |
| 665 | typedef struct error_block { |
| 666 | struct error_block *next; |
| 667 | const uschar *text1; |
| 668 | uschar *text2; |
| 669 | } error_block; |
| 670 | |
| 671 | /* Chain of file names when processing the queue */ |
| 672 | |
| 673 | typedef struct queue_filename { |
| 674 | struct queue_filename *next; |
| 675 | uschar dir_uschar; |
| 676 | uschar text[1]; |
| 677 | } queue_filename; |
| 678 | |
| 679 | /* Chain of items of retry information, read from the retry config. */ |
| 680 | |
| 681 | typedef struct retry_rule { |
| 682 | struct retry_rule *next; |
| 683 | int rule; |
| 684 | int timeout; |
| 685 | int p1; |
| 686 | int p2; |
| 687 | } retry_rule; |
| 688 | |
| 689 | typedef struct retry_config { |
| 690 | struct retry_config *next; |
| 691 | uschar *pattern; |
| 692 | int basic_errno; |
| 693 | int more_errno; |
| 694 | uschar *senders; |
| 695 | retry_rule *rules; |
| 696 | } retry_config; |
| 697 | |
| 698 | /* Structure for each node in a tree, of which there are various kinds */ |
| 699 | |
| 700 | typedef struct tree_node { |
| 701 | struct tree_node *left; /* pointer to left child */ |
| 702 | struct tree_node *right; /* pointer to right child */ |
| 703 | union |
| 704 | { |
| 705 | void *ptr; /* pointer to data */ |
| 706 | int val; /* or integer data */ |
| 707 | } data; |
| 708 | uschar balance; /* balancing factor */ |
| 709 | uschar name[1]; /* node name - variable length */ |
| 710 | } tree_node; |
| 711 | |
| 712 | /* Structure for holding time-limited data such as DNS returns. |
| 713 | We use this rather than extending tree_node to avoid wasting |
| 714 | space for most tree use (variables...) at the cost of complexity |
| 715 | for the lookups cache */ |
| 716 | |
| 717 | typedef struct expiring_data { |
| 718 | time_t expiry; /* if nonzero, data invalid after this time */ |
| 719 | void *ptr; /* pointer to data */ |
| 720 | } expiring_data; |
| 721 | |
| 722 | /* Structure for holding the handle and the cached last lookup for searches. |
| 723 | This block is pointed to by the tree entry for the file. The file can get |
| 724 | closed if too many are opened at once. There is a LRU chain for deciding which |
| 725 | to close. */ |
| 726 | |
| 727 | typedef struct search_cache { |
| 728 | void *handle; /* lookup handle, or NULL if closed */ |
| 729 | int search_type; /* search type */ |
| 730 | tree_node *up; /* LRU up pointer */ |
| 731 | tree_node *down; /* LRU down pointer */ |
| 732 | tree_node *item_cache; /* tree of cached results */ |
| 733 | } search_cache; |
| 734 | |
| 735 | /* Structure for holding a partially decoded DNS record; the name has been |
| 736 | uncompressed, but the data pointer is into the raw data. */ |
| 737 | |
| 738 | typedef struct { |
| 739 | uschar name[DNS_MAXNAME]; /* domain name */ |
| 740 | int type; /* record type */ |
| 741 | unsigned short ttl; /* time-to-live, seconds */ |
| 742 | int size; /* size of data */ |
| 743 | const uschar *data; /* pointer to data */ |
| 744 | } dns_record; |
| 745 | |
| 746 | /* Structure for holding the result of a DNS query. A touch over |
| 747 | 64k big, so take care to release as soon as possible. */ |
| 748 | |
| 749 | typedef struct { |
| 750 | int answerlen; /* length of the answer */ |
| 751 | uschar answer[NS_MAXMSG]; /* the answer itself */ |
| 752 | } dns_answer; |
| 753 | |
| 754 | /* Structure for holding the intermediate data while scanning a DNS answer |
| 755 | block. */ |
| 756 | |
| 757 | typedef struct { |
| 758 | int rrcount; /* count of RRs in the answer */ |
| 759 | const uschar *aptr; /* pointer in the answer while scanning */ |
| 760 | dns_record srr; /* data from current record in scan */ |
| 761 | } dns_scan; |
| 762 | |
| 763 | /* Structure for holding a chain of IP addresses that are extracted from |
| 764 | an A, AAAA, or A6 record. For the first two, there is only ever one address, |
| 765 | but the chaining feature of A6 allows for several addresses to be realized from |
| 766 | a single initial A6 record. The structure defines the address field of length |
| 767 | 1. In use, a suitable sized block is obtained to hold the complete textual |
| 768 | address. */ |
| 769 | |
| 770 | typedef struct dns_address { |
| 771 | struct dns_address *next; |
| 772 | uschar address[1]; |
| 773 | } dns_address; |
| 774 | |
| 775 | /* Structure used for holding intermediate data during MD5 computations. */ |
| 776 | |
| 777 | typedef struct md5 { |
| 778 | unsigned int length; |
| 779 | unsigned int abcd[4]; |
| 780 | } |
| 781 | md5; |
| 782 | |
| 783 | /* Structure used for holding intermediate data during SHA-1 computations. */ |
| 784 | |
| 785 | typedef struct sha1 { |
| 786 | unsigned int H[5]; |
| 787 | unsigned int length; |
| 788 | } sha1; |
| 789 | |
| 790 | /* A client-initiated connection. If TLS, the second element is non-NULL */ |
| 791 | typedef struct { |
| 792 | int sock; |
| 793 | void * tls_ctx; |
| 794 | } client_conn_ctx; |
| 795 | |
| 796 | |
| 797 | /* Structure used to hold incoming packets of SMTP responses for a specific |
| 798 | socket. The packets which may contain multiple lines (and in some cases, |
| 799 | multiple responses). */ |
| 800 | |
| 801 | typedef struct smtp_inblock { |
| 802 | client_conn_ctx * cctx; /* the connection */ |
| 803 | int buffersize; /* the size of the buffer */ |
| 804 | uschar *ptr; /* current position in the buffer */ |
| 805 | uschar *ptrend; /* end of data in the buffer */ |
| 806 | uschar *buffer; /* the buffer itself */ |
| 807 | } smtp_inblock; |
| 808 | |
| 809 | /* Structure used to hold buffered outgoing packets of SMTP commands for a |
| 810 | specific socket. The packets which may contain multiple lines when pipelining |
| 811 | is in use. */ |
| 812 | |
| 813 | typedef struct smtp_outblock { |
| 814 | client_conn_ctx * cctx; /* the connection */ |
| 815 | int cmd_count; /* count of buffered commands */ |
| 816 | int buffersize; /* the size of the buffer */ |
| 817 | BOOL authenticating; /* TRUE when authenticating */ |
| 818 | uschar *ptr; /* current position in the buffer */ |
| 819 | uschar *buffer; /* the buffer itself */ |
| 820 | } smtp_outblock; |
| 821 | |
| 822 | /* Structure to hold information about the source of redirection information */ |
| 823 | |
| 824 | typedef struct redirect_block { |
| 825 | uschar *string; /* file name or string */ |
| 826 | uid_t *owners; /* allowed file owners */ |
| 827 | gid_t *owngroups; /* allowed file groups */ |
| 828 | struct passwd *pw; /* possible owner if not NULL */ |
| 829 | int modemask; /* forbidden bits */ |
| 830 | BOOL isfile; /* TRUE if string is a file name */ |
| 831 | BOOL check_owner; /* TRUE, FALSE, or TRUE_UNSET */ |
| 832 | BOOL check_group; /* TRUE, FALSE, or TRUE_UNSET */ |
| 833 | } redirect_block; |
| 834 | |
| 835 | /* Structure for passing arguments to check_host() */ |
| 836 | |
| 837 | typedef struct check_host_block { |
| 838 | const uschar *host_name; |
| 839 | const uschar *host_address; |
| 840 | const uschar *host_ipv4; |
| 841 | BOOL negative; |
| 842 | } check_host_block; |
| 843 | |
| 844 | /* Structure for remembering lookup data when caching the result of |
| 845 | a lookup in a named list. */ |
| 846 | |
| 847 | typedef struct namedlist_cacheblock { |
| 848 | struct namedlist_cacheblock *next; |
| 849 | uschar *key; |
| 850 | uschar *data; |
| 851 | } namedlist_cacheblock; |
| 852 | |
| 853 | /* Structure for holding data for an entry in a named list */ |
| 854 | |
| 855 | typedef struct namedlist_block { |
| 856 | const uschar *string; /* the list string */ |
| 857 | namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ |
| 858 | int number; /* the number of the list for caching */ |
| 859 | } namedlist_block; |
| 860 | |
| 861 | /* Structures for Access Control Lists */ |
| 862 | |
| 863 | typedef struct acl_condition_block { |
| 864 | struct acl_condition_block *next; |
| 865 | uschar *arg; |
| 866 | int type; |
| 867 | union { |
| 868 | BOOL negated; |
| 869 | uschar *varname; |
| 870 | } u; |
| 871 | } acl_condition_block; |
| 872 | |
| 873 | typedef struct acl_block { |
| 874 | struct acl_block *next; |
| 875 | acl_condition_block *condition; |
| 876 | int verb; |
| 877 | } acl_block; |
| 878 | |
| 879 | /* smtp transport calc outbound_ip */ |
| 880 | typedef BOOL (*oicf) (uschar *message_id, void *data); |
| 881 | |
| 882 | /* DKIM information for transport */ |
| 883 | struct ob_dkim { |
| 884 | uschar *dkim_domain; |
| 885 | uschar *dkim_identity; |
| 886 | uschar *dkim_private_key; |
| 887 | uschar *dkim_selector; |
| 888 | uschar *dkim_canon; |
| 889 | uschar *dkim_sign_headers; |
| 890 | uschar *dkim_strict; |
| 891 | uschar *dkim_hash; |
| 892 | uschar *dkim_timestamps; |
| 893 | BOOL dot_stuffed; |
| 894 | BOOL force_bodyhash; |
| 895 | #ifdef EXPERIMENTAL_ARC |
| 896 | uschar *arc_signspec; |
| 897 | #endif |
| 898 | }; |
| 899 | |
| 900 | /* End of structs.h */ |