]> git.ipfire.org Git - thirdparty/dovecot/core.git/log
thirdparty/dovecot/core.git
19 hours agofts: Correctly handle internal http-client response errors main
Michael M Slusarz [Sun, 16 Jan 2022 02:11:52 +0000 (19:11 -0700)] 
fts: Correctly handle internal http-client response errors

Previously, only server triggered 5xx errors would cause a retry. However,
there are multiple categories of errors from http-client that should
also cause a retry (9xxx errors).

e.g., setting Tika to restart after every processed file can easily
cause either 9003 (connect failed) or 9005 (connection_lost) errors, which
is a temporary condition.

19 hours agofts: Don't send request to Tika if there is no body text
Michael M Slusarz [Sat, 15 Jan 2022 22:24:28 +0000 (15:24 -0700)] 
fts: Don't send request to Tika if there is no body text

Nothing to parse, so waste of network RT, and Tika will log error anyway

19 hours agolib-var-expand-crypt: Check that hex decoding actually succeeds
Aki Tuomi [Fri, 24 Apr 2026 11:13:03 +0000 (14:13 +0300)] 
lib-var-expand-crypt: Check that hex decoding actually succeeds

Found by Aurelien DESBRIERES <aurelien@hackers.camp>

19 hours agolib-var-expand-crypt: Fix invalid cipher test
Aki Tuomi [Fri, 24 Apr 2026 11:14:23 +0000 (14:14 +0300)] 
lib-var-expand-crypt: Fix invalid cipher test

19 hours agolib-var-expand-crypt: Fix error matching in tests
Aki Tuomi [Fri, 24 Apr 2026 11:13:54 +0000 (14:13 +0300)] 
lib-var-expand-crypt: Fix error matching in tests

20 hours agolib-sql: sqlite - Apply sqlite_journal_mode via PRAGMA
Timo Sirainen [Tue, 21 Apr 2026 11:12:02 +0000 (11:12 +0000)] 
lib-sql: sqlite - Apply sqlite_journal_mode via PRAGMA

The sqlite_journal_mode setting was never actually applied to the
database. The code added SQLITE_OPEN_WAL to sqlite3_open_v2() flags,
but that flag is documented as VFS-internal and has no effect on the
journal mode of the database.

Issue a 'PRAGMA journal_mode = <mode>' statement after connecting so
the setting takes effect. Without this, databases remained in the
default rollback journal mode, where readers block on writers and
writers block on readers, causing spurious 'database is locked'
failures under concurrency.

20 hours agolib-storage: Auto-rename non-NFC subscription file entries to NFC on read
Timo Sirainen [Mon, 27 Apr 2026 10:10:55 +0000 (10:10 +0000)] 
lib-storage: Auto-rename non-NFC subscription file entries to NFC on read

Mailbox listing already auto-renames non-NFC mailbox names to NFC form
during iteration. Apply the same treatment to the subscription file:
when mailbox_list_subscriptions_refresh reads a subscription whose name
is not in NFC form, insert the NFC version into the in-memory
subscription tree and rewrite the file on disk to use the NFC name.

The rewrite first adds the NFC subscription and then removes the
non-NFC one, so a crash between the two leaves the subscription intact
under the old name and the next refresh retries. If either subsfile
operation fails, log the error and stop processing further renames.

20 hours agolib-storage: Remove unnecessary duplicate data stack frame
Timo Sirainen [Mon, 27 Apr 2026 10:21:29 +0000 (13:21 +0300)] 
lib-storage: Remove unnecessary duplicate data stack frame

20 hours agolib-storage: Normalize subscription name to NFC in mailbox_list_set_subscribed
Timo Sirainen [Mon, 27 Apr 2026 10:10:45 +0000 (10:10 +0000)] 
lib-storage: Normalize subscription name to NFC in mailbox_list_set_subscribed

When mailbox_list_normalize_names_to_nfc is enabled, normalize the
subscription name to NFC before passing it to the backend. Ensures that
subscribe/unsubscribe operations on non-NFC mailbox names hit the same
entry as the NFC name, matching the existing NFC handling for mailbox
listing.

20 hours agologin-proxy: Fix crash with rawlog and multiplexing during reconnection
Timo Sirainen [Thu, 23 Apr 2026 10:36:26 +0000 (13:36 +0300)] 
login-proxy: Fix crash with rawlog and multiplexing during reconnection

If login_proxy_rawlog_dir was enabled, reconnection (especially with
immediate SSL like SMTPS) caused a panic in proxy_rawlog_deinit().
login_proxy_disconnect() destroyed server_input directly, leaving
rawlog_input/rawlog_output pointing to freed streams. On reconnect the
new server_input no longer matched rawlog_input, tripping the
assertions in proxy_rawlog_deinit().

Fix this by having login_proxy_disconnect() tear down the stream chain
(multiplex + rawlog) properly before destroying server_input, and by
clearing pre_rawlog_input/output in proxy_rawlog_deinit().

Also reorder login_proxy_starttls() so multiplex is removed before
rawlog. Multiplex sits on top of rawlog, so rawlog_deinit()'s
server_input == rawlog_input assertion requires multiplex to be gone
first.

proxy_multiplex_deinit() gains a NULL check so it is safe to call
unconditionally from login_proxy_disconnect().

20 hours agologin-proxy: Extract proxy_multiplex_deinit()
Timo Sirainen [Wed, 22 Apr 2026 15:31:06 +0000 (18:31 +0300)] 
login-proxy: Extract proxy_multiplex_deinit()

The same multiplex teardown was inlined in login_proxy_starttls() and
login_proxy_detach(). Extract it into a helper. No functional change.

20 hours agolib: Fix truncation of long log messages with event_set_log_message_callback()
Timo Sirainen [Thu, 23 Apr 2026 10:35:34 +0000 (13:35 +0300)] 
lib: Fix truncation of long log messages with event_set_log_message_callback()

event_get_log_message() cached a pointer from str_c(glmctx->log_prefix)
at the top of the function, then kept appending to the same string_t
buffer via str_vprintfa() / str_append(). When the appended data
exceeded the buffer's current allocation, the buffer was reallocated
and the cached pointer was left pointing at the old (truncated) copy.

The stale pointer was then passed to the log_message_callback as
in_message, and also used in the equality check that decides whether
the callback returned its input buffer.

Fix by calling str_c() after each mutation so the pointer always
reflects the current buffer.

20 hours agolib, global: iostream_rawlog_create*() - Add event and setting name parameters
Timo Sirainen [Thu, 5 Feb 2026 13:53:37 +0000 (15:53 +0200)] 
lib, global: iostream_rawlog_create*() - Add event and setting name parameters

Log errors using the event. Also if creation failed due to directory not
existing or not writable, log a debug event.

46 hours agolib: ostream-multiplex - Take ownership of parent cork across wrap/unwrap
Timo Sirainen [Sat, 25 Apr 2026 16:08:32 +0000 (19:08 +0300)] 
lib: ostream-multiplex - Take ownership of parent cork across wrap/unwrap

The multiplex's interaction with the parent ostream's cork was loose:
the channel send paths corked the parent on demand and the trailing
o_stream_multiplex_sendv() blindly uncorked it, even when the cork
had been put there by someone outside the multiplex. That made it
ambiguous who owns the parent's cork while a multiplex is wrapping
it, and easy for a caller to leave the parent corked across a wrap
or to cork it directly through the wrapped pointer and have the
multiplex undo it.

Take ownership explicitly:

 - A new parent_corked bit tracks the cork state the multiplex
   itself has set on the parent. multiplex_cork_parent() asserts
   that the observed cork matches the tracked state on every
   transition, catching any caller that corks/uncorks the parent
   behind the multiplex's back. After the o_stream_(un)cork() call
   it re-reads o_stream_is_corked() so a no-op on a closed/errored
   stream stays consistent with the tracker.
 - The send_packet()/send_stream() transient cork and the matching
   uncork at the tail of o_stream_multiplex_sendv() now go through
   the helper.
 - stream_send_io() in ostream-file.c corks the parent around the
   flush callback, which is the only legal external cork. Undo it
   on entry to o_stream_multiplex_flush() so the invariant
   (parent_corked reflects reality) holds everywhere else.

Transfer the parent's cork across wrap/unwrap. At wrap time, if the
parent is corked, move the cork onto channel 0 - from the caller's
point of view nothing changed, the ostream they got back is corked
and a later o_stream_uncork() on it stays balanced. At destroy time
do the reverse: if channel 0 is corked when it goes away, re-cork
the parent in o_stream_multiplex_try_destroy() before releasing the
multiplex's reference, so a caller still holding the parent ostream
sees the cork preserved.

The transfer cannot go through o_stream_(un)cork(): o_stream_uncork()
flushes data already buffered in the parent (ostream-file.c
buffer_flush(), default cork's o_stream_flush()), which would defeat
the transparency of the transfer - the caller wrapped a corked parent
and expects its buffered bytes to stay buffered until they uncork
channel 0. multiplex_transfer_parent_cork() bypasses the public API
and writes the corked bit directly, asserting first that the parent
is in the expected state and is neither closed nor errored. The
destroy direction uses the same helper for symmetry.

The flush-callback invariant (parent_corked tracks reality) is kept:
the cork is moved off the parent during create, and back on as the
last step of try_destroy() when the multiplex no longer manipulates
the parent.

Adds unit tests covering both transfer directions and the
buffered-parent case that the direct-bit transfer protects against.

4 days agolib-event: Add event_register_callback_prepend()
Timo Sirainen [Fri, 24 Apr 2026 19:07:06 +0000 (19:07 +0000)] 
lib-event: Add event_register_callback_prepend()

A plugin that wants to annotate outgoing events with extra fields has
no good way to get in front of the stats client today. The stats
client registers its event callback in master_service_init(), well
before any module is loaded, and event_register_callback() always
appends - so a plugin's own callback runs after the stats client has
already exported the event.

Add event_register_callback_prepend() for callers that need to run
first. Implementation is a one-line array_push_front() against the
same event_handlers array.

5 days agolib-sasl: Test malformed input
Aki Tuomi [Fri, 24 Apr 2026 07:20:58 +0000 (10:20 +0300)] 
lib-sasl: Test malformed input

5 days agolib-sasl: sasl-server-mech-oauth2 - Fix one byte out of bounds read
Stephan Bosch [Thu, 9 Apr 2026 22:57:37 +0000 (00:57 +0200)] 
lib-sasl: sasl-server-mech-oauth2 - Fix one byte out of bounds read

This could cause a segfault, but so far this was only spotted by an address
sanitizer.

5 days agolib: iostream_fd_unref() - NULL out the pointer like other unref APIs
Timo Sirainen [Wed, 22 Apr 2026 12:06:03 +0000 (15:06 +0300)] 
lib: iostream_fd_unref() - NULL out the pointer like other unref APIs

iostream_fd_unref() takes a pointer-to-pointer argument but did not
set *_ref to NULL after unreferencing. This left fstream->fd_ref in
both file_istream and file_ostream dangling after close, which made
the fstream->fd_ref != NULL guard in stream_closed() and
i_stream_file_close() ineffective if either function was called more
than once on the same stream. A second call would dereference freed
memory, either hitting the refcount > 0 assertion or corrupting the
heap (detected later as a malloc crash).

Observed in managesieve-login during SSL proxying when the post-login
managesieve process crashed shortly after starting: the iostream_fd
shared between the socketpair istream and ostream got double-unrefed
through iostream_fd_proxy_finished() -> iostream_proxy_unref() ->
iostream_pump_unref() -> o_stream_unref().

Fixes:
Panic: file iostream.c: line 28 (iostream_fd_unref): assertion failed: (ref->refcount > 0)

5 days agolib-sql: Link libsql.la with SSL if cassandra is not plugin
Aki Tuomi [Thu, 23 Apr 2026 16:06:19 +0000 (19:06 +0300)] 
lib-sql: Link libsql.la with SSL if cassandra is not plugin

6 days agoconfig: Add __weak__ to rest of the structs too
Aki Tuomi [Wed, 22 Apr 2026 11:19:51 +0000 (14:19 +0300)] 
config: Add __weak__ to rest of the structs too

7 days agolib-sql: cassandra - Suppress libcrypto's atexit handler
Timo Sirainen [Tue, 21 Apr 2026 12:35:04 +0000 (12:35 +0000)] 
lib-sql: cassandra - Suppress libcrypto's atexit handler

libcassandra initializes libcrypto lazily on first SSL use.  In processes
that do not load lib-ssl-iostream (e.g. dict-async with a cassandra SSL
dict backend), nobody else passes OPENSSL_INIT_NO_ATEXIT first, so
libcrypto registers atexit(OPENSSL_cleanup).

That handler runs after main() returns, which is after Dovecot has
dlclose()d libdriver_cassandra.so and its libcassandra dependency.
OPENSSL_cleanup() then walks per-thread OpenSSL state holding method
pointers into unmapped libcassandra/libuv code, crashing the process at
exit.

Call OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL) from
driver_cassandra_init() so that even in minimal processes where
dovecot_openssl_common_global_ref() is never called, libcrypto's unsafe
atexit handler is suppressed.  The per-process OpenSSL state is leaked at
exit, which is harmless as the kernel reclaims it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7 days agolib-ssl-iostream: Pass OPENSSL_INIT_NO_ATEXIT to OPENSSL_init_ssl()
Timo Sirainen [Tue, 21 Apr 2026 12:34:53 +0000 (12:34 +0000)] 
lib-ssl-iostream: Pass OPENSSL_INIT_NO_ATEXIT to OPENSSL_init_ssl()

Prevent libcrypto from registering its own atexit() handler.  libcrypto's
handler runs after main() returns, which is after Dovecot has dlclose()d
plugins that may have registered OpenSSL callbacks (e.g. libcassandra).
Accessing those unmapped code pages from OPENSSL_cleanup() crashes the
process at exit.

Dovecot already calls OPENSSL_cleanup() explicitly via
dovecot_openssl_common_global_unref() while the relevant modules are still
loaded, so libcrypto's own atexit handler was redundant and unsafe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 days agolib-dcrypt: Validate hex_to_binary() return in key loading paths
Aki Tuomi [Mon, 20 Apr 2026 11:32:56 +0000 (14:32 +0300)] 
lib-dcrypt: Validate hex_to_binary() return in key loading paths

Check return value of hex_to_binary() at all call sites that process
untrusted key material. Previously ignored return value meant invalid
hex input (non-hex characters) would silently produce truncated buffers
rather than an explicit error.

8 days agolib-dcrypt: Limit key lengths and replace VLA with dynamic buffer
Aki Tuomi [Wed, 8 Apr 2026 12:55:47 +0000 (15:55 +0300)] 
lib-dcrypt: Limit key lengths and replace VLA with dynamic buffer

Reject oversized key material early to prevent large datastack/buffer
allocations from untrusted input. DCRYPT_MAX_KEY_BUFFER_SIZE = 16 KB
for raw keys, x2 for hex-encoded fields, x4 for JWK/PEM.

Replace VLA (unsigned char keybuf[keylen]) in
dcrypt_openssl_load_public_key_dovecot_v2() with a pool_datastack_create()
buffer to avoid potential stack overflow.

8 days agomail-crypt: Use crypt_settings_to_flags()
Aki Tuomi [Wed, 8 Apr 2026 12:38:48 +0000 (15:38 +0300)] 
mail-crypt: Use crypt_settings_to_flags()

Fixes crash in mail crypt plugin when HMAC based algorithm
is used.

Also fixes that ChaCha20-Poly1305 will use AEAD instead of HMAC.

8 days agomail-crypt: Add crypt_settings_to_flags()
Aki Tuomi [Wed, 8 Apr 2026 12:38:29 +0000 (15:38 +0300)] 
mail-crypt: Add crypt_settings_to_flags()

Returns correct flags for given settings.

8 days agolib-index: Fix dangling index->map pointer when fsck fails in mail_index_map_latest_f...
Aki Tuomi [Sat, 18 Apr 2026 18:00:36 +0000 (21:00 +0300)] 
lib-index: Fix dangling index->map pointer when fsck fails in mail_index_map_latest_file()

If mail_index_fsck() returns -1 (e.g. log lock failure), index->map was
left pointing at new_map. The subsequent mail_index_unmap(&new_map) freed
that object, leaving index->map as a dangling pointer.

Fix by restoring index->map = old_map before breaking on fsck error,
mirroring what the success path already does.

9 days agoquota: quota-status - Limit input buffer size to 1 kB
Timo Sirainen [Fri, 10 Apr 2026 20:50:31 +0000 (23:50 +0300)] 
quota: quota-status - Limit input buffer size to 1 kB

This should be more than enough.

9 days agoauth: ldap - Fix escaping 0x13 control character
Timo Sirainen [Fri, 17 Apr 2026 15:43:13 +0000 (17:43 +0200)] 
auth: ldap - Fix escaping 0x13 control character

Broken by 74a6f1612e7732026e69e8d8489291842df68589

9 days agoconfig: Add __attribute__((weak)) to global variable definitions in all-settings.c
Timo Sirainen [Fri, 17 Apr 2026 12:51:02 +0000 (12:51 +0000)] 
config: Add __attribute__((weak)) to global variable definitions in all-settings.c

all-settings.c copies global variable definitions (e.g. mail_storage_default_settings,
setting_parser_info structs) verbatim from plugin settings files. The same symbols
are also compiled into the plugin .so files. When doveconf dlopen()'s a plugin at
runtime, ASAN detects duplicate definitions and reports an ODR violation.

Fix by injecting __attribute__((weak)) on these definitions as settings-get.pl
generates all-settings.c. ASAN doesn't flag weak+strong as an ODR violation, and
the strong definition from the .so correctly takes precedence at runtime. Static
symbols are excluded since Clang rejects __attribute__((weak)) on internal-linkage
declarations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9 days agolib-language: Fix compiler warning when building without libicu
Timo Sirainen [Fri, 17 Apr 2026 12:34:30 +0000 (14:34 +0200)] 
lib-language: Fix compiler warning when building without libicu

11 days agolib: Fix unsigned underflow in buffer_check_limits() bounds check
Koda Reef [Tue, 24 Mar 2026 18:45:35 +0000 (18:45 +0000)] 
lib: Fix unsigned underflow in buffer_check_limits() bounds check

When pos > buf->max_size, the unsigned subtraction buf->max_size - pos
wraps to a large value instead of triggering the panic. Add an explicit
check before the subtraction so out-of-range positions are caught.

This does not affect buffers created with buffer_create_dynamic(), which
use max_size == SIZE_MAX.

Also add an i_assert in buffer_check_append_limits() to verify the
invariant that used <= writable_size.

2 weeks agolib-sql: cassandra - Fix reusing Cassandra SSL connections
Timo Sirainen [Mon, 13 Apr 2026 06:51:29 +0000 (08:51 +0200)] 
lib-sql: cassandra - Fix reusing Cassandra SSL connections

Cassandra SSL settings were compared wrong. This could have caused it to keep
creating new Cassandra connections instead of reusing existing ones.

2 weeks agofts: tika - Fix use-after-free crash during DNS lookup
Timo Sirainen [Thu, 9 Apr 2026 11:16:46 +0000 (14:16 +0300)] 
fts: tika - Fix use-after-free crash during DNS lookup

This is a similar fix as 3d0aea564e7f3d0763c290f0bc86c9483cb6dab7 for
fts-solr.

2 weeks agolib-ldap: Don't use OpenLDAP default CA if either ssl_client_ca_dir/file is set
Timo Sirainen [Tue, 7 Apr 2026 20:29:22 +0000 (23:29 +0300)] 
lib-ldap: Don't use OpenLDAP default CA if either ssl_client_ca_dir/file is set

2 weeks agolib-ldap: Use default ldap settings if not overridden by Dovecot config
Timo Sirainen [Tue, 7 Apr 2026 20:10:31 +0000 (23:10 +0300)] 
lib-ldap: Use default ldap settings if not overridden by Dovecot config

This fixes e.g. using system default CAs.

2 weeks agolib-ldap: Add ldap_init_defaults()
Timo Sirainen [Tue, 7 Apr 2026 16:10:58 +0000 (19:10 +0300)] 
lib-ldap: Add ldap_init_defaults()

2 weeks agolib-ldap: Require LDAP_OPT_X_TLS_NEWCTX to exist
Timo Sirainen [Tue, 7 Apr 2026 19:59:37 +0000 (22:59 +0300)] 
lib-ldap: Require LDAP_OPT_X_TLS_NEWCTX to exist

It's unclear what the behavior will be if it's not supported.
Better to fail at compiling.

2 weeks agoimap: cmd-append - Fix assertion panic occurring upon invalid 'REPLACE 0' command
Stephan Bosch [Sun, 29 Mar 2026 18:03:40 +0000 (20:03 +0200)] 
imap: cmd-append - Fix assertion panic occurring upon invalid 'REPLACE 0' command

Panic was:
Panic: file mail-cache-lookup.c: line 354 (mail_cache_field_exists): assertion failed: (seq > 0)

2 weeks agoimap: cmd-append - Properly consume message literal for invalid REPLACE message sequence
Stephan Bosch [Thu, 2 Apr 2026 01:02:53 +0000 (03:02 +0200)] 
imap: cmd-append - Properly consume message literal for invalid REPLACE message sequence

2 weeks agofts-solr: Fix use-after-free crash during DNS lookup
Timo Sirainen [Wed, 1 Apr 2026 12:24:52 +0000 (15:24 +0300)] 
fts-solr: Fix use-after-free crash during DNS lookup

The solr_http_client singleton outlived the user session that created
it. Its event chain held a ref on the mail_storage_service_user event,
keeping it alive after the user was freed. The SETTINGS_EVENT_INSTANCE on
that event still pointed to the already-freed settings_instance. On the
next user session, dns_lookup() walked the stale event chain and
dereferenced the dangling pointer in settings_instance_get().

Fix this by using a shorter lived HTTP client.

2 weeks agolib-http: Calculate "other ioloop" statistics also when request wasn't sent
Timo Sirainen [Tue, 31 Mar 2026 17:54:19 +0000 (20:54 +0300)] 
lib-http: Calculate "other ioloop" statistics also when request wasn't sent

2 weeks agolib-http: Count lock and ioloop wait statistics beginning when request is queued
Timo Sirainen [Tue, 31 Mar 2026 17:49:42 +0000 (20:49 +0300)] 
lib-http: Count lock and ioloop wait statistics beginning when request is queued

Previously they were counted only after the request was sent. However,
it's important to also know where time is spent while the request is still
queued.

This also fixes wrong output for lock wait statistics when the request
was never sent (e.g. DNS lookup failure).

3 weeks agolib-master, master: Fix inet_listener_reuse_port=yes handling
Timo Sirainen [Wed, 18 Mar 2026 16:30:20 +0000 (18:30 +0200)] 
lib-master, master: Fix inet_listener_reuse_port=yes handling

This only works properly if the listener sockets don't change and
there is always a process listening on each of the sockets.

Now master process creates the reuse_port=yes listeners for all of the
processes at startup (up to process_limit). Each child process inherits
exactly one unique listener socket based on its assigned process index.

Since with reuse_port=yes connections are assigned to a specific socket,
processes can no longer rely on other processes picking up connections when
they are full. Instead, each process is now responsible for rejecting
connections when they reach client_limit.

3 weeks agomaster: Add checks to services with inet_listener_reuse_port=yes
Timo Sirainen [Wed, 18 Mar 2026 15:47:46 +0000 (17:47 +0200)] 
master: Add checks to services with inet_listener_reuse_port=yes

 * They must have process_min_avail = process_limit
 * All or none of the inet_listeners must have reuse_port=yes

Otherwise reuse_port=yes doesn't work very well.

3 weeks agolib-master, master: Replace inet_listener_reuse_port with service_reuse_port
Timo Sirainen [Thu, 26 Mar 2026 14:57:54 +0000 (16:57 +0200)] 
lib-master, master: Replace inet_listener_reuse_port with service_reuse_port

All inet_listeners require the same value for reuse_port, so it's better to
be a service setting.

3 weeks agopop3: Fix memory leak when using DELE+RSET+DELE
Fred Morcos [Tue, 17 Mar 2026 10:55:19 +0000 (11:55 +0100)] 
pop3: Fix memory leak when using DELE+RSET+DELE

This fixes a leak where calls to delete -> reset -> delete would leak memory because the
client->deleted flag is checked but the state of the client->deleted_bitmask isn't.

This removes client->deleted and uses the bitmask as a marker instead.

3 weeks agolmtp: Add back service_extra_groups=$SET:default_internal_group
Timo Sirainen [Thu, 2 Apr 2026 06:16:46 +0000 (09:16 +0300)] 
lmtp: Add back service_extra_groups=$SET:default_internal_group

Reverts 8ec25c24db9f1ad9be437ef266688272686daf42 for lmtp.

3 weeks agoplugins/push-notification: push-notification-driver-ox - Remove trailing whitespace
Karl Fleischmann [Tue, 31 Mar 2026 09:42:36 +0000 (11:42 +0200)] 
plugins/push-notification: push-notification-driver-ox - Remove trailing whitespace

3 weeks agoplugins/push-notification: push-notification-driver-ox - Restore default http-client...
Karl Fleischmann [Tue, 31 Mar 2026 10:46:58 +0000 (12:46 +0200)] 
plugins/push-notification: push-notification-driver-ox - Restore default http-client settings

This was dropped with the config-rewrite conversion.

3 weeks agoplugins/push-notification: push-notification-driver-ox - Use settings_event_add_filte...
Karl Fleischmann [Tue, 31 Mar 2026 09:50:12 +0000 (11:50 +0200)] 
plugins/push-notification: push-notification-driver-ox - Use settings_event_add_filter_name()

3 weeks agoplugins/push-notification: push-notification-driver-lua - Use settings_event_add_filt...
Karl Fleischmann [Tue, 31 Mar 2026 09:47:30 +0000 (11:47 +0200)] 
plugins/push-notification: push-notification-driver-lua - Use settings_event_add_filter_name()

3 weeks agoplugins/push-notification: push-notification-driver-dlog - Add filter name for dlog...
Karl Fleischmann [Tue, 31 Mar 2026 10:42:08 +0000 (12:42 +0200)] 
plugins/push-notification: push-notification-driver-dlog - Add filter name for dlog driver

This makes this push notification driver work the same as the ox and lua ones.

3 weeks agoplugins/quota: Use settings_event_add_filter_name()
Karl Fleischmann [Tue, 31 Mar 2026 09:49:26 +0000 (11:49 +0200)] 
plugins/quota: Use settings_event_add_filter_name()

3 weeks agoauth: Use timing safe comparison for certificate and public key fingerprint
Aki Tuomi [Mon, 6 Apr 2026 17:21:53 +0000 (20:21 +0300)] 
auth: Use timing safe comparison for certificate and public key fingerprint

3 weeks agolmtp: lmtp-proxy - Make passdb lookup for recipient redirect asynchronous
Stephan Bosch [Tue, 24 Mar 2026 14:09:19 +0000 (15:09 +0100)] 
lmtp: lmtp-proxy - Make passdb lookup for recipient redirect asynchronous

3 weeks agolmtp: lmtp-proxy - Split off lmtp_proxy_rcpt_redirect_relookup_cb() from lmtp_proxy_r...
Stephan Bosch [Tue, 24 Mar 2026 22:00:12 +0000 (23:00 +0100)] 
lmtp: lmtp-proxy - Split off lmtp_proxy_rcpt_redirect_relookup_cb() from lmtp_proxy_rcpt_redirect_relookup()

This is not an actual callback yet.

3 weeks agolmtp: lmtp-proxy - Rename variable "ret" to "result" in lmtp_proxy_rcpt_redirect_relo...
Stephan Bosch [Tue, 24 Mar 2026 21:47:13 +0000 (22:47 +0100)] 
lmtp: lmtp-proxy - Rename variable "ret" to "result" in lmtp_proxy_rcpt_redirect_relookup()

3 weeks agolmtp: lmtp-proxy - Make normal passdb lookup for recipient asynchronous
Stephan Bosch [Sat, 29 Dec 2018 00:07:38 +0000 (01:07 +0100)] 
lmtp: lmtp-proxy - Make normal passdb lookup for recipient asynchronous

3 weeks agolmtp: lmtp-proxy - Split off lmtp_proxy_rcpt_user_lookup_cb() from lmtp_proxy_rcpt()
Stephan Bosch [Mon, 18 May 2020 20:39:37 +0000 (22:39 +0200)] 
lmtp: lmtp-proxy - Split off lmtp_proxy_rcpt_user_lookup_cb() from lmtp_proxy_rcpt()

This is not an actual callback yet.

3 weeks agolmtp: lmtp-proxy - Drop orig_username variable in lmtp_proxy_rcpt()
Stephan Bosch [Mon, 18 May 2020 20:49:34 +0000 (22:49 +0200)] 
lmtp: lmtp-proxy - Drop orig_username variable in lmtp_proxy_rcpt()

3 weeks agolmtp: lmtp-proxy - Rename variable "ret" to "result" in lmtp_proxy_rcpt()
Stephan Bosch [Mon, 18 May 2020 20:21:23 +0000 (22:21 +0200)] 
lmtp: lmtp-proxy - Rename variable "ret" to "result" in lmtp_proxy_rcpt()

3 weeks agolmtp: Make RCPT command implementation suitable for asynchronous lookups
Stephan Bosch [Fri, 28 Dec 2018 23:03:48 +0000 (00:03 +0100)] 
lmtp: Make RCPT command implementation suitable for asynchronous lookups

3 weeks agolib-smtp: smtp-server - Make smtp_server_command_ref/unref() public
Stephan Bosch [Tue, 2 Jun 2020 23:06:31 +0000 (01:06 +0200)] 
lib-smtp: smtp-server - Make smtp_server_command_ref/unref() public

3 weeks agolib-smtp: smtp-client-connection - Make sure all ioloop objects are created on the...
Stephan Bosch [Mon, 28 Jul 2025 23:33:26 +0000 (01:33 +0200)] 
lib-smtp: smtp-client-connection - Make sure all ioloop objects are created on the connection's ioloop

3 weeks agolib-dns-client: dns-lookup - Allow performing lookups on a specific ioloop
Stephan Bosch [Mon, 28 Jul 2025 23:32:21 +0000 (01:32 +0200)] 
lib-dns-client: dns-lookup - Allow performing lookups on a specific ioloop

3 weeks agolib: connection - Retain pre-initialized ioloop
Stephan Bosch [Mon, 28 Jul 2025 23:31:29 +0000 (01:31 +0200)] 
lib: connection - Retain pre-initialized ioloop

3 weeks agolib-auth-client: auth-master - Prevent hangs and crashes when lookups are nested
Stephan Bosch [Thu, 28 Aug 2025 02:36:12 +0000 (04:36 +0200)] 
lib-auth-client: auth-master - Prevent hangs and crashes when lookups are nested

3 weeks agolmtp: Add debug log message indicating which backend will serve the recipient
Stephan Bosch [Tue, 24 Mar 2026 04:02:23 +0000 (05:02 +0100)] 
lmtp: Add debug log message indicating which backend will serve the recipient

3 weeks agolib-smtp: smtp-server-recipient - Add debug logging for submitted RCPT reply
Stephan Bosch [Mon, 23 Mar 2026 22:28:34 +0000 (23:28 +0100)] 
lib-smtp: smtp-server-recipient - Add debug logging for submitted RCPT reply

3 weeks agolib-smtp: smtp-server-recipient - Add recipient index to event log once recipient...
Stephan Bosch [Mon, 23 Mar 2026 21:28:17 +0000 (22:28 +0100)] 
lib-smtp: smtp-server-recipient - Add recipient index to event log once recipient is accepted

3 weeks agolib-smtp: smtp-server-recipient - Use public recipient struct as smtp_server_recipien...
Stephan Bosch [Mon, 23 Mar 2026 21:30:48 +0000 (22:30 +0100)] 
lib-smtp: smtp-server-recipient - Use public recipient struct as smtp_server_recipient_update_event() parameter

3 weeks agolib-smtp: smtp-server-reply - Fix presence of dash in smtp_server_reply_write_one_lin...
Stephan Bosch [Tue, 24 Mar 2026 02:11:25 +0000 (03:11 +0100)] 
lib-smtp: smtp-server-reply - Fix presence of dash in smtp_server_reply_write_one_line() output

3 weeks agolib-smtp: Reformat smtp-server-reply.c
Stephan Bosch [Tue, 24 Mar 2026 02:32:02 +0000 (03:32 +0100)] 
lib-smtp: Reformat smtp-server-reply.c

3 weeks agoindexer-worker: Drop root privileges permanently
Timo Sirainen [Wed, 1 Apr 2026 16:00:46 +0000 (19:00 +0300)] 
indexer-worker: Drop root privileges permanently

3 weeks agoindexer-worker: Change default restart_request_count
Timo Sirainen [Wed, 1 Apr 2026 15:59:52 +0000 (18:59 +0300)] 
indexer-worker: Change default restart_request_count

For Pro, use default 1000 like with imap/pop3/etc processes.

For CE, use default 1 so that it works with multiple UIDs after the
following change.

Add settings history only for Pro, because with CE the old default
value might not work anymore now that root privileges are permanetly
dropped.

3 weeks agoutil: script-login - Don't allow running as root
Timo Sirainen [Wed, 1 Apr 2026 15:11:57 +0000 (18:11 +0300)] 
util: script-login - Don't allow running as root

Originally it it was forgotten to be prevented, and it was changed to be
explicitly allowed by e0dae5d76ea0a4aef849602750ce73dfae995bc8.

3 weeks agoquota: quota-status - Don't allow running as root
Timo Sirainen [Wed, 1 Apr 2026 15:09:42 +0000 (18:09 +0300)] 
quota: quota-status - Don't allow running as root

Originally it it was forgotten to be prevented, and it was changed to be
explicitly allowed by e0dae5d76ea0a4aef849602750ce73dfae995bc8.

3 weeks agolib-auth-client: Avoid "unknown id" errors for aborted auth requests
Timo Sirainen [Thu, 26 Mar 2026 11:31:53 +0000 (13:31 +0200)] 
lib-auth-client: Avoid "unknown id" errors for aborted auth requests

Delay freeing aborted request until its response is received or auth server
is disconnected.

Fixes:
Error: auth-client: conn ...: Auth entication server sent unknown id ...

3 weeks agolib-auth-client, auth: CANCEL command now replies with CANCELLED reply
Timo Sirainen [Thu, 26 Mar 2026 12:27:27 +0000 (14:27 +0200)] 
lib-auth-client, auth: CANCEL command now replies with CANCELLED reply

This is done when auth client protocol is >=v1.4. The CANCELLED reply is
used to free the auth request, if it still exists.

3 weeks agologin-common: When process is full, don't destroy clients waiting on master auth
Timo Sirainen [Thu, 26 Mar 2026 10:19:36 +0000 (12:19 +0200)] 
login-common: When process is full, don't destroy clients waiting on master auth

These clients have already successfully authenticated. Killing their client
is only going to cause errors.

3 weeks agologin-common: Give better reason for auth_client_request_abort()
Timo Sirainen [Thu, 26 Mar 2026 10:01:55 +0000 (12:01 +0200)] 
login-common: Give better reason for auth_client_request_abort()

3 weeks agologin-common: Remove unused client_auth_abort()
Timo Sirainen [Thu, 26 Mar 2026 10:00:16 +0000 (12:00 +0200)] 
login-common: Remove unused client_auth_abort()

3 weeks agolib-master: Fix crash when reaching client_limit with restart_request_count>1 and...
Timo Sirainen [Thu, 26 Mar 2026 09:45:24 +0000 (11:45 +0200)] 
lib-master: Fix crash when reaching client_limit with restart_request_count>1 and client_limit>1

Fixes:
Panic: file master-service.c: line 1909 (master_service_listen): assertion failed: (service->master_status.available_count > 0)

3 weeks agolib-master, master: Fix behavior for services with client_limit>1 and restart_request...
Timo Sirainen [Wed, 25 Mar 2026 09:30:20 +0000 (11:30 +0200)] 
lib-master, master: Fix behavior for services with client_limit>1 and restart_request_count

Especially login processes are commonly configured to use client_limit > 1
and process_limit = process_min_avail = number of CPUs. However, this
prevents using restart_request_count, because long lived connections
can reserve the process and prevent a new one from being launched.

Change the behavior so that when restart_request_count is reached for a
process whose service has client_limit > 1, the process is no longer
counted towards process_limit.

3 weeks agomaster: service_status_more() - Change status parameter to status_available_count
Timo Sirainen [Wed, 25 Mar 2026 09:45:56 +0000 (11:45 +0200)] 
master: service_status_more() - Change status parameter to status_available_count

Simplifies the next commit.

3 weeks agolib-http: Count time spent in any ioloop waiting on HTTP request as "http ioloop"
Timo Sirainen [Tue, 31 Mar 2026 15:35:07 +0000 (18:35 +0300)] 
lib-http: Count time spent in any ioloop waiting on HTTP request as "http ioloop"

Previously only http_client_wait() caused times to be counted in "http
ioloop". This isn't relevant though. The important difference is that
time spent on "http ioloop" is actually time spent on waiting for the
HTTP request, while "other ioloop" is time spent on waiting for an ioloop
without the HTTP request.

3 weeks agovirtual: virtual_storage_create() - Deny index rather than allowing just fs
Marco Bettini [Mon, 30 Mar 2026 12:34:54 +0000 (12:34 +0000)] 
virtual: virtual_storage_create() - Deny index rather than allowing just fs

3 weeks agom4: want_mysql.m4 - Fix detecting SSL support with libmariadb
Timo Sirainen [Wed, 1 Apr 2026 12:22:16 +0000 (15:22 +0300)] 
m4: want_mysql.m4 - Fix detecting SSL support with libmariadb

3 weeks agolib-regex: Fix memory leak when replace pattern doesn't match
Timo Sirainen [Wed, 1 Apr 2026 13:06:05 +0000 (16:06 +0300)] 
lib-regex: Fix memory leak when replace pattern doesn't match

4 weeks agolib-program-client: program-client - Assert that program_input is set in program_clie...
Stephan Bosch [Sat, 28 Mar 2026 19:50:55 +0000 (20:50 +0100)] 
lib-program-client: program-client - Assert that program_input is set in program_client_input_finish()

Even though all paths leading to this function make sure it is assigned,
Coverity is worried about it being NULL at some point (CID: 42244).

4 weeks agolib-json: json-istream - Assert that value_stream either both set or unset in json_is...
Stephan Bosch [Sat, 28 Mar 2026 19:46:40 +0000 (20:46 +0100)] 
lib-json: json-istream - Assert that value_stream either both set or unset in json_istream_consume_value_stream()

This confuses Coverity otherwise (CID: 42255).

4 weeks agolib-http: http-server-request - Assert that response is set in http_server_request_fi...
Stephan Bosch [Sat, 28 Mar 2026 19:32:57 +0000 (20:32 +0100)] 
lib-http: http-server-request - Assert that response is set in http_server_request_finished()

Previous code suggested it may be NULL, which is not true.

Found by Coverity (CID: 42271)

4 weeks agolib-auth: auth-scram-server - Assert that hash method never gets to be NULL somehow
Stephan Bosch [Sat, 28 Mar 2026 19:18:15 +0000 (20:18 +0100)] 
lib-auth: auth-scram-server - Assert that hash method never gets to be NULL somehow

Stack-based buffer sizes are based on it a field in the hash method struct. An
assert is easier to debug than a segfault. Also, this makes code consistent with
auth-scram-client.

4 weeks agolib-auth: auth-scram-client - Check assertions earlier so that no segfault is trigger...
Stephan Bosch [Sat, 28 Mar 2026 19:14:03 +0000 (20:14 +0100)] 
lib-auth: auth-scram-client - Check assertions earlier so that no segfault is triggered instead

Issue found by Coverity (CID: 42292)

4 weeks agolib-var-expand: Remove pointless assigment in var_expand_program_execute_one_real()
Aki Tuomi [Tue, 31 Mar 2026 10:24:37 +0000 (13:24 +0300)] 
lib-var-expand: Remove pointless assigment in var_expand_program_execute_one_real()

Forgotten from 2b8036fbb90c0c0d716ee419a5595a4328c118be

4 weeks agodoveadm: Remove CORS headers from OPTIONS reply
Aki Tuomi [Mon, 30 Mar 2026 18:30:45 +0000 (21:30 +0300)] 
doveadm: Remove CORS headers from OPTIONS reply

4 weeks agolib-program-client: program-client-local - Drop any real root privileges before progr...
Stephan Bosch [Tue, 10 Mar 2026 04:16:52 +0000 (05:16 +0100)] 
lib-program-client: program-client-local - Drop any real root privileges before program execvp()

Running programs with real root privileges while the effective privileges are
user-level is risky and often unexpected.

4 weeks agoauth: auth_request_validate_client_fp() - Ensure client certificate can be checked
Karl Fleischmann [Fri, 20 Mar 2026 08:48:52 +0000 (09:48 +0100)] 
auth: auth_request_validate_client_fp() - Ensure client certificate can be checked

4 weeks agolib-sasl: oauth2 - Send configured scope for failure responses
Aki Tuomi [Mon, 16 Mar 2026 11:44:33 +0000 (13:44 +0200)] 
lib-sasl: oauth2 - Send configured scope for failure responses