diff -Nru dovecot-2.2.22/ChangeLog dovecot-2.2.24/ChangeLog --- dovecot-2.2.22/ChangeLog 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/ChangeLog 2016-04-26 15:10:57.000000000 +0000 @@ -1,19 +1,1438 @@ -2016-03-16 09:48:21 +0200 Timo Sirainen (0968566) +2016-04-26 17:30:35 +0300 Timo Sirainen (a94e44e) - Released v2.2.22. + Released v2.2.24. M NEWS M configure.ac -2016-03-16 09:27:04 +0200 Teemu Huovila (ab36e80) +2016-04-26 17:12:25 +0300 Timo Sirainen (a82c823) + + stats: Support multiple FIFO listeners. + + +M src/stats/fifo-input-connection.c +M src/stats/fifo-input-connection.h +M src/stats/main.c + +2016-04-26 11:12:45 +0300 Timo Sirainen (9de3ff6) + + doveadm -u: Use mail_storage_service_all_init_mask() + + +M src/doveadm/doveadm-mail.c + +2016-04-26 11:11:57 +0300 Timo Sirainen (d5804a0) + + lib-storage: Added mail_storage_service_all_init_mask() + + This allows providing a usermask hint to the userdb iteration lookup. For + example with LDAP this allows setting the base based on the @domain. + +M src/lib-storage/mail-storage-service.c +M src/lib-storage/mail-storage-service.h + +2016-04-26 11:10:35 +0300 Baofeng Wang (c87684e) + + lib-storage: fixup the broken search result with \seen or \delete + + remove side effects of match_always flag during search. + +M src/lib-storage/index/index-search.c + +2016-04-26 10:31:49 +0300 Timo Sirainen (6956285) + + lib-sql: Fixed building Cassandra as plugin + + +M src/lib-sql/Makefile.am + +2016-04-25 20:14:19 +0300 Timo Sirainen (53d07fb) + + fts-lucene: Rescan skipped namespace roots. + + +M src/plugins/fts-lucene/lucene-wrapper.cc + +2016-04-25 20:13:54 +0300 Timo Sirainen (70d2103) + + fts-lucene: Cleanup - move code to a separate function + + +M src/plugins/fts-lucene/lucene-wrapper.cc + +2016-04-25 16:58:30 +0300 Timo Sirainen (ad09af2) + + lib-mail: More fixes to istream-header-filter with large input. + + Don't assume that when reading the header the second time we'll get exactly + the same header blocks as the first time. + + This commit also prevents the filter callback from switching the + matching-decision on non-first header line. This shouldn't be needed and it + could just cause confusion. (It also made it a bit easier to implement this + fix.) + +M src/lib-mail/istream-header-filter.c +M src/lib-mail/test-istream-header-filter.c + +2016-04-25 16:34:59 +0300 Timo Sirainen (5fdca8e) + + lib-mail: Improved istream-header-filter unit test. + + Existing code already assumes that the callback is called for all the header + data. So it's not used just for filtering headers but also parsing the + header contents. Make this assumption now explicit as a unit test. + +M src/lib-mail/test-istream-header-filter.c + +2016-04-25 16:25:46 +0300 Timo Sirainen (d7524cf) + + lib-mail: istream-header-filter didn't limit memory usage. + + A large header was always added to hdr_buf, ignoring any max_buffer_size + limits. + +M src/lib-mail/istream-header-filter.c +M src/lib-mail/test-istream-header-filter.c + +2016-04-25 16:22:12 +0300 Timo Sirainen (30ad986) + + lib-mail: Code cleanup to istream-header-filter unit test + + The exclude_headers arrays were used in a confusing way. The X-Drop header + wasn't actually even used in the exclude_headers. + +M src/lib-mail/test-istream-header-filter.c + +2016-04-25 14:38:35 +0300 Timo Sirainen (7919e95) + + dsync: If state is invalid, exit with code 2 instead of tempfail. + + We'll have dsync_mailbox_import_*() just return success to everything until + _deinit() is called. The _deinit() will return a failure and set "resync + needed"-flag, which caller will know how to handle. + +M src/doveadm/dsync/dsync-brain-mailbox.c +M src/doveadm/dsync/dsync-brain-mails.c +M src/doveadm/dsync/dsync-mailbox-import.c +M src/doveadm/dsync/dsync-mailbox-import.h + +2016-04-25 14:35:21 +0300 Timo Sirainen (da0b62e) + + dsync: If full resync is requested, return empty state string. + + If the state is wrong, it's better to fully resync all the mailboxes rather + than just the one where a problem was noticed. + +M src/doveadm/dsync/dsync-brain.c + +2016-04-25 14:08:37 +0300 Timo Sirainen (69811d9) + + dsync: Improved detecting state state string. + + +M src/doveadm/dsync/dsync-mailbox-import.c + +2016-04-15 16:12:44 +0300 Timo Sirainen (c7ea86d) + + lib-storage: Don't use same session ID for multiple + mail_storage_service_next() calls. + + dsync does multiple mail_storage_service_next() calls for the same + mail_storage_service_user. This causes stats plugin to send the same session + ID to stats process, which complains about duplicates. Solved this in a + generic way by having the following mail_storage_service_next() calls append + :counter to session ID. + +M src/lib-storage/mail-storage-service.c + +2016-04-11 17:25:51 +0300 Timo Sirainen (e534a82) + + fs-posix: If link() fails, preserve its errno through the following unlink() + + +M src/lib-fs/fs-posix.c + +2016-04-11 17:20:52 +0300 Timo Sirainen (b7d31e7) + + fs-posix: Minor code cleanup - removed unnecessary code. + + If success==TRUE, temp_path==NULL always also. + +M src/lib-fs/fs-posix.c + +2016-04-22 19:37:57 +0300 Timo Sirainen (0bbaf39) + + cassandra: Added num_threads, connect_timeout and request_timeout settings. + + +M src/lib-sql/Makefile.am +M src/lib-sql/driver-cassandra.c + +2016-04-21 19:18:55 +0300 Timo Sirainen (4968bfa) + + lib-dovecot: Avoid duplication of listing *.la in both Makefile.am and + configure + + +M configure.ac +M src/lib-dovecot/Makefile.am + +2016-04-21 18:58:10 +0300 Timo Sirainen (2a81294) + + lib-dict: Moved dict-ldap to lib-dict-extra + + This also allows moving lib-ldap away from LIBDOVECOT_SUBDIRS in + src/Makefile.am, which was wrong because it's not really part of + libdovecot.la. + +M src/Makefile.am +M src/lib-dict-extra/Makefile.am +A src/lib-dict-extra/dict-ldap-settings.c +A src/lib-dict-extra/dict-ldap-settings.h +A src/lib-dict-extra/dict-ldap.c +M src/lib-dict/Makefile.am +D src/lib-dict/dict-ldap-settings.c +D src/lib-dict/dict-ldap-settings.h +D src/lib-dict/dict-ldap.c + +2016-04-21 18:51:57 +0300 Timo Sirainen (bfbb24b) + + Split parts of lib-dict into lib-dict-extra. + + Otherwise there's a circular dependency because lib-dict/dict-fs.c depends + on lib-fs, while lib-fs/fs-dict.c depends on lib-dict. This becomes a + problem when compiling --without-shared-libs, although for some reason it + works for me while linking the Dovecot core, but not when linking external + plugins. + +M configure.ac +M src/Makefile.am +A src/lib-dict-extra/Makefile.am +A src/lib-dict-extra/dict-fs.c +A src/lib-dict-extra/dict-register.c +M src/lib-dict/Makefile.am +D src/lib-dict/dict-fs.c +D src/lib-dict/dict-register.c +M src/lib-dovecot/Makefile.am + +2016-04-19 19:08:52 +0300 Timo Sirainen (cfb90f1) + + doveadm user: Added -e parameter to expand %variables in + + This allows expanding any %variable that the mail processes normally expand. + For example: + + % doveadm user -e "%u's home is %h" testuser@example.com + testuser@example.com's home is /var/mail/testuser@example.com + +M src/doveadm/doveadm-auth.c + +2016-04-19 19:07:51 +0300 Timo Sirainen (ed2e2ac) + + doveadm user: Code cleanup - move field printing to its own function. + + No functional changes. + +M src/doveadm/doveadm-auth.c + +2016-04-22 18:35:04 +0300 Timo Sirainen (c6f4412) + + lib-mail: Improved test-message-parser further + + +M src/lib-mail/test-message-parser.c + +2016-04-22 18:28:20 +0300 Timo Sirainen (8062281) + + lib-mail: Fixed inner MIME part boundary being a prefix of outer boundary. + + +M src/lib-mail/message-parser.c +M src/lib-mail/test-message-parser.c + +2016-04-22 18:15:44 +0300 Timo Sirainen (55a79cf) + + lib-mail: Fixed handling duplicate boundary prefixes. + + If inner MIME part had the same --boundary prefix as its parent(s) and the + MIME part body started with the inner --boundary prefix, we didn't yet have + it in the list of valid boundaries, so we thought that the outer boundary + was found and the MIME headers were truncated. But due to an extra bug we + still treated it as if it were the inner boundary, except the MIME part + sizes/offsets were set wrong. + + This for example fixes a situation where FETCH [1.2.MIME] returns an extra + newline before the actual headers. + +M src/lib-mail/message-parser.c +M src/lib-mail/test-message-parser.c + +2016-04-22 16:39:49 +0300 Timo Sirainen (ff1f515) + + dsync: Fixed assert-crash in rename algorithm + + Fixes a crash: Panic: file dsync-mailbox-tree-sync.c: line 1308 + (sync_mailbox_child_dirs): assertion failed: (!node_is_existent(local_node)) + +M src/doveadm/dsync/dsync-mailbox-tree-sync.c +M src/doveadm/dsync/test-dsync-mailbox-tree-sync.c + +2016-04-22 16:28:56 +0300 Timo Sirainen (66da586) + + dsync: Determine better when rename-algorithm might have gotten stuck. + + A hardcoded value of 100 isn't necessarily enough if there are a lot of + mailboxes with a lot of renames. Base the max count on the total number of + mailboxes on both local and remote. And just in case multiple it by 3. + Probably smaller number would be fine too. + +M src/doveadm/dsync/dsync-mailbox-tree-sync.c + +2016-04-22 16:25:00 +0300 Timo Sirainen (412fb67) + + dsync: Fixed crash when rename algorithm thinks it has gone to infinite + loop. + + ctx->brain was NULL, so trying to access it crashed. + +M src/doveadm/dsync/dsync-brain-mailbox-tree.c +M src/doveadm/dsync/dsync-mailbox-tree-sync.c +M src/doveadm/dsync/dsync-mailbox-tree.h + +2016-04-21 17:55:51 +0300 Timo Sirainen (973c6d6) + + lib-fs: fs-metawrap stat() and get_metadata(): use existing istream if + possible + + This may reduce reads from parent fs, but it's at least required for the + following commit. + +M src/lib-fs/fs-metawrap.c + +2016-04-21 17:54:54 +0300 Timo Sirainen (5c20139) + + lib-fs: Added initial fs-metawrap unit test. + + +M src/lib-fs/Makefile.am +A src/lib-fs/test-fs-metawrap.c + +2016-04-21 17:52:44 +0300 Timo Sirainen (bdff783) + + lib-fs: Added fs-test backend for helping with creation of fs-wrapper unit + tests. + + +M src/lib-fs/Makefile.am +M src/lib-fs/fs-api-private.h +M src/lib-fs/fs-api.c +A src/lib-fs/fs-test.c +A src/lib-fs/fs-test.h + +2016-04-20 23:01:45 +0300 Timo Sirainen (06c3262) + + lib: var_expand() now expands %{nonexistent} to + UNSUPPORTED_VARIABLE_nonexistent + + Earlier it was expanded to "nonexistent}", which looked more like a bug. + This change hopefully makes it clear enough to understand when a variable + isn't supported. + +M src/lib/test-var-expand.c +M src/lib/var-expand.c + +2016-04-21 21:45:02 +0300 Timo Sirainen (de73aa2) + + lib-ssl-iostream: Return stacked errors as single combined string. + + Instead of logging stacked errors as separate log lines, which don't provide + any context of what created them. + +M src/lib-ssl-iostream/iostream-openssl-common.c + +2016-04-19 16:55:02 +0300 Timo Sirainen (2f1be1f) + + lib-http: Include information about number of request attempts and its + timing in response reason. + + Because the reason is usually logged as part of the error string, this + causes all of the error messages to include the attempts count and how long + the requests took in total. This should make it easier to understand + problems in error logs. + + http_client_request_set_preserve_exact_reason() can be used to disable + modifying the reason string. This may also apply to other reason + modifications that may be done in the future. + +M src/lib-http/http-client-private.h +M src/lib-http/http-client-request.c +M src/lib-http/http-client.h + +2016-04-22 16:00:36 +0300 Timo Sirainen (2335ab1) + + push-notification: Small optimization - don't lookup uidvalidity for each + message. + + +M src/plugins/push-notification/push-notification-txn-msg.c + +2016-04-22 00:21:12 +0300 Timo Sirainen (11c704a) + + imapc: Added support for imapc_features=modseq + + If the remote server supports CONDSTORE or QRESYNC extensions we'll use the + remote's MODSEQ and HIGHESTMODSEQ counts. + + There are some situations where the HIGHESTMODSEQ isn't updated exactly + correctly on an open mailbox, so this feature shouldn't be fully relied on. + It was primarily implemented for dsync+imapc support - both for preserving + modseqs and also for HIGHESTMODSEQ lookups. + +M src/lib-storage/index/imapc/imapc-mail.c +M src/lib-storage/index/imapc/imapc-mailbox.c +M src/lib-storage/index/imapc/imapc-settings.c +M src/lib-storage/index/imapc/imapc-settings.h +M src/lib-storage/index/imapc/imapc-storage.c +M src/lib-storage/index/imapc/imapc-storage.h +M src/lib-storage/index/imapc/imapc-sync.c + +2016-04-22 20:31:02 +0300 Timo Sirainen (58e4e5b) + + lib: Fix to previous istream-timeout commit + + The one commit I didn't bother putting through all the automated testing + stages and I of course forgot to even compile after the last change :( + +M src/lib/istream-timeout.c + +2016-04-22 20:10:34 +0300 Timo Sirainen (81672c7) + + lib: Improved istream-timeout error message. + + We're supposed to check that timeout isn't triggered after a long-running + code, but it's not perfect. So provide the actual timing information we saw + instead of the expected timeout. + +M src/lib/istream-timeout.c + +2016-04-17 21:15:30 +0300 Timo Sirainen (ceefe5b) + + cassandra: Added support for user and password settings. + + +M src/lib-sql/driver-cassandra.c + +2016-04-21 21:41:23 +0300 Timo Sirainen (b9e1531) + + lib-ssl-iostream: Fixed reporting errors returned by OpenSSL. + + We were always logging all errors as "Stacked error" and then returning + "Unknown error". + +M src/lib-ssl-iostream/iostream-openssl-common.c + +2016-04-15 23:59:24 +0200 Stephan Bosch (2a99688) + + lib-http: client: Implemented means to set request payload buffer rather + than an input stream. + + This is not purely a convenience function: there have been bugs caused by + allocating a data input stream from a datastack buffer. With this function, + the buffer is copied to the request pool, so that it is durably allocated + while the request exists. This prevents futher mishaps. The server already + has an equivalent function for its response object. + +M src/lib-http/http-client-request.c +M src/lib-http/http-client.h + +2016-04-20 19:34:05 +0300 Timo Sirainen (7ce6777) + + zlib: Compiling fix to a1630a3b3 - don't return a void function + + +M src/plugins/zlib/zlib-plugin.c + +2016-04-20 17:10:17 +0300 Timo Sirainen (a6a14c7) + + lazy-expunge: Fixed using a mailbox (instead of namespace) as lazy_expunge + destination. + + The initial implementation in f2d7ae020bda762f78e8e639a69fb129230cbb7d was + completely broken. + +M src/plugins/lazy-expunge/lazy-expunge-plugin.c + +2016-04-20 02:23:31 +0300 Timo Sirainen (61c30c7) + + lib-index: If opening a cache file fails, try again later. + + The previous code would never retry opening the cache file within the same + session. + +M src/lib-index/mail-cache-compress.c +M src/lib-index/mail-cache.c + +2016-04-20 00:29:49 +0300 Timo Sirainen (06bed4f) + + lib-index: Fixed calling mail_cache_open_and_verify() on an already open + cache. + + This was done at least by index_index_rebuild_init(). + + Either the currently open cache->fd was leaked, or if the cache file open() + failed we left the cache in an inconsistent state where cache->fd == -1, but + cache->hdr != NULL, so it caused MAIL_CACHE_IS_UNUSABLE() to also be TRUE. + This could have ended up in an assert: + + Panic: file mail-index-lock.c: line 31 (mail_index_lock_fd): assertion + failed: (MAIL_INDEX_IS_IN_MEMORY(index)) + +M src/lib-index/mail-cache.c + +2016-04-20 02:47:13 +0300 Timo Sirainen (31349fd) + + zlib plugin: Make sure we don't keep mail istream referenced after mail is + closed. + + +M src/plugins/zlib/zlib-plugin.c + +2016-04-14 19:04:28 +0300 Timo Sirainen (b1c7419) + + lazy-expunge: Allow lazy_expunge setting to point to a mailbox in any + namespace. + + This way we can use an existing namespace without having to create a new one + just for a single lazy_expunge mailbox. + +M src/plugins/lazy-expunge/lazy-expunge-plugin.c + +2016-04-18 16:40:49 +0300 Timo Sirainen (8828071) + + lib: Implement utc_mktime() with timegm() if it exists. + + It should be more efficient than repeatedly calling gmtime() many times. + +M configure.ac +M src/lib/utc-mktime.c + +2016-04-19 11:55:00 +0300 Timo Sirainen (d1e4867) + + auth: Added passdb/userdb { auth_verbose } setting. + + If this is explicitly set to yes or no, it overrides the global auth_verbose + setting. However, auth_debug=yes overrides all of the auth_verbose settings. + +M src/auth/auth-request.c +M src/auth/auth-settings.c +M src/auth/auth-settings.h + +2016-04-19 16:59:48 +0300 Timo Sirainen (6d85cb1) + + lib-storage: Added MAIL_STORAGE_CLASS_FLAG_NO_LIST_DELETES and + MAILBOX_LIST_FLAG_NO_DELETES + + +M src/lib-storage/list/mailbox-list-index-backend.c +M src/lib-storage/mail-storage-private.h +M src/lib-storage/mail-storage.c +M src/lib-storage/mailbox-list.h + +2016-04-15 14:51:42 +0300 Timo Sirainen (40e5747) + + stats plugin: stats_notify_path can now specify path to the stats-mail FIFO + + +M src/plugins/stats/stats-plugin.c + +2016-04-15 15:01:20 +0300 Timo Sirainen (14e2d75) + + lib-stats: Handle better write() to stats process failing with EAGAIN + + It only means that the stats process is too busy and the FIFO is filled up. + Retrying the write later should work. We also don't want to log too much + about the same warning, so do it only once per 30 seconds. + +M src/lib-stats/stats-connection.c + +2016-04-13 23:12:00 +0200 Stephan Bosch (6da64a8) + + lib-http: server: Prevent aborting finished or already aborted requests + again. + + +M src/lib-http/http-server-request.c + +2016-04-13 17:19:52 +0300 Timo Sirainen (b025075) + + configure: Fixed building lib-ldap / dict-ldap --with-ldap=plugin + + +M configure.ac + +2016-04-13 17:17:53 +0300 Timo Sirainen (c6f4485) + + lib-dict: Don't build dict-ldap if --with-ldap=no + + +M src/lib-dict/Makefile.am + +2016-04-13 13:47:51 +0300 Timo Sirainen (ee73d96) + + doveconf: Improved the warning message about global setting not overriding a + filter + + +M src/config/config-parser.c + +2016-04-13 11:22:12 +0300 Aki Tuomi (45fee9d) + + lib-dict: Disable debug log unless debug enabled + + +M src/lib-dict/dict-ldap.c + +2016-04-13 11:01:29 +0300 Aki Tuomi (d3be014) + + lib-ldap: Allow disabling of TLS + + +M src/lib-dict/dict-ldap-settings.c +M src/lib-dict/dict-ldap-settings.h +M src/lib-dict/dict-ldap.c +M src/lib-ldap/ldap-client.h +M src/lib-ldap/ldap-connection.c + +2016-04-11 22:56:40 +0300 Aki Tuomi (ccaab3d) + + lib-dict: Add option to enforce SSL + + +M src/lib-dict/dict-ldap-settings.c +M src/lib-dict/dict-ldap-settings.h +M src/lib-dict/dict-ldap.c + +2016-04-11 22:56:37 +0300 Aki Tuomi (77475f6) + + lib-ldap: Hard fail when SSL is required + + +M src/lib-ldap/ldap-connection.c + +2016-04-11 20:44:41 +0300 Aki Tuomi (0f01489) + + lib-ldap: Allow and warn insecure LDAP connection + + +M src/lib-ldap/ldap-client.h +M src/lib-ldap/ldap-connection.c + +2016-04-11 20:32:55 +0300 Aki Tuomi (5a48906) + + lib-ldap: Remove callback from connection_connect + + +M src/lib-ldap/ldap-connection.c +M src/lib-ldap/ldap-private.h + +2016-04-11 17:29:35 +0300 Aki Tuomi (dd8dbd1) + + lib-dict: Reuse LDAP connections + + +M src/lib-dict/dict-ldap.c + +2016-04-11 17:29:02 +0300 Aki Tuomi (3b84023) + + lib-ldap: Max idle time is seconds + + +M src/lib-dict/dict-ldap.c +M src/lib-ldap/ldap-client.h +M src/lib-ldap/ldap-connection.c + +2016-04-11 17:27:31 +0300 Aki Tuomi (d4a4ddf) + + lib-ldap: Do not call NULL callback + + +M src/lib-ldap/ldap-connection.c + +2016-04-12 21:22:48 +0300 Timo Sirainen (76a58bc) + + lib: Moved enum iostream_rawlog_flags to public iostream-rawlog.h + + This allows using [io]stream-rawlog.h APIs directly. + +M src/lib/iostream-rawlog-private.h +M src/lib/iostream-rawlog.h + +2016-04-12 20:00:51 +0300 Timo Sirainen (d1eec04) + + lib: Added ostream-null + + +M src/lib/Makefile.am +A src/lib/ostream-null.c +A src/lib/ostream-null.h + +2016-04-12 16:48:34 +0300 Timo Sirainen (f7cc532) + + lib-storage: Fixed crash when using SEARCH INTHREAD + + mail_search_args_init() -> mail_search_args_simplify() -> .. -> + mail_search_arg_one_equals(), which assumed SEARCH_INTHREAD was already + initialized. + +M src/lib-storage/mail-search.c + +2016-04-10 14:41:28 +0300 Timo Sirainen (87404ea) + + doveconf: Log a warning if a global setting is updated after it was already + set inside a filter + + For example: + + protocol imap { + mail_plugins = $mail_plugins imap_quota + } mail_plugins = $mail_plugins quota + + Will result in: + + doveconf: Warning: dovecot.conf line 4: Global setting mail_plugins won't + change the setting inside an earlier filter at dovecot.conf line 2 + +M src/config/config-parser-private.h +M src/config/config-parser.c + +2016-04-10 14:39:22 +0300 Timo Sirainen (6347bb6) + + doveconf, config: Free all memory at deinit + + +M src/config/config-parser.c +M src/config/config-parser.h +M src/config/doveconf.c +M src/config/main.c + +2016-04-06 14:45:01 +0300 Timo Sirainen (06116e6) + + imapc: Mark most of the commands retriable. + + +M src/lib-storage/index/imapc/imapc-list.c +M src/lib-storage/index/imapc/imapc-save.c +M src/lib-storage/index/imapc/imapc-storage.c + +2016-04-06 14:44:00 +0300 Timo Sirainen (461bcfc) + + imapc: If root separator lookup fails, fail all further lookups. + + We already returned a potentially wrong separator (since there's no way to + return error), so we don't want to continue and possibly make things worse. + +M src/lib-storage/index/imapc/imapc-list.c +M src/lib-storage/index/imapc/imapc-list.h + +2016-04-06 14:43:02 +0300 Timo Sirainen (2a7a7f6) + + imapc: Added missing error handling to subscriptions list refreshing. + + +M src/lib-storage/index/imapc/imapc-list.c + +2016-04-06 14:41:16 +0300 Timo Sirainen (e74f4af) + + imapc: Fixed mailbox_exists() error handling. + + +M src/lib-storage/index/imapc/imapc-storage.c + +2016-04-06 14:24:21 +0300 Timo Sirainen (e4020d1) + + imapc: Support retrying after connect() failure. + + +M src/lib-imap-client/imapc-connection.c +M src/lib-imap-client/imapc-connection.h + +2016-04-06 14:17:02 +0300 Timo Sirainen (1e85b60) + + imapc: Support retrying after connect/authentication timeouts. + + +M src/lib-imap-client/imapc-connection.c + +2016-04-06 14:16:13 +0300 Timo Sirainen (3153bce) + + imapc: Support retrying for non-mailbox commands. + + +M src/lib-imap-client/imapc-connection.c + +2016-04-06 14:12:25 +0300 Timo Sirainen (b60daa2) + + imapc: Prepare for non-mailbox command retrying: Set reconnect_command_count + earlier + + This probably doesn't fix itself anything yet, but is needed for the + following changes. + +M src/lib-imap-client/imapc-client.c +M src/lib-imap-client/imapc-connection.c +M src/lib-imap-client/imapc-connection.h + +2016-04-06 14:09:13 +0300 Timo Sirainen (5e02162) + + imapc: Fixed checking of whether same IMAP command keeps crashing server. + + reconnect_command_count was counting only the post-login commands, but we + were decreasing it also for pre-login commands. This caused it to shrink to + 0 too early. + +M src/lib-imap-client/imapc-connection.c + +2016-04-06 14:05:26 +0300 Timo Sirainen (5ba8e64) + + imapc: Code cleanup - imapc_connection_reconnect() is now always called when + reconnect is ok. + + +M src/lib-imap-client/imapc-client.c + +2016-04-06 14:03:20 +0300 Timo Sirainen (8cd9a12) + + imapc: Code cleanup - Use a common function for checking/logging if we want + to reconnect or disconnect + + +M src/lib-imap-client/imapc-connection.c + +2016-04-06 13:52:24 +0300 Timo Sirainen (0e2e526) + + lib-storage: Fixed error handling for mailbox_list_iter_init_namespaces() + + If iteration for the first namespace failed, we tried to copy the error + string to error_list, which was the same first namespace's list. This caused + the error string to be freed while it was being copied, so the end result + was that the error became either an empty or garbage string. + +M src/lib-storage/list/mailbox-list-iter.c + +2016-04-06 12:41:38 +0300 Timo Sirainen (03af8e5) + + dsync: Don't export header hashes if remote mailbox is empty. + + This avoids doing a lot of work of reading through all mails' headers and + hashing them, when the hashes aren't actually going to be used for anything. + +M src/doveadm/dsync/dsync-brain-mailbox.c +M src/doveadm/dsync/dsync-mailbox-export.c +M src/doveadm/dsync/dsync-mailbox-export.h + +2016-04-12 11:42:38 +0200 Stephan Bosch (a1ffc40) + + lib-http: server: Fixed bug in request reference counting caused by earlier + fix (390b600a6f7fdb4ccc65950527ee30129f49a6ac). + + The earlier change erroneously dropped two lines that unreferenced the + request object after calling the callback. + +M src/lib-http/http-server-connection.c + +2016-04-12 10:49:50 +0300 Timo Sirainen (a8f11f9) + + lib-master: Fixed assert-crash when HAProxy aborts connections. + + close() was called before io_remove(), which resulted in: + + Panic: epoll_ctl(del, 14) failed: Bad file descriptor + +M src/lib-master/master-service-haproxy.c + +2016-04-11 12:24:59 +0300 Timo Sirainen (cc5493d) + + dict-ldap: Compiler warning fix + + +M src/lib-dict/dict-ldap.c + +2016-04-11 09:40:22 +0300 Aki Tuomi (1af8b31) + + lib-dict: Add ldap driver + + +M src/lib-dict/Makefile.am +A src/lib-dict/dict-ldap-settings.c +A src/lib-dict/dict-ldap-settings.h +A src/lib-dict/dict-ldap.c + +2016-04-11 09:38:27 +0300 Aki Tuomi (b4c47b7) + + configure: Add lib-ldap + + +M configure.ac +M src/Makefile.am + +2016-04-11 09:37:39 +0300 Aki Tuomi (844129d) + + lib-ldap: Add lib-ldap implementation + + +A src/lib-ldap/Makefile.am +A src/lib-ldap/ldap-client.c +A src/lib-ldap/ldap-client.h +A src/lib-ldap/ldap-compare.c +A src/lib-ldap/ldap-connection.c +A src/lib-ldap/ldap-entry.c +A src/lib-ldap/ldap-iterator.c +A src/lib-ldap/ldap-private.h +A src/lib-ldap/ldap-search.c + +2016-04-10 14:57:48 +0300 Timo Sirainen (9a69030) + + lib-master: Fixed memory leaks when failing to read settings. + + +M src/lib-master/master-service-settings.c + +2016-04-07 17:50:28 +0300 Timo Sirainen (e3367d7) + + virtual plugin: struct mail_vfuncs.close() wasn't implemented. + + This wasn't a problem normally, because the core code wouldn't try to call + this. It became a problem only after other plugins were trying to call it. + +M src/plugins/virtual/virtual-mail.c + +2016-04-07 16:35:28 +0300 Timo Sirainen (9f41af1) + + lib-master: Preserve LOG_STDERR_TIMESTAMP environment through doveconf exec. + + This should be needed only for standalone programs, so don't bother trying + to preserve it otherwise. + +M src/lib-master/master-service-settings.c + +2016-04-05 20:14:15 +0300 Timo Sirainen (aeea3db) + + lmtp: Use separate session ID suffixes for each RCPT TO delivery. + + Otherwise each delivery will use the same session ID when talking to stats + process, which results in errors like: + + Error: stats: FIFO input error: CONNECT: Duplicate session ID + ME3ZHCi+A1dUDQAAvAUe3g for user foobar service lmtp Warning: stats: Couldn't + find session ID: ME3ZHCi+A1dUDQAAvAUe3g + + (There was a DISCONNECT for the session ID between these two log lines.) + +M src/lmtp/client.h +M src/lmtp/commands.c + +2016-04-05 20:10:53 +0300 Timo Sirainen (6cb874b) + + lib-storage: Changed separator between session_id_prefix and unique part to + be ':' + + Although '-' wasn't used by default either, it's much more likely that + custom session IDs might contain it. ':' is hopefully less likely to be + used. This allows log parsers that actually want to find out the original + session's all log lines to cut out everything after the initial ':'. + +M src/lib-storage/mail-storage-service.c + +2016-04-06 22:43:52 +0300 Timo Sirainen (a50f8b9) + + lmtp: Changed default LMTP proxy timeout to 125 seconds. + + The main problem with LMTP proxy timing out too early is that it causes + duplicates if the backend actually finishes the mail delivery. + + The 30 seconds is bad, because there are various timeouts in backend set to + 30 seconds also. 125 seconds is hopefully large enough to hit most of the 2 + minute timeouts and we'll have a few extra seconds left to see the failure. + +M src/lmtp/commands.c + +2016-04-06 22:12:54 +0300 Timo Sirainen (53c4294) + + doveadm sync: -R parameter shouldn't switch to "doveadm backup -R" behavior. + + Just ignore the -R parameter for doveadm sync, unless -1 parameter is also + used. Alternatively we could also fail the command, but maybe that's + unnecessary extra work. + +M src/doveadm/doveadm-dsync.c + +2016-04-06 22:08:14 +0300 Timo Sirainen (eba17ec) + + doveadm: Reverted 7a3b52b8f - doveadm sync -1 -R is useful. + + +M src/doveadm/doveadm-dsync.c + +2016-04-06 20:19:04 +0300 Timo Sirainen (2fb829d) + + dict-redis: When timeout was reached, we didn't actually stop but just + continued waiting. + + +M src/lib-dict/dict-redis.c + +2016-04-04 21:05:44 +0300 Aki Tuomi (b0b6999) + + doveadm-http: Fix mismatch in authorization + + The code advertizes X-Dovecot-API in WWW-Authenticate header, but expects + X-Doveadm-API in Authorization header. This change makes it expect + X-Dovecot-API. + +M src/doveadm/client-connection-http.c + +2016-04-05 19:59:18 +0300 Timo Sirainen (e82efb3) + + imapc: If we get disconnected during SELECT/EXAMINE, retry it once. + + This seems to be happening especially with dsync migrations from IMAP + servers with small timeouts. The initial dsync run opens imapc connection + early to do a LIST + SELECT the first mailbox, but then dsync may spend a + while creating all the local mailboxes before it continues using the imapc + connection. + +M src/lib-imap-client/imapc-client.c +M src/lib-storage/index/imapc/imapc-storage.c + +2016-04-05 16:26:08 +0300 Timo Sirainen (dca6152) + + fts-tika: Don't crash on 500 errors (caused by 146f6f85d) + + http_req=NULL here set by http_client_request_send_payload(). Even if it + wasn't, the payload wouldn't be there. + +M src/plugins/fts/fts-parser-tika.c + +2016-04-05 12:05:15 +0300 Aki Tuomi (76537b1) + + doveadm-proxy: Change to work with doveadm ver2 + + +M src/doveadm/doveadm-proxy.c + +2016-04-04 12:22:06 +0300 Timo Sirainen (6fbc1a2) + + lib-storage: FS layout assert-crashed when trying to list with invalid UTF8 + pattern + + +M src/lib-storage/list/mailbox-list-fs-iter.c + +2016-04-04 11:11:13 +0300 Timo Sirainen (05e8b3e) + + lib: Updated fdpass.h comments. + + +M src/lib/fdpass.h + +2016-04-03 22:54:17 +0200 Stephan Bosch (d17a99d) + + istream-unix: Fixed handling of EOF from fd_read() (ret==0). + + This situation was ignored. + +M src/lib/istream-unix.c + +2016-03-31 16:35:06 +0300 Teemu Huovila (4adefdb) + + quota: Fix NetBSD build. + + +M src/plugins/quota/quota-fs.c + +2016-03-31 12:41:25 +0300 Aki Tuomi (9ba5c49) + + doveadm-mail: Honor -u flag on v1 commands + + +M src/doveadm/doveadm-mail.c + +2016-03-30 16:24:56 +0300 Timo Sirainen (a2fdfd2) + + doveadm-server: Register builtin dict drivers always at init + + This was already done for doveadm. Fixes using doveadm dict commands via + doveadm-server. + +M src/doveadm/main.c + +2016-03-30 13:14:40 +0300 Aki Tuomi (c3ffcb7) + + doveadm-mail: Initialize missing cmd context username + + Fixes assert-crash in doveadm_mail_single_user() + +M src/doveadm/doveadm-mail.c + +2016-03-30 10:51:50 +0300 Timo Sirainen (0be3a0d) + + lib-storage: Fixed memory leak when iterating attributes. + + +M src/lib-storage/mailbox-attribute.c + +2016-03-30 10:34:06 +0300 Aki Tuomi (4af926f) + + doveadm-mail: Don't lose rip/lip/lport/rport in passdb lookups for doveadm + TCP connections + + +M src/doveadm/doveadm-mail.c + +2016-03-30 08:24:51 +0300 Timo Sirainen (002eaed) + + director: Avoid a potential assert-crash after removing a director from + ring. + + This should fix the crash: Panic: director: file director-connection.c: line + 1926 (director_connection_init_out): assertion failed: (!host->removed) + + Also moved the last_network_failure timestamp reset a bit later, since + there's no need to reset the timestamp if we're not actually connecting to + the server. + +M src/director/director-connection.c + +2016-03-29 21:17:22 +0300 Timo Sirainen (315aa3c) + + doveadm: Fixed reading USER environment for v1 commands. + + +M src/doveadm/doveadm-mail.c + +2016-03-29 20:38:19 +0300 Timo Sirainen (969f57f) + + imapc: Don't try to FETCH uncommitted mails, because it would attempt to + FETCH uid=0 + + +M src/lib-storage/index/imapc/imapc-mail-fetch.c + +2016-03-29 15:17:29 +0300 Timo Sirainen (e052c22) + + auth: Disable auth caching for passwd-file + + Its caching is usually unnecessary, because the passwd-files are efficiently + in memory already. It's also problematic, because extra_fields can contain + %variables, which can be lookup-dependent. So for example if %{lport} is + used in extra_fields, it would need to be included in the cache key. But + because different variables can be used by different users' extra_fields, + there's really no good way to include all of it in the cache key. + +M src/auth/passdb-passwd-file.c +M src/auth/userdb-passwd-file.c + +2016-03-29 15:04:01 +0300 Timo Sirainen (3e25053) + + doveadm-batch: Fixed error message for an unknown subcommand. + + +M src/doveadm/doveadm-mail-batch.c + +2016-03-29 14:57:20 +0300 Timo Sirainen (edbc6fe) + + doveadm: Fixed adding username header to commands iterating through multiple + users. + + +M src/doveadm/doveadm-mail.c + +2016-03-29 14:17:01 +0300 Timo Sirainen (32e1486) + + doveadm-server: v2 mail commands weren't doing a userdb lookup. + + +M src/doveadm/doveadm-mail.c + +2016-03-29 14:10:10 +0300 Timo Sirainen (6a8c95b) + + doveadm-server: Fixed running multi-word commands. + + The problem with for example "mailbox status" command is that: + - doveadm cli: argv[0] = "mailbox", argv[1] = "status" + - doveadm-server: argv[0] = "mailbox status" + + So with doveadm cli we'll now instead just skip over words until argv[0] is + the last word of the command ("status"). + +M src/doveadm/client-connection.c +M src/doveadm/doveadm-cmd.c +M src/doveadm/doveadm-cmd.h +M src/doveadm/doveadm-mail-batch.c + +2016-03-29 14:06:43 +0300 Timo Sirainen (36a052b) + + doveadm: Code cleanup - always use const char *const[] type for argv. + + Needed to fix compiler warnings in the following patch. + +M src/doveadm/client-connection.c +M src/doveadm/doveadm-cmd.c +M src/doveadm/doveadm-cmd.h +M src/doveadm/doveadm.c + +2016-03-29 12:15:05 +0300 Timo Sirainen (cbaac1e) + + login-proxy: When logging failures, include the client info prefix. + + +M src/login-common/client-common-auth.c +M src/login-common/login-proxy.c + +2016-03-29 11:28:55 +0300 Timo Sirainen (200b024) + + login-*: When logging about client certificate validity, include the client + info prefix. + + +M src/login-common/ssl-proxy-openssl.c + +2016-03-25 03:01:00 +0900 Timo Sirainen (090c9c2) + + auth: If user is unknown and there are more passdbs/userdb, log about it. + + +M src/auth/auth-request.c + +2016-03-25 02:48:55 +0900 Stephan Bosch (173d538) + + lib-http: client: Fixed request timeout handling during pipelining. + + The timeout was not managed correctly. If an earlier request finished, it + would not restart the timeout for the next pending request. + + Also, filling the pipeline caused the timout to be reset inappropriately, + postponing its expiry. + +M src/lib-http/http-client-connection.c +M src/lib-http/http-client-private.h +M src/lib-http/http-client-request.c + +2016-03-25 02:47:28 +0900 Stephan Bosch (8cf6363) + + lib-http: client: Fixed handling of stalled connections that emerge when the + client ioloop hasn't run for a long time. + + Inside the peer's request handler routine, the connections are verified + after the ioloop continues. If they turn out to be broken, they + self-destruct while the handler routine is active, leading to problems. + + Solved by referencing the connection and retrying the connection statistics + loop when a connection is lost in the process. + +M src/lib-http/http-client-peer.c + +2016-03-25 00:45:54 +0900 Timo Sirainen (4f9855b) + + Set postmaster_address=%d by default because imap now loads lda settings and + it must be non-empty. + + We don't want imap to suddenly start failing because of the c15e8f33c + change. This isn't a perfect solution either, but should be ok enough. + +M src/lib-lda/lda-settings.c + +2016-03-24 10:07:15 +0900 Timo Sirainen (afbc622) + + director: Make sure freeing a user doesn't leak a timeout. + + +M src/director/user-directory.c + +2016-03-24 10:01:17 +0900 Timo Sirainen (6f8d511) + + director: Fixed memory leak when killing a user. + + +M src/director/director.c + +2016-03-24 10:00:00 +0900 Timo Sirainen (488d921) + + director: Make sure a long-delayed kill reply for user doesn't mess up the + state. + + This should fix assert-crash: + + director: Panic: file director.c: line 690 + (director_user_kill_finish_delayed_to): assertion failed: + (ctx->user->kill_state == USER_KILL_STATE_DELAY) + +M src/director/director.c + +2016-03-24 09:43:43 +0900 Timo Sirainen (5897c88) + + director: Small improvements to director-test.sh + + Test with a bigger director ring. Include microseconds in log timestamps to + make debugging easier. Changed the name of the info_log_path. + +M src/director/director-test.sh + +2016-03-24 09:42:50 +0900 Timo Sirainen (58b8a30) + + director: Don't re-send SYNC unnecessarily often. + + +M src/director/director-connection.c +M src/director/director.c +M src/director/director.h + +2016-03-24 09:36:14 +0900 Timo Sirainen (f8c57c3) + + director: Fixed user weakness getting stuck if multiple directors set user + weak simultaneously + + +M src/director/director-connection.c + +2016-03-23 23:33:49 +0900 Timo Sirainen (a986ef3) + + pop3-login: XCLIENT / XOIP no longer return -ERR for untrusted IP ranges. + + The command is simply ignored, similarly to imap-login ID. + +M src/pop3-login/client.c + +2016-03-23 09:01:31 +0200 Aki Tuomi (6199949) + + doveadm: Move getenv to correct place + + All getenv()s must be done after master_service_init() or the pointer will + be corrupted with Linux and other OSes without setproctitle(). + +M src/doveadm/doveadm.c + +2016-03-22 01:16:26 +0100 Stephan Bosch (c15e8f3) + + imap: Made LDA settings accessible from plugins. + + This way, plugins can also send mail. + +M src/imap/Makefile.am +M src/imap/imap-client.c +M src/imap/imap-client.h +M src/imap/main.c + +2016-03-22 09:19:45 +0200 Aki Tuomi (fcb8a4a) + + doveadm-server: Fixed initializing username for mail commands. + + +M src/doveadm/client-connection.c + +2016-03-23 10:08:06 +0900 Timo Sirainen (7b98fc3) + + doveadm: Getting user from USER environment wasn't done in the right place. + + doveadm_mail_cmdline_init() is also called when parsing commands from + doveadm-server. The USER environment is supposed to be read only from + doveadm command line. + +M src/doveadm/doveadm-mail.c +M src/doveadm/doveadm.c + +2016-03-21 22:10:08 +0900 Timo Sirainen (4a76960) + + lazy-expunge: Fixed crash if lazy_expunge-namespace was not found. + + +M src/plugins/lazy-expunge/lazy-expunge-plugin.c + +2016-03-21 21:51:49 +0900 Timo Sirainen (65d8efa) + + lib: Avoid assert-crash in istream-concat at close. + + If stream was seeked to EOF, cur_input=NULL and closing the stream would + cause i_stream_concat_skip() to crash. Fixed this by making sure cur_input + is never NULL. This also adds a check to not allow seeking past EOF, but + this shouldn't happen anyway. + +M src/lib/istream-concat.c + +2016-03-21 21:46:47 +0900 Timo Sirainen (4219733) + + lib: Small code cleanup to istream-concat - don't use a magic UINT_MAX value + as error code + + +M src/lib/istream-concat.c + +2016-03-11 17:44:41 +1300 Timo Sirainen (2586654) + + lib-storage: Support autoexpunging from wildcards mailbox names. For + example: + + mailbox Trash { + autoexpunge = 30d + } mailbox Trash/* { + autoexpunge = 30d + } + +M src/lib-storage/mail-autoexpunge.c + +2016-03-03 19:55:03 -0700 Michael M Slusarz (20ad75b) + + doveadm: Fix typos in error messages + + +M src/doveadm/client-connection-http.c + +2016-03-11 18:01:33 +1300 Timo Sirainen (8281cfd) + + lazy-expunge: If lazy_expunge is set to namespace root, save all mails to + the root mailbox. + + So the difference is: + + namespace { + prefix = expunged/ + .. + } plugin { + # Move expunged mails to expunged/INBOX, expunged/Trash, etc. mailboxes + lazy_expunge = expunged/ + # Move all expunged mails to "expunged" mailbox, which is the namespace + root. + lazy_expunge = expunged + } + +M src/plugins/lazy-expunge/lazy-expunge-plugin.c + +2016-03-11 17:57:41 +1300 Timo Sirainen (eade058) + + lazy-expunge: Code cleanup - move destination mailbox name generation to its + own function + + +M src/plugins/lazy-expunge/lazy-expunge-plugin.c + +2016-03-16 09:27:04 +0200 Teemu Huovila (998395f) lib-fts: Fix unit tests for lib-fts. M src/lib-fts/test-fts-tokenizer.c -2016-02-29 19:29:14 +0200 Phil Carmody (96fbb1f) +2016-03-16 16:34:32 +1100 Timo Sirainen (7a3b52b) + + doveadm sync: Don't allow -R parameter. + + -R implicitly enabled doveadm backup mode, which wasn't supposed to happen. + +M src/doveadm/doveadm-dsync.c + +2016-02-29 19:29:14 +0200 Phil Carmody (b22dcc3) plugins: fts-expunge-log - subtraction from and dumping of a flattened log @@ -28,7 +1447,7 @@ M src/plugins/fts/fts-expunge-log.c M src/plugins/fts/fts-expunge-log.h -2016-03-12 01:56:55 +0100 Stephan Bosch (652edd6) +2016-03-12 01:56:55 +0100 Stephan Bosch (ca270e3) lib-http: client: Improved test-http-payload to test partial reading of response payload. @@ -37,7 +1456,7 @@ M src/lib-http/http-client-connection.c M src/lib-http/test-http-payload.c -2016-03-03 22:29:44 +0100 Stephan Bosch (7b8d9e9) +2016-03-03 22:29:44 +0100 Stephan Bosch (641ab76) lib-http: server: Improved test-http-payload to test partial reading of request payload. @@ -45,7 +1464,7 @@ M src/lib-http/test-http-payload.c -2016-03-03 22:28:47 +0100 Stephan Bosch (4536601) +2016-03-03 22:28:47 +0100 Stephan Bosch (390b600) lib-http: server: Fixed handling of partially read request payload. @@ -54,7 +1473,7 @@ M src/lib-http/http-server-connection.c M src/lib-http/http-server-request.c -2016-03-15 10:48:31 +0200 Teemu Huovila (66d3d20) +2016-03-15 10:48:31 +0200 Teemu Huovila (af177be) lib-fts: Limit maximum length of addresses found. @@ -67,7 +1486,7 @@ M src/lib-fts/fts-tokenizer-address.c M src/lib-fts/test-fts-tokenizer.c -2016-03-15 10:47:20 +0200 Teemu Huovila (1110079) +2016-03-15 10:47:20 +0200 Teemu Huovila (00544ad) lib-fts: Lift helper function out of generic tokenizer. @@ -77,14 +1496,14 @@ A src/lib-fts/fts-tokenizer-common.h M src/lib-fts/fts-tokenizer-generic.c -2016-03-16 10:55:01 +1100 Timo Sirainen (0af104b) +2016-03-16 10:55:01 +1100 Timo Sirainen (613d69e) virtual plugin: Fixed off-by-one in virtual_max_open_mailboxes check. M src/plugins/virtual/virtual-storage.c -2016-03-16 10:33:26 +1100 Timo Sirainen (a859547) +2016-03-16 10:33:26 +1100 Timo Sirainen (74bf1be) virtual plugin: Don't assert-crash if backend mailbox is recreated while virtual mailbox is open. @@ -92,14 +1511,14 @@ M src/plugins/virtual/virtual-sync.c -2016-03-16 10:23:52 +1100 Timo Sirainen (7429118) +2016-03-16 10:23:52 +1100 Timo Sirainen (5b7ff90) virtual plugin: Handle backend mailbox deletion on backend open/sync M src/plugins/virtual/virtual-sync.c -2016-03-16 10:17:45 +1100 Timo Sirainen (a2736e5) +2016-03-16 10:17:45 +1100 Timo Sirainen (1ce59b0) virtual plugin: Code cleanup - remove confusing bbox_index_opened @@ -109,7 +1528,7 @@ M src/plugins/virtual/virtual-sync.c -2016-03-16 10:04:32 +1100 Timo Sirainen (9fb02dc) +2016-03-16 10:04:32 +1100 Timo Sirainen (76fd7aa) virtual plugin: If we detect backend box to be deleted, mark it permanently deleted. @@ -118,28 +1537,78 @@ M src/plugins/virtual/virtual-storage.h M src/plugins/virtual/virtual-sync.c -2016-03-16 09:30:20 +1100 Timo Sirainen (c99596a) +2016-03-16 09:30:20 +1100 Timo Sirainen (baa93d5) dbox: Fixed pop3.order caching for mails without no specified order. M src/lib-storage/index/dbox-common/dbox-mail.c -2016-03-10 14:59:46 +1300 Timo Sirainen (9354228) +2016-03-11 19:03:34 +1300 Timo Sirainen (11120ac) + + doveadm-auth: Added missing code forgotten from commit 208754367 + + +M src/lib-storage/mail-storage-service.c +M src/lib-storage/mail-storage-service.h + +2016-03-11 18:43:57 +1300 Timo Sirainen (6aafdd8) + + auth: Code cleanup - avoid using void *context + + auth_request_callback_t always uses struct auth_client/master_connection* in + the context - no need to try to be too generic here. + +M src/auth/auth-master-connection.c +M src/auth/auth-master-connection.h +M src/auth/auth-request-handler.c +M src/auth/auth-request-handler.h + +2016-03-11 18:37:43 +1300 Timo Sirainen (2087543) + + doveadm-auth: If auth_debug setting is enabled, send "debug" field to auth + lookups. + + The idea is that you could enable auth_debug for specific requests with + e.g.: + + doveadm -o auth_debug=yes user user@example.com + +M src/doveadm/doveadm-auth.c +M src/doveadm/doveadm-settings.c +M src/doveadm/doveadm-settings.h +M src/lib-auth/auth-client-request.c +M src/lib-auth/auth-client.h +M src/lib-auth/auth-master.c +M src/lib-auth/auth-master.h + +2016-03-11 18:37:04 +1300 Timo Sirainen (d76a914) + + auth: If auth request contains "debug" field, enable auth_debug=yes for the + request. + + +M src/auth/auth-request.c +M src/auth/auth-request.h +M src/auth/db-ldap.c +M src/auth/passdb-imap.c +M src/auth/userdb-prefetch.c + +2016-03-10 14:59:46 +1300 Timo Sirainen (3b39022) lib-fs: Fixed fs-sis to work again M src/lib-fs/fs-posix.c -2016-03-04 16:40:23 +0200 Timo Sirainen (27c5000) +2016-03-04 16:40:23 +0200 Timo Sirainen (2839c7c) doveadm who: Don't require mask parameter. M src/doveadm/doveadm-who.c -2016-03-04 13:12:59 +0200 Timo Sirainen (3e6b7d0) +2016-03-04 13:12:59 +0200 Timo Sirainen (e50a729) config: Escape regexps properly in settings-get.pl to avoid warnings with new Perl @@ -147,14 +1616,6 @@ M src/config/settings-get.pl -2016-03-04 13:02:37 +0200 Timo Sirainen (fe789d2) - - v2.2.22.rc1 released - - -M NEWS -M configure.ac - 2016-03-03 16:10:51 +0200 Timo Sirainen (78d33b5) fts: Added "doveadm fts tokenize" command. diff -Nru dovecot-2.2.22/compile dovecot-2.2.24/compile --- dovecot-2.2.22/compile 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/compile 2015-12-09 15:53:17.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify diff -Nru dovecot-2.2.22/config.guess dovecot-2.2.24/config.guess --- dovecot-2.2.22/config.guess 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/config.guess 2015-12-09 15:53:17.000000000 +0000 @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-03-23' +timestamp='2015-08-20' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -24,12 +24,12 @@ # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` @@ -50,7 +50,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -168,20 +168,27 @@ # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -197,6 +204,13 @@ os=netbsd ;; esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need @@ -207,13 +221,13 @@ release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -235,6 +249,9 @@ *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -579,8 +596,9 @@ else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi @@ -932,6 +950,9 @@ crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -1020,7 +1041,7 @@ echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} diff -Nru dovecot-2.2.22/config.h.in dovecot-2.2.24/config.h.in --- dovecot-2.2.22/config.h.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/config.h.in 2016-04-26 14:29:23.000000000 +0000 @@ -489,6 +489,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_VMOUNT_H +/* Define to 1 if you have the `timegm' function. */ +#undef HAVE_TIMEGM + /* Define if you have struct tm->tm_gmtoff */ #undef HAVE_TM_GMTOFF diff -Nru dovecot-2.2.22/config.sub dovecot-2.2.24/config.sub --- dovecot-2.2.22/config.sub 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/config.sub 2015-12-09 15:53:17.000000000 +0000 @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2014-09-11' +timestamp='2015-08-20' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -68,7 +68,7 @@ version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -117,7 +117,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -255,12 +255,13 @@ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ @@ -305,7 +306,7 @@ | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -313,6 +314,7 @@ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -327,6 +329,9 @@ c6x) basic_machine=tic6x-unknown ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none @@ -372,12 +377,13 @@ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ @@ -424,12 +430,13 @@ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -437,6 +444,7 @@ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ + | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -513,6 +521,9 @@ basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -774,6 +785,9 @@ basic_machine=m68k-isi os=-sysv ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; m68knommu) basic_machine=m68k-unknown os=-linux @@ -1365,7 +1379,7 @@ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ diff -Nru dovecot-2.2.22/configure dovecot-2.2.24/configure --- dovecot-2.2.22/configure 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/configure 2016-04-26 15:10:48.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Dovecot 2.2.22. +# Generated by GNU Autoconf 2.69 for Dovecot 2.2.24. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='Dovecot' PACKAGE_TARNAME='dovecot' -PACKAGE_VERSION='2.2.22' -PACKAGE_STRING='Dovecot 2.2.22' +PACKAGE_VERSION='2.2.24' +PACKAGE_STRING='Dovecot 2.2.24' PACKAGE_BUGREPORT='dovecot@dovecot.org' PACKAGE_URL='' @@ -677,6 +677,7 @@ sql_drivers LIBDOVECOT_LIBFTS_DEPS LIBDOVECOT_LIBFTS +LIBDOVECOT_LDAP LIBDOVECOT_LDA LIBDOVECOT_DSYNC LIBDOVECOT_COMPRESS @@ -685,6 +686,7 @@ LIBDOVECOT_STORAGE_DEPS LIBDOVECOT_STORAGE LIBDOVECOT_DEPS +LIBDOVECOT_LA_LIBS LIBDOVECOT mailbox_list_drivers LINKED_STORAGE_LDADD @@ -709,6 +711,8 @@ CRYPT_LIBS MYSQL_CONFIG PG_CONFIG +HAVE_LDAP_FALSE +HAVE_LDAP_TRUE LDAP_PLUGIN_FALSE LDAP_PLUGIN_TRUE LDAP_LIBS @@ -1504,7 +1508,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Dovecot 2.2.22 to adapt to many kinds of systems. +\`configure' configures Dovecot 2.2.24 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1575,7 +1579,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Dovecot 2.2.22:";; + short | recursive ) echo "Configuration of Dovecot 2.2.24:";; esac cat <<\_ACEOF @@ -1765,7 +1769,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Dovecot configure 2.2.22 +Dovecot configure 2.2.24 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2492,7 +2496,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Dovecot $as_me 2.2.22, which was +It was created by Dovecot $as_me 2.2.24, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2842,7 +2846,7 @@ cat >>confdefs.h <<_ACEOF -#define DOVECOT_ABI_VERSION "2.2.ABIv22($PACKAGE_VERSION)" +#define DOVECOT_ABI_VERSION "2.2.ABIv24($PACKAGE_VERSION)" _ACEOF @@ -3363,7 +3367,7 @@ # Define the identity of the package. PACKAGE='dovecot' - VERSION='2.2.22' + VERSION='2.2.24' cat >>confdefs.h <<_ACEOF @@ -19589,7 +19593,7 @@ getmntinfo setpriority quotactl getmntent kqueue kevent \ backtrace_symbols walkcontext dirfd clearenv \ malloc_usable_size glob fallocate posix_fadvise \ - getpeereid getpeerucred inotify_init + getpeereid getpeerucred inotify_init timegm do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -23851,6 +23855,13 @@ LDAP_PLUGIN_FALSE= fi + if test "$want_ldap" = "yes"; then + HAVE_LDAP_TRUE= + HAVE_LDAP_FALSE='#' +else + HAVE_LDAP_TRUE='#' + HAVE_LDAP_FALSE= +fi dict_drivers= @@ -25149,6 +25160,7 @@ fi +LIBDOVECOT_LA_LIBS='$(top_builddir)/src/lib-dict-extra/libdict_extra.la $(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-stats/libstats.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' if test "$want_shared_libs" = "yes"; then LIBDOVECOT_DEPS='$(top_builddir)/src/lib-dovecot/libdovecot.la' LIBDOVECOT="$LIBDOVECOT_DEPS \$(MODULE_LIBS)" @@ -25156,12 +25168,17 @@ LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else - LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-stats/libstats.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' + LIBDOVECOT_DEPS="$LIBDOVECOT_LA_LIBS" LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV) \$(MODULE_LIBS)" LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libstorage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la' fi +if test $want_ldap != no; then + LIBDOVECOT_LDAP='$(top_builddir)/src/lib-ldap/libdovecot-ldap.la' +else + LIBDOVECOT_LDAP='' +fi LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_DEPS" LIBDOVECOT_DSYNC='$(top_builddir)/src/doveadm/dsync/libdovecot-dsync.la' LIBDOVECOT_SQL='$(top_builddir)/src/lib-sql/libsql.la' @@ -25180,6 +25197,8 @@ + + build_pgsql=no build_mysql=no build_sqlite=no @@ -26313,7 +26332,7 @@ ac_config_headers="$ac_config_headers config.h" -ac_config_files="$ac_config_files Makefile doc/Makefile doc/man/Makefile doc/wiki/Makefile doc/example-config/Makefile doc/example-config/conf.d/Makefile src/Makefile src/lib/Makefile src/lib-sql/Makefile src/lib-auth/Makefile src/lib-charset/Makefile src/lib-compression/Makefile src/lib-dict/Makefile src/lib-dns/Makefile src/lib-fs/Makefile src/lib-fts/Makefile src/lib-http/Makefile src/lib-imap/Makefile src/lib-imap-storage/Makefile src/lib-imap-client/Makefile src/lib-imap-urlauth/Makefile src/lib-index/Makefile src/lib-lda/Makefile src/lib-mail/Makefile src/lib-master/Makefile src/lib-ntlm/Makefile src/lib-otp/Makefile src/lib-dovecot/Makefile src/lib-sasl/Makefile src/lib-settings/Makefile src/lib-ssl-iostream/Makefile src/lib-stats/Makefile src/lib-test/Makefile src/lib-storage/Makefile src/lib-storage/list/Makefile src/lib-storage/index/Makefile src/lib-storage/index/imapc/Makefile src/lib-storage/index/pop3c/Makefile src/lib-storage/index/maildir/Makefile src/lib-storage/index/mbox/Makefile src/lib-storage/index/dbox-common/Makefile src/lib-storage/index/dbox-multi/Makefile src/lib-storage/index/dbox-single/Makefile src/lib-storage/index/cydir/Makefile src/lib-storage/index/raw/Makefile src/lib-storage/index/shared/Makefile src/lib-storage/register/Makefile src/anvil/Makefile src/auth/Makefile src/config/Makefile src/doveadm/Makefile src/doveadm/dsync/Makefile src/lda/Makefile src/log/Makefile src/lmtp/Makefile src/dict/Makefile src/director/Makefile src/dns/Makefile src/indexer/Makefile src/ipc/Makefile src/imap/Makefile src/imap-hibernate/Makefile src/imap-login/Makefile src/imap-urlauth/Makefile src/login-common/Makefile src/master/Makefile src/pop3/Makefile src/pop3-login/Makefile src/replication/Makefile src/replication/aggregator/Makefile src/replication/replicator/Makefile src/ssl-params/Makefile src/stats/Makefile src/util/Makefile src/plugins/Makefile src/plugins/acl/Makefile src/plugins/imap-acl/Makefile src/plugins/autocreate/Makefile src/plugins/expire/Makefile src/plugins/fs-compress/Makefile src/plugins/fts/Makefile src/plugins/fts-lucene/Makefile src/plugins/fts-solr/Makefile src/plugins/fts-squat/Makefile src/plugins/last-login/Makefile src/plugins/lazy-expunge/Makefile src/plugins/listescape/Makefile src/plugins/mail-filter/Makefile src/plugins/mail-log/Makefile src/plugins/mailbox-alias/Makefile src/plugins/notify/Makefile src/plugins/push-notification/Makefile src/plugins/pop3-migration/Makefile src/plugins/quota/Makefile src/plugins/quota-clone/Makefile src/plugins/imap-quota/Makefile src/plugins/replication/Makefile src/plugins/snarf/Makefile src/plugins/stats/Makefile src/plugins/imap-stats/Makefile src/plugins/trash/Makefile src/plugins/virtual/Makefile src/plugins/zlib/Makefile src/plugins/imap-zlib/Makefile stamp.h dovecot-config.in" +ac_config_files="$ac_config_files Makefile doc/Makefile doc/man/Makefile doc/wiki/Makefile doc/example-config/Makefile doc/example-config/conf.d/Makefile src/Makefile src/lib/Makefile src/lib-sql/Makefile src/lib-auth/Makefile src/lib-charset/Makefile src/lib-compression/Makefile src/lib-dict/Makefile src/lib-dict-extra/Makefile src/lib-dns/Makefile src/lib-fs/Makefile src/lib-fts/Makefile src/lib-http/Makefile src/lib-imap/Makefile src/lib-imap-storage/Makefile src/lib-imap-client/Makefile src/lib-imap-urlauth/Makefile src/lib-index/Makefile src/lib-lda/Makefile src/lib-ldap/Makefile src/lib-mail/Makefile src/lib-master/Makefile src/lib-ntlm/Makefile src/lib-otp/Makefile src/lib-dovecot/Makefile src/lib-sasl/Makefile src/lib-settings/Makefile src/lib-ssl-iostream/Makefile src/lib-stats/Makefile src/lib-test/Makefile src/lib-storage/Makefile src/lib-storage/list/Makefile src/lib-storage/index/Makefile src/lib-storage/index/imapc/Makefile src/lib-storage/index/pop3c/Makefile src/lib-storage/index/maildir/Makefile src/lib-storage/index/mbox/Makefile src/lib-storage/index/dbox-common/Makefile src/lib-storage/index/dbox-multi/Makefile src/lib-storage/index/dbox-single/Makefile src/lib-storage/index/cydir/Makefile src/lib-storage/index/raw/Makefile src/lib-storage/index/shared/Makefile src/lib-storage/register/Makefile src/anvil/Makefile src/auth/Makefile src/config/Makefile src/doveadm/Makefile src/doveadm/dsync/Makefile src/lda/Makefile src/log/Makefile src/lmtp/Makefile src/dict/Makefile src/director/Makefile src/dns/Makefile src/indexer/Makefile src/ipc/Makefile src/imap/Makefile src/imap-hibernate/Makefile src/imap-login/Makefile src/imap-urlauth/Makefile src/login-common/Makefile src/master/Makefile src/pop3/Makefile src/pop3-login/Makefile src/replication/Makefile src/replication/aggregator/Makefile src/replication/replicator/Makefile src/ssl-params/Makefile src/stats/Makefile src/util/Makefile src/plugins/Makefile src/plugins/acl/Makefile src/plugins/imap-acl/Makefile src/plugins/autocreate/Makefile src/plugins/expire/Makefile src/plugins/fs-compress/Makefile src/plugins/fts/Makefile src/plugins/fts-lucene/Makefile src/plugins/fts-solr/Makefile src/plugins/fts-squat/Makefile src/plugins/last-login/Makefile src/plugins/lazy-expunge/Makefile src/plugins/listescape/Makefile src/plugins/mail-filter/Makefile src/plugins/mail-log/Makefile src/plugins/mailbox-alias/Makefile src/plugins/notify/Makefile src/plugins/push-notification/Makefile src/plugins/pop3-migration/Makefile src/plugins/quota/Makefile src/plugins/quota-clone/Makefile src/plugins/imap-quota/Makefile src/plugins/replication/Makefile src/plugins/snarf/Makefile src/plugins/stats/Makefile src/plugins/imap-stats/Makefile src/plugins/trash/Makefile src/plugins/virtual/Makefile src/plugins/zlib/Makefile src/plugins/imap-zlib/Makefile stamp.h dovecot-config.in" cat >confcache <<\_ACEOF @@ -26497,6 +26516,10 @@ as_fn_error $? "conditional \"LDAP_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_LDAP_TRUE}" && test -z "${HAVE_LDAP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_LDAP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${BUILD_PGSQL_TRUE}" && test -z "${BUILD_PGSQL_FALSE}"; then as_fn_error $? "conditional \"BUILD_PGSQL\" was never defined. @@ -26943,7 +26966,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Dovecot $as_me 2.2.22, which was +This file was extended by Dovecot $as_me 2.2.24, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -27009,7 +27032,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Dovecot config.status 2.2.22 +Dovecot config.status 2.2.24 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -27535,6 +27558,7 @@ "src/lib-charset/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-charset/Makefile" ;; "src/lib-compression/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-compression/Makefile" ;; "src/lib-dict/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-dict/Makefile" ;; + "src/lib-dict-extra/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-dict-extra/Makefile" ;; "src/lib-dns/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-dns/Makefile" ;; "src/lib-fs/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-fs/Makefile" ;; "src/lib-fts/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-fts/Makefile" ;; @@ -27545,6 +27569,7 @@ "src/lib-imap-urlauth/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-imap-urlauth/Makefile" ;; "src/lib-index/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-index/Makefile" ;; "src/lib-lda/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-lda/Makefile" ;; + "src/lib-ldap/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-ldap/Makefile" ;; "src/lib-mail/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-mail/Makefile" ;; "src/lib-master/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-master/Makefile" ;; "src/lib-ntlm/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib-ntlm/Makefile" ;; diff -Nru dovecot-2.2.22/configure.ac dovecot-2.2.24/configure.ac --- dovecot-2.2.22/configure.ac 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/configure.ac 2016-04-26 14:29:06.000000000 +0000 @@ -2,8 +2,8 @@ # Be sure to update ABI version also if anything changes that might require # recompiling plugins. Most importantly that means if any structs are changed. -AC_INIT([Dovecot],[2.2.22],[dovecot@dovecot.org]) -AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv22($PACKAGE_VERSION)", [Dovecot ABI version]) +AC_INIT([Dovecot],[2.2.24],[dovecot@dovecot.org]) +AC_DEFINE_UNQUOTED([DOVECOT_ABI_VERSION], "2.2.ABIv24($PACKAGE_VERSION)", [Dovecot ABI version]) AC_CONFIG_SRCDIR([src]) @@ -456,7 +456,7 @@ getmntinfo setpriority quotactl getmntent kqueue kevent \ backtrace_symbols walkcontext dirfd clearenv \ malloc_usable_size glob fallocate posix_fadvise \ - getpeereid getpeerucred inotify_init) + getpeereid getpeerucred inotify_init timegm) AC_CHECK_TYPES([struct sockpeercred],,,[ #include @@ -2044,7 +2044,7 @@ fi fi AM_CONDITIONAL(LDAP_PLUGIN, test "$have_ldap_plugin" = "yes") - +AM_CONDITIONAL(HAVE_LDAP, test "$want_ldap" = "yes") dict_drivers= if test $want_db != no; then @@ -2516,6 +2516,7 @@ dnl ** Shared libraries usage dnl ** +LIBDOVECOT_LA_LIBS='$(top_builddir)/src/lib-dict-extra/libdict_extra.la $(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-stats/libstats.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' if test "$want_shared_libs" = "yes"; then LIBDOVECOT_DEPS='$(top_builddir)/src/lib-dovecot/libdovecot.la' LIBDOVECOT="$LIBDOVECOT_DEPS \$(MODULE_LIBS)" @@ -2523,18 +2524,24 @@ LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else - LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-stats/libstats.la $(top_builddir)/src/lib-http/libhttp.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-sasl/libsasl.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la' + LIBDOVECOT_DEPS="$LIBDOVECOT_LA_LIBS" LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV) \$(MODULE_LIBS)" LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libstorage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la' fi +if test $want_ldap != no; then + LIBDOVECOT_LDAP='$(top_builddir)/src/lib-ldap/libdovecot-ldap.la' +else + LIBDOVECOT_LDAP='' +fi LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_DEPS" LIBDOVECOT_DSYNC='$(top_builddir)/src/doveadm/dsync/libdovecot-dsync.la' LIBDOVECOT_SQL='$(top_builddir)/src/lib-sql/libsql.la' LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la' LIBDOVECOT_LIBFTS='$(top_builddir)/src/lib-fts/libfts.la' AC_SUBST(LIBDOVECOT) +AC_SUBST(LIBDOVECOT_LA_LIBS) AC_SUBST(LIBDOVECOT_DEPS) AC_SUBST(LIBDOVECOT_STORAGE) AC_SUBST(LIBDOVECOT_STORAGE_DEPS) @@ -2543,6 +2550,7 @@ AC_SUBST(LIBDOVECOT_COMPRESS) AC_SUBST(LIBDOVECOT_DSYNC) AC_SUBST(LIBDOVECOT_LDA) +AC_SUBST(LIBDOVECOT_LDAP) AC_SUBST(LIBDOVECOT_LIBFTS) AC_SUBST(LIBDOVECOT_LIBFTS_DEPS) @@ -2853,6 +2861,7 @@ src/lib-charset/Makefile src/lib-compression/Makefile src/lib-dict/Makefile +src/lib-dict-extra/Makefile src/lib-dns/Makefile src/lib-fs/Makefile src/lib-fts/Makefile @@ -2863,6 +2872,7 @@ src/lib-imap-urlauth/Makefile src/lib-index/Makefile src/lib-lda/Makefile +src/lib-ldap/Makefile src/lib-mail/Makefile src/lib-master/Makefile src/lib-ntlm/Makefile diff -Nru dovecot-2.2.22/debian/changelog dovecot-2.2.24/debian/changelog --- dovecot-2.2.22/debian/changelog 2016-04-20 23:59:34.000000000 +0000 +++ dovecot-2.2.24/debian/changelog 2016-08-18 02:01:05.000000000 +0000 @@ -1,3 +1,60 @@ +dovecot (1:2.2.24-1ubuntu1) yakkety; urgency=medium + + * Merge with Debian; Remaining Changes: + + Add autopkgtest to debian/tests/*. + + Drop build dependency on libstemmer-dev (universe) + + Use Snakeoil SSL certificates by default + - d/control: Depend on ssl-cert + + add lsb base dependency to ensure debian/dovecot-core.dovecot.init is + working correctly + + Add ufw integration: + - d/dovecot-core.ufw.profile: new ufw profile. + - d/rules: install profile in dovecot-core. + - d/control: dovecot-core - suggest ufw. + + Add apport hook: + - d/rules, d/source_dovecot.py + + Remove lintian override for drac + + Add mail-stack-delivery + - add package in d/rules, d/control + - add d/*mail-stack-delivery* maintainer scripts and default conf + - d/mail-stack-delivery.preinst: Move previously installed backups and + config files to a new package namespace. + * Added Changes: + - Disable dovecot-lucene plugin as it had various issues, has universe + dependencies and is deprecated in favor of solr anyway (LP: #1524526). + - Fixup the autopkgtests we add to work with recent dovecot versions + - d/mail-stack-delivery.README.Debian clarified use of configuration files + - handle conffile removal of /etc/init/dovecot.conf (due to dropping + upstart). Can be removed once no upgrade path from Tue, 21 Jun 2016 16:31:29 +0200 + +dovecot (1:2.2.24-1) unstable; urgency=medium + + * [26020b6] Imported Upstream version 2.2.24 (Closes: #818652) + + -- Apollon Oikonomopoulos Mon, 09 May 2016 10:42:08 +0300 + +dovecot (1:2.2.23-1) unstable; urgency=medium + + [ Jaldhar H. Vyas ] + * Drop missing-expunges.patch, merged upstream + + [ Apollon Oikonomopoulos ] + * [8a01915] Imported Upstream version 2.2.23 + + -- Apollon Oikonomopoulos Tue, 12 Apr 2016 17:30:03 +0300 + dovecot (1:2.2.22-1ubuntu4) xenial; urgency=medium * Urgh. Previous upload added a runtime dependency on libstemmer0d to diff -Nru dovecot-2.2.22/debian/control dovecot-2.2.24/debian/control --- dovecot-2.2.22/debian/control 2016-04-21 00:00:20.000000000 +0000 +++ dovecot-2.2.24/debian/control 2016-08-18 02:01:05.000000000 +0000 @@ -24,7 +24,6 @@ libwrap0-dev, dh-systemd, lsb-release, - libclucene-dev (>= 2.3), liblzma-dev, liblz4-dev, libexttextcat-dev, @@ -38,11 +37,12 @@ Package: dovecot-core Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime (>= 0.76-13.1), openssl, adduser, ucf (>= 2.0020), ssl-cert, lsb-base -Recommends: ntpdate -Suggests: ntp, dovecot-gssapi, dovecot-sieve, dovecot-pgsql, dovecot-mysql, dovecot-sqlite, dovecot-ldap, dovecot-imapd, dovecot-pop3d, dovecot-lmtpd, dovecot-managesieved, dovecot-solr, dovecot-lucene, ufw +Suggests: ntp, dovecot-gssapi, dovecot-sieve, dovecot-pgsql, dovecot-mysql, dovecot-sqlite, dovecot-ldap, dovecot-imapd, dovecot-pop3d, dovecot-lmtpd, dovecot-managesieved, dovecot-solr, ufw Provides: dovecot-common, dovecot-abi-${dovecot:ABI-Version} -Replaces: dovecot-common (<< 1:2.0.14-2~), mailavenger (<< 0.8.1-4) -Breaks: dovecot-common (<< 1:2.0.14-2~), mailavenger (<< 0.8.1-4) +Replaces: dovecot-common (<< 1:2.0.14-2~), mailavenger (<< 0.8.1-4), + dovecot-lucene (<<1:2.2.24~) +Breaks: dovecot-common (<< 1:2.0.14-2~), mailavenger (<< 0.8.1-4), + dovecot-lucene (<<1:2.2.24~) Description: secure POP3/IMAP server - core files Dovecot is a mail server whose major goals are security and extreme reliability. It tries very hard to handle all error conditions and verify @@ -207,18 +207,6 @@ . This package provides Solr full text search support for Dovecot. -Package: dovecot-lucene -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, dovecot-core (= ${binary:Version}) -Description: secure POP3/IMAP server - Lucene support - Dovecot is a mail server whose major goals are security and extreme - reliability. It tries very hard to handle all error conditions and verify - that all data is valid, making it nearly impossible to crash. It supports - mbox/Maildir and its own dbox/mdbox formats, and should also be pretty - fast, extensible, and portable. - . - This package provides Lucene full text search support for Dovecot. - Package: dovecot-dbg Section: debug Priority: extra diff -Nru dovecot-2.2.22/debian/docs dovecot-2.2.24/debian/docs --- dovecot-2.2.22/debian/docs 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -NEWS -README -TODO diff -Nru dovecot-2.2.22/debian/dovecot-core.dovecot.upstart dovecot-2.2.24/debian/dovecot-core.dovecot.upstart --- dovecot-2.2.22/debian/dovecot-core.dovecot.upstart 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/dovecot-core.dovecot.upstart 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -# dovecot - pop3/imap mail server -# -# Dovecot is a mail server whose major goals are security and extreme reliability. - -description "dovecot - pop3/imap mail server" - -start on runlevel [2345] -stop on runlevel [!2345] - -respawn - -pre-start script - test -x /usr/sbin/dovecot || { stop ; exit 0; } - test -r /etc/dovecot/dovecot.conf || { stop ; exit 0; } - - # dont check for inetd.conf if its not installed - if [ -f /etc/inetd.conf ]; then - # The init script should do nothing if dovecot or another imap/pop3 server - # is being run from inetd, and dovecot is configured to run as an imap or - # pop3 service - for p in `sed -r "s/^ *(([^:]+|\[[^]]+]|\*):)?(pop3s?|imaps?)[ \t].*/\3/;t;d" \ - /etc/inetd.conf` - do - for q in `sed -r "s/^[ \t]*protocols[ \t]*=[ \t]*(([^\"]*)|\"(.*)\")/\2\3/;t;d" \ - /etc/dovecot/dovecot.conf` - do - if [ $p = $q ]; then - exit 0 - fi - done - done - fi - -end script - -script - test -x /usr/sbin/ntp-wait && ntp-wait -n 2 || true - exec /usr/sbin/dovecot -F -c /etc/dovecot/dovecot.conf -end script diff -Nru dovecot-2.2.22/debian/dovecot-core.maintscript dovecot-2.2.24/debian/dovecot-core.maintscript --- dovecot-2.2.22/debian/dovecot-core.maintscript 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/debian/dovecot-core.maintscript 2016-08-18 02:01:05.000000000 +0000 @@ -0,0 +1 @@ +rm_conffile /etc/init/dovecot.conf 1:2.2.22-1ubuntu4 diff -Nru dovecot-2.2.22/debian/mail-stack-delivery.postinst dovecot-2.2.24/debian/mail-stack-delivery.postinst --- dovecot-2.2.22/debian/mail-stack-delivery.postinst 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/mail-stack-delivery.postinst 2016-08-18 02:01:05.000000000 +0000 @@ -61,10 +61,6 @@ echo ' done.' fi fi - # Parameters that need to be changed on upgrades - if [ ! -z "$2" ] && dpkg --compare-versions $2 lt 1:2.1.7-7ubuntu1; then - set_postfix_option "mailbox_command = /usr/lib/dovecot/deliver -c /etc/dovecot/dovecot.conf -m \"\${EXTENSION}\"" - fi else echo "" echo "Postfix not configured. Run" diff -Nru dovecot-2.2.22/debian/mail-stack-delivery.preinst dovecot-2.2.24/debian/mail-stack-delivery.preinst --- dovecot-2.2.22/debian/mail-stack-delivery.preinst 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/mail-stack-delivery.preinst 2016-08-18 02:01:05.000000000 +0000 @@ -25,45 +25,25 @@ } case "$1" in install|upgrade) - if dpkg --compare-versions "$2" lt "1:1.2.9-1ubuntu8"; then - prep_mv_conffile mail-stack-delivery "/etc/dovecot/conf.d/01-dovecot-postfix.conf" - prep_mv_conffile mail-stack-delivery "/etc/dovecot/auth.d/01-dovecot-postfix.auth" - if [ -f "/usr/share/dovecot/dovecot-postfix.conf" ]; then - mv -f "/usr/share/dovecot/dovecot-postfix.conf" "/usr/share/dovecot/mail-stack-delivery.conf" - fi - if [ -f "/etc/dovecot/dovecot-postfix.conf" ]; then - mv -f "/etc/dovecot/dovecot-postfix.conf" "/etc/dovecot/mail-stack-delivery.conf" - fi - if [ -e "/var/backups/dovecot-postfix/main.cf-backup" ]; then - if [ -n "//var/backups/mail-stack-delivery/" ]; then - mkdir "/var/backups/mail-stack-delivery/" + # Check if mail-stack-delivery.conf had any customizations + if [ -f "/usr/share/dovecot/mail-stack-delivery.conf" ]; then + if [ -f "/etc/dovecot/mail-stack-delivery.conf" ]; then + mv /etc/dovecot/mail-stack-delivery.conf /etc/dovecot/mail-stack-delivery.conf.bak + DIR=`mktemp -d` + egrep -v ^protocol /etc/dovecot/mail-stack-delivery.conf.bak > $DIR/mail-stack-delivery-custom.conf + egrep -v ^protocol /usr/share/dovecot/mail-stack-delivery.conf > $DIR/mail-stack-delivery.conf + if diff -qur $DIR/mail-stack-delivery-dist.conf $DIR/mail-stack-delivery-custom.conf 1>/dev/null 2>&1; then + rm -f /etc/dovecot/mail-stack-delivery.conf.bak + else + awk ' /^auth default/ {flag=1;next} /^}/{flag=0} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak > /etc/dovecot/auth.d/01-mail-stack-delivery.auth + awk ' /^## Dovecot conf/{flag=1} /^auth default/{flag=0} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak > /etc/dovecot/conf.d/01-mail-stack-delivery.conf + awk ' /^# If you wish to use another authentication server than dovecot-auth/{flag=1} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak >> /etc/dovecot/conf.d/01-mail-stack-delivery.conf fi - mv -f "/var/backups/dovecot-postfix/main.cf-backup" "/var/backups/mail-stack-delivery/main.cf-backup" - test -d /var/backups/dovecot-postfix/ && rmdir --ignore-fail-on-non-empty /var/backups/dovecot-postfix/ - fi + rm -rf $DIR fi + fi + ;; - - # Check if mail-stack-delivery.conf had any customizations - if [ -f "/usr/share/dovecot/mail-stack-delivery.conf" ]; then - if [ -f "/etc/dovecot/mail-stack-delivery.conf" ]; then - mv /etc/dovecot/mail-stack-delivery.conf /etc/dovecot/mail-stack-delivery.conf.bak - DIR=`mktemp -d` - egrep -v ^protocol /etc/dovecot/mail-stack-delivery.conf.bak > $DIR/mail-stack-delivery-custom.conf - egrep -v ^protocol /usr/share/dovecot/mail-stack-delivery.conf > $DIR/mail-stack-delivery.conf - if diff -qur $DIR/mail-stack-delivery-dist.conf $DIR/mail-stack-delivery-custom.conf 1>/dev/null 2>&1; then - rm -f /etc/dovecot/mail-stack-delivery.conf.bak - else - awk ' /^auth default/ {flag=1;next} /^}/{flag=0} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak > /etc/dovecot/auth.d/01-mail-stack-delivery.auth - awk ' /^## Dovecot conf/{flag=1} /^auth default/{flag=0} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak > /etc/dovecot/conf.d/01-mail-stack-delivery.conf - awk ' /^# If you wish to use another authentication server than dovecot-auth/{flag=1} flag { print }' /etc/dovecot/mail-stack-delivery.conf.bak >> /etc/dovecot/conf.d/01-mail-stack-delivery.conf - fi - rm -rf $DIR - fi - - fi - ;; - abort-upgrade) ;; diff -Nru dovecot-2.2.22/debian/mail-stack-delivery.prerm dovecot-2.2.24/debian/mail-stack-delivery.prerm --- dovecot-2.2.22/debian/mail-stack-delivery.prerm 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/mail-stack-delivery.prerm 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -#! /bin/sh - -set -e - -# conffile renamed in 1:1.2.9-1ubuntu8 -if dpkg --compare-versions "$2" lt-nl "1:1.2.9-1ubuntu8"; then - # "$1" is equal to "upgrade" (which means downgrading in this case) or "abort-upgrade" - # downgrading to <1:1.2.9-1ubuntu8 -- restore old conffile name - if [ -f "/etc/dovecot/conf.d/01-mail-stack-delivery.conf" ]; then - mv -f "/etc/dovecot/conf.d/01-mail-stack-delivery.conf" "/etc/dovecot/conf.d/01-dovecot-postfix.conf" - fi - if [ -f "/etc/dovecot/conf.d/01-mail-stack-delivery.auth" ]; then - mv -f "/etc/dovecot/conf.d/01-mail-stack-delivery.auth" "/etc/dovecot/conf.d/01-dovecot-postfix.auth" - fi - if [ -f "/usr/share/dovecot/mail-stack-delivery.conf" ]; then - mv -f "/usr/share/dovecot/mail-stack-delivery.conf" "/usr/share/dovecot/dovecot-postfix.conf" - fi - if [ -f "/etc/dovecot/mail-stack-delivery.conf" ]; then - mv -f "/etc/dovecot/mail-stack-delivery.conf" "/etc/dovecot/dovecot-postfix.conf" - fi - if [ -e "/var/backups/mail-stack-delivery/main.cf-backup" ]; then - if [ -n "//var/backups/dovecot-postfix/" ]; then - mkdir "/var/backups/dovecot-postfix/" - fi - mv -f "/var/backups/mail-stack-delivery/main.cf-backup" "/var/backups/dovecot-postfix/main.cf-backup" - test -d /var/backups/mail-stack-delivery/ && rmdir /var/backups/mail-stack-delivery/ - fi -fi - -#DEBHELPER# - -exit 0 diff -Nru dovecot-2.2.22/debian/mail-stack-delivery.README.Debian dovecot-2.2.24/debian/mail-stack-delivery.README.Debian --- dovecot-2.2.22/debian/mail-stack-delivery.README.Debian 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/mail-stack-delivery.README.Debian 2016-08-18 02:01:05.000000000 +0000 @@ -5,9 +5,8 @@ contains only configuration file /etc/dovecot/mail-stack-delivery.conf with configuration prerpared by Ubuntu Server Team. -dovecot's init script checks existance of -/etc/dovecot/mail-stack-delivery.conf and if that file exists, it reads it -instead of /etc/dovecot/dovecot.conf. +The matching configuration for dovecot is placed in: + /etc/dovecot/conf.d/99-mail-stack-delivery.conf During installation of package, it modifies postfix's configuration and stores original version of /etc/postfix/main.cf in /var/backup/mail-stack-delivery. diff -Nru dovecot-2.2.22/debian/rules dovecot-2.2.24/debian/rules --- dovecot-2.2.22/debian/rules 2016-03-21 19:29:50.000000000 +0000 +++ dovecot-2.2.24/debian/rules 2016-08-18 02:01:05.000000000 +0000 @@ -57,8 +57,6 @@ solr_files = usr/lib/dovecot/modules/lib??_fts_solr_* -lucene_files = usr/lib/dovecot/modules/lib??_fts_lucene_* - dev_files = usr/include/* \ usr/lib/dovecot/dovecot-config @@ -77,7 +75,7 @@ --with-solr \ --with-ioloop=best \ --with-libwrap \ - --with-lucene \ + --without-lucene \ --with-lz4 \ --prefix=/usr \ --sysconfdir=/etc \ diff -Nru dovecot-2.2.22/debian/tests/control dovecot-2.2.24/debian/tests/control --- dovecot-2.2.22/debian/tests/control 2016-03-21 19:32:54.000000000 +0000 +++ dovecot-2.2.24/debian/tests/control 2016-08-18 02:01:05.000000000 +0000 @@ -9,4 +9,4 @@ Tests: general Restrictions: needs-root Features: no-build-needed -Depends: python, dovecot-imapd, dovecot-pop3d +Depends: python, dovecot-imapd, dovecot-pop3d, dovecot-managesieved, mail-stack-delivery diff -Nru dovecot-2.2.22/debian/tests/general dovecot-2.2.24/debian/tests/general --- dovecot-2.2.22/debian/tests/general 2016-03-21 19:30:29.000000000 +0000 +++ dovecot-2.2.24/debian/tests/general 2016-08-18 02:01:05.000000000 +0000 @@ -19,27 +19,34 @@ self.user = testlib.TestUser() config = ''' -protocols = imap imaps pop3 pop3s +protocols = imap pop3 log_timestamp = "%Y-%m-%d %H:%M:%S " -mail_extra_groups = mail +mail_privileged_group = mail +managesieve_notify_capability = mailto +managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext ''' if config_mmap_disable: config += ''' mmap_disable = yes ''' config += ''' -protocol imap { +ssl = yes +ssl_cert = 0: - # Old dovecot config=''' -protocols = imap imaps pop3 pop3s -login = imap -login = pop3 -mail_extra_groups = mail - -auth = auth-cram -auth_mechanisms = cram-md5 -auth_passdb = passwd-file /etc/dovecot/test.passwd -auth_user = root - -auth = auth-plain -auth_mechanisms = plain -auth_passdb = pam -auth_user = root - -''' - self.old_version = True - else: - # Modern dovecot - config=''' -protocols = imap imaps pop3 pop3s +protocols = imap pop3 log_timestamp = "%Y-%m-%d %H:%M:%S " -mail_extra_groups = mail -protocol imap { +mail_privileged_group = mail +managesieve_notify_capability = mailto +managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext +mmap_disable = yes +ssl = yes +ssl_cert = -[UserDatabase.ExtraFields.txt] with templates. For example: +[UserDatabase.ExtraFields.txt] with templates, but in v2.1+ it's done in a +better way by using override_fields. For example: ---%<------------------------------------------------------------------------- userdb { driver = passwd - args = home=/var/mail/%u mail=maildir:/var/mail/%u/Maildir + # Pre-v2.1: + #args = home=/var/mail/%u mail=maildir:/var/mail/%u/Maildir + # v2.1+: + override_fields = home=/var/mail/%u mail=maildir:/var/mail/%u/Maildir } ---%<------------------------------------------------------------------------- This uses the UID and GID fields from passwd, but home directory is overridden. Also the default [MailLocation.txt] setting is overridden. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/AuthDatabase.SQL.txt dovecot-2.2.24/doc/wiki/AuthDatabase.SQL.txt --- dovecot-2.2.22/doc/wiki/AuthDatabase.SQL.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/AuthDatabase.SQL.txt 2016-04-26 04:43:05.000000000 +0000 @@ -223,4 +223,4 @@ MD5-CRYPT. Also, the example above requires a 'dovecot' user in PostgreSQL with read (SELECT) privileges on the 'horde_users' table. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/AuthDatabase.txt dovecot-2.2.24/doc/wiki/AuthDatabase.txt --- dovecot-2.2.22/doc/wiki/AuthDatabase.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/AuthDatabase.txt 2016-04-26 04:43:04.000000000 +0000 @@ -15,4 +15,4 @@ * [AuthDatabase.VPopMail.txt]: External software used to handle virtual domains -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/AuthDatabase.VPopMail.txt dovecot-2.2.24/doc/wiki/AuthDatabase.VPopMail.txt --- dovecot-2.2.22/doc/wiki/AuthDatabase.VPopMail.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/AuthDatabase.VPopMail.txt 2016-04-26 04:43:05.000000000 +0000 @@ -164,4 +164,4 @@ account dovecot can still log this user on because the result of the password query has been stored in cache and used. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Caching.txt dovecot-2.2.24/doc/wiki/Authentication.Caching.txt --- dovecot-2.2.22/doc/wiki/Authentication.Caching.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Caching.txt 2016-04-26 04:43:05.000000000 +0000 @@ -99,4 +99,4 @@ previous authentication was unsuccessful, so Dovecot doesn't bother doing another backend passdb lookup (until cache TTL expires). The login fails. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Kerberos.txt dovecot-2.2.24/doc/wiki/Authentication.Kerberos.txt --- dovecot-2.2.22/doc/wiki/Authentication.Kerberos.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Kerberos.txt 2016-04-26 04:43:05.000000000 +0000 @@ -97,7 +97,12 @@ * v2.2+ has "k5principals" [PasswordDatabase.ExtraFields.txt], which is a comma separated list of usernames that are allowed to log in. If it's set, it bypasses the - krb5_kuserok() check. + krb5_kuserok() check.*NOTE*: for this to work, you need a password database + which supports *credential lookups*. This excludes LDAP databases using + "auth_bind = yes". However, if LDAP BIND authentication is needed, you can + add a second LDAP passdb entry without "auth_bind = yes" for the sole + purpose of Kerberos principals mapping. This passdb doesn't need to return a + password attribute (and usually should'nt). * Solaris uses _gss_userok() instead of krb5_kuserok() Client support @@ -170,4 +175,4 @@ * run command klist (list all kerberos keys) should show imap/HOSTNAME * /etc/hosts has to be set properly so that kerberos can find server. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.MasterUsers.txt dovecot-2.2.24/doc/wiki/Authentication.MasterUsers.txt --- dovecot-2.2.22/doc/wiki/Authentication.MasterUsers.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.MasterUsers.txt 2016-04-26 04:43:05.000000000 +0000 @@ -307,4 +307,4 @@ group by uid ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.DigestMD5.txt dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.DigestMD5.txt --- dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.DigestMD5.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.DigestMD5.txt 2016-04-26 04:43:05.000000000 +0000 @@ -77,4 +77,4 @@ imtest -a user@example.com ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.NTLM.txt dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.NTLM.txt --- dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.NTLM.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.NTLM.txt 2016-04-26 04:43:05.000000000 +0000 @@ -31,4 +31,4 @@ For more information about NTLM internals, see http://ubiqx.org/cifs/ and http://davenport.sourceforge.net/ntlm.html -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.txt dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.txt --- dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.txt 2016-04-26 04:43:05.000000000 +0000 @@ -74,4 +74,4 @@ auth_mechanisms = plain login cram-md5 ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.Winbind.txt dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.Winbind.txt --- dovecot-2.2.22/doc/wiki/Authentication.Mechanisms.Winbind.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Mechanisms.Winbind.txt 2016-04-26 04:43:05.000000000 +0000 @@ -32,4 +32,4 @@ responding (e.g. network problems), Dovecot blocks all other authentication requests until it's finished. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.MultipleDatabases.txt dovecot-2.2.24/doc/wiki/Authentication.MultipleDatabases.txt --- dovecot-2.2.22/doc/wiki/Authentication.MultipleDatabases.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.MultipleDatabases.txt 2016-04-26 04:43:05.000000000 +0000 @@ -109,4 +109,4 @@ userid = '%u' ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.PasswordSchemes.txt dovecot-2.2.24/doc/wiki/Authentication.PasswordSchemes.txt --- dovecot-2.2.22/doc/wiki/Authentication.PasswordSchemes.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.PasswordSchemes.txt 2016-04-26 04:43:05.000000000 +0000 @@ -201,4 +201,4 @@ not all password schemes provided by dovecotpw are supported. Have a look at the module VBoxAdm::DovecotPW for more details. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.Penalty.txt dovecot-2.2.24/doc/wiki/Authentication.Penalty.txt --- dovecot-2.2.22/doc/wiki/Authentication.Penalty.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.Penalty.txt 2016-04-26 04:43:05.000000000 +0000 @@ -42,4 +42,4 @@ Also you can have similar functionality with fail2ban [http://wiki2.dovecot.org/HowTo/Fail2Ban]. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.RestrictAccess.txt dovecot-2.2.24/doc/wiki/Authentication.RestrictAccess.txt --- dovecot-2.2.22/doc/wiki/Authentication.RestrictAccess.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.RestrictAccess.txt 2016-04-26 04:43:05.000000000 +0000 @@ -82,4 +82,4 @@ returning [PasswordDatabase.ExtraFields.AllowNets.txt] extra field in passdb. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Authentication.txt dovecot-2.2.24/doc/wiki/Authentication.txt --- dovecot-2.2.22/doc/wiki/Authentication.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Authentication.txt 2016-04-26 04:43:05.000000000 +0000 @@ -33,4 +33,4 @@ * Non-plaintext authentication mechanisms require either PLAIN password scheme or a mechanism-specific password scheme. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/BasicConfiguration.txt dovecot-2.2.24/doc/wiki/BasicConfiguration.txt --- dovecot-2.2.22/doc/wiki/BasicConfiguration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/BasicConfiguration.txt 2016-04-26 04:43:05.000000000 +0000 @@ -140,4 +140,4 @@ Note: Specifying the privileged user must be done as shown. Simply adding 'dovecot' user to the 'mail' group does /*not*/ grant write permission. -(This file was created from the wiki on 2016-03-16 04:43) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Chrooting.txt dovecot-2.2.24/doc/wiki/Chrooting.txt --- dovecot-2.2.22/doc/wiki/Chrooting.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Chrooting.txt 2016-04-26 04:43:12.000000000 +0000 @@ -62,4 +62,4 @@ to chroot into '/home', or 'home=/home/user/./' to chroot into '/home/user'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Clients.NegativeUIDs.txt dovecot-2.2.24/doc/wiki/Clients.NegativeUIDs.txt --- dovecot-2.2.22/doc/wiki/Clients.NegativeUIDs.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Clients.NegativeUIDs.txt 2016-04-26 04:43:13.000000000 +0000 @@ -50,4 +50,4 @@ to cause it somehow (by receiving 2 billion mails?), you can recreate the UIDs by deleting 'dovecot-uidlist' file. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Clients.txt dovecot-2.2.24/doc/wiki/Clients.txt --- dovecot-2.2.22/doc/wiki/Clients.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Clients.txt 2016-04-26 04:43:13.000000000 +0000 @@ -169,4 +169,4 @@ [http://atmail.com/]. Can also read mailbox quota via the getquotaroot IMAP command. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/CompilingSource.txt dovecot-2.2.24/doc/wiki/CompilingSource.txt --- dovecot-2.2.22/doc/wiki/CompilingSource.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/CompilingSource.txt 2016-04-26 04:43:13.000000000 +0000 @@ -364,4 +364,4 @@ which the plugins are loaded. This is important if one plugin depends on another. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/ConfigFile.txt dovecot-2.2.24/doc/wiki/ConfigFile.txt --- dovecot-2.2.22/doc/wiki/ConfigFile.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/ConfigFile.txt 2016-04-26 04:43:13.000000000 +0000 @@ -235,6 +235,7 @@ All the whitespace between lines is converted to a single space regardless of how many spaces or tabs are at the beginning of the line or before the '\'. +Even if there is zero whitespace a single space is added. Reading value from file ----------------------- @@ -294,6 +295,11 @@ # protocol imap { # mail_plugins = " acl imap_acl imap_quota" - NOT OK # } +# v2.2.24+ also gives a warning about this: +# doveconf: Warning: /etc/dovecot/dovecot.conf line 8: Global setting +mail_plugins won't change the setting inside an earlier filter at +/etc/dovecot/dovecot.conf line 5 (if this is intentional, avoid this warning by +moving the global setting before /etc/dovecot/dovecot.conf line 5) ---%<------------------------------------------------------------------------- This is because the second mail_plugins change that added "quota" globally @@ -303,4 +309,4 @@ Those variables *cannot* be referred to, that is '$sieve_extensions' won't work. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Debugging.Authentication.txt dovecot-2.2.24/doc/wiki/Debugging.Authentication.txt --- dovecot-2.2.22/doc/wiki/Debugging.Authentication.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Debugging.Authentication.txt 2016-04-26 04:43:13.000000000 +0000 @@ -78,4 +78,4 @@ to check that you have encoded correctly. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Debugging.ProcessTracing.txt dovecot-2.2.24/doc/wiki/Debugging.ProcessTracing.txt --- dovecot-2.2.22/doc/wiki/Debugging.ProcessTracing.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Debugging.ProcessTracing.txt 2016-04-26 04:43:13.000000000 +0000 @@ -41,4 +41,4 @@ '-r0' and '-w1' cause all IMAP input/output to be logged. '-d' adds timestamps to the log. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Debugging.Rawlog.txt dovecot-2.2.24/doc/wiki/Debugging.Rawlog.txt --- dovecot-2.2.22/doc/wiki/Debugging.Rawlog.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Debugging.Rawlog.txt 2016-04-26 04:43:13.000000000 +0000 @@ -89,4 +89,4 @@ chmod 0700 /var/run/dovecot/login/rawlogs ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Debugging.Thunderbird.txt dovecot-2.2.24/doc/wiki/Debugging.Thunderbird.txt --- dovecot-2.2.22/doc/wiki/Debugging.Thunderbird.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Debugging.Thunderbird.txt 2016-04-26 04:43:13.000000000 +0000 @@ -55,4 +55,4 @@ above will create a date/time stamped logfile for each run, so you won't lose the previous logs. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Arrays.txt dovecot-2.2.24/doc/wiki/Design.Arrays.txt --- dovecot-2.2.22/doc/wiki/Design.Arrays.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Arrays.txt 2016-04-26 04:43:13.000000000 +0000 @@ -106,4 +106,4 @@ * 'array_bsearch(array, key, cmp_func)' is a wrapper for 'bsearch()' also adding type safety, just like 'array_sort()'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.AuthProcess.txt dovecot-2.2.24/doc/wiki/Design.AuthProcess.txt --- dovecot-2.2.22/doc/wiki/Design.AuthProcess.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.AuthProcess.txt 2016-04-26 04:43:13.000000000 +0000 @@ -362,4 +362,4 @@ callback(USERDB_RESULT_OK, reply, auth_request); ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.AuthProtocol.txt dovecot-2.2.24/doc/wiki/Design.AuthProtocol.txt --- dovecot-2.2.22/doc/wiki/Design.AuthProtocol.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.AuthProtocol.txt 2016-04-26 04:43:13.000000000 +0000 @@ -242,4 +242,4 @@ System user name which can be used to get extra groups. This will probably be replaced later by giving just multiple gid fields. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Buffers.txt dovecot-2.2.24/doc/wiki/Design.Buffers.txt --- dovecot-2.2.22/doc/wiki/Design.Buffers.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Buffers.txt 2016-04-26 04:43:13.000000000 +0000 @@ -27,6 +27,10 @@ buffer_create_data(&buf, buf_data, sizeof(buf_data)); ---%<------------------------------------------------------------------------- +Trying to write more than 1024 bytes to the buffer will cause an assert-crash, +so these buffers shouldn't be used unless you know exactly what the maximum +buffer size is. + To avoid accidental buffer overflows, don't use any more complex calculations in the size parameter of 'buffer_create_data()'. It should always be 'sizeof(data_buffer)'. @@ -40,7 +44,9 @@ Dynamically growing buffers can be created with 'buffer_create_dynamic(pool, init_size)'. Memory for buffer is allocated from the given pool. When memory needs to be grown, it's grown exponentially (2^n), with some exceptions to -avoid growing the given memory pool unless necessary. +avoid growing the given memory pool unless necessary. The initial buffer size +is always a guess - try to make it large enough that buffer wouldn't be grown +most of the time, but not so large that it wastes memory. You should be careful with memory returned by 'buffer_get_space_unsafe()' and 'buffer_append_space_unsafe()'. This returned memory should be accessed @@ -56,4 +62,4 @@ can use 'buffer_set_used_size()' to grow it back to its original size (but no larger). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Code.txt dovecot-2.2.24/doc/wiki/Design.Code.txt --- dovecot-2.2.22/doc/wiki/Design.Code.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Code.txt 2016-04-26 04:43:13.000000000 +0000 @@ -189,4 +189,4 @@ In v2.2+ see 'CALLBACK_TYPECHECK()' macro and for example 'io_add()' for example usage. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.DoveadmProtocol.HTTP.txt dovecot-2.2.24/doc/wiki/Design.DoveadmProtocol.HTTP.txt --- dovecot-2.2.22/doc/wiki/Design.DoveadmProtocol.HTTP.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.DoveadmProtocol.HTTP.txt 2016-04-26 04:43:14.000000000 +0000 @@ -48,6 +48,43 @@ ] ---%<------------------------------------------------------------------------- +In following examples, you can either use Basic or X-Dovecot-API authorization. +X-Dovecot-API usage: + +---%<------------------------------------------------------------------------- +curl -H "Authorization: X-Dovecot-API " +---%<------------------------------------------------------------------------- + +Basic authorization uses "doveadm" as the username, and doveadm_password +setting as the password: + +---%<------------------------------------------------------------------------- +curl -H "Authorization: Basic " +---%<------------------------------------------------------------------------- + +To get acceptable routes + +---%<------------------------------------------------------------------------- +curl -H "Authorization: Basic " +http://server:8080/ +---%<------------------------------------------------------------------------- + +To get acceptable commands and their parameters + +---%<------------------------------------------------------------------------- +curl -H "Authorization: Basic " +http://server:8080/doveadm/v1 +---%<------------------------------------------------------------------------- + +an example command would be + +---%<------------------------------------------------------------------------- +curl -H "Content-Type: application/json" -H "Authorization: Basic " -d +'[["fetch",{"user":"username","field":["uid"],"query":["mailbox","INBOX"]},"c01"]]' +http://server:8080/doveadm/v1 +---%<------------------------------------------------------------------------- + You can have multiple commands in the array, but for now it is safest *not* to do so, as some commands may kill the server in certain error conditions and leaving you without any response. @@ -65,4 +102,4 @@ strings on requests. In case of fatal errors, the access.log string might be missing. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.DoveadmProtocol.txt dovecot-2.2.24/doc/wiki/Design.DoveadmProtocol.txt --- dovecot-2.2.22/doc/wiki/Design.DoveadmProtocol.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.DoveadmProtocol.txt 2016-04-26 04:43:14.000000000 +0000 @@ -86,4 +86,4 @@ fa8cb722dfad9c52b62600007049b30b125159fa8cb722dfad9c52b62600007049b30b125160 ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Dsync.txt dovecot-2.2.24/doc/wiki/Design.Dsync.txt --- dovecot-2.2.22/doc/wiki/Design.Dsync.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Dsync.txt 2016-04-26 04:43:14.000000000 +0000 @@ -111,4 +111,4 @@ to work in fast sync mode, the full mailbox list would have to be looked up from local side. And this would slow it down.. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Indexes.Cache.txt dovecot-2.2.24/doc/wiki/Design.Indexes.Cache.txt --- dovecot-2.2.22/doc/wiki/Design.Indexes.Cache.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Indexes.Cache.txt 2016-04-26 04:43:14.000000000 +0000 @@ -134,4 +134,4 @@ picked two months because people go to at least one month vacations where they might still be reading mails, but with different clients. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Indexes.MailIndexApi.txt dovecot-2.2.24/doc/wiki/Design.Indexes.MailIndexApi.txt --- dovecot-2.2.22/doc/wiki/Design.Indexes.MailIndexApi.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Indexes.MailIndexApi.txt 2016-04-26 04:43:14.000000000 +0000 @@ -44,4 +44,4 @@ non-map versions return the data from the latest map if the message hasn't been expunged. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Indexes.MainIndex.txt dovecot-2.2.24/doc/wiki/Design.Indexes.MainIndex.txt --- dovecot-2.2.22/doc/wiki/Design.Indexes.MainIndex.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Indexes.MainIndex.txt 2016-04-26 04:43:14.000000000 +0000 @@ -242,4 +242,4 @@ The records size is always divisible by the maximum alignment requirement. This isn't strictly necessary either, so it could be fixed later as well. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Indexes.TransactionLog.txt dovecot-2.2.24/doc/wiki/Design.Indexes.TransactionLog.txt --- dovecot-2.2.22/doc/wiki/Design.Indexes.TransactionLog.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Indexes.TransactionLog.txt 2016-04-26 04:43:14.000000000 +0000 @@ -262,4 +262,4 @@ }; ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Indexes.txt dovecot-2.2.24/doc/wiki/Design.Indexes.txt --- dovecot-2.2.22/doc/wiki/Design.Indexes.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Indexes.txt 2016-04-26 04:43:14.000000000 +0000 @@ -67,4 +67,4 @@ and lockless integers. The "unset" value is returned as 0, so it's not possible to differentiate between "unset" and "set" 0 values. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.InputStreams.txt dovecot-2.2.24/doc/wiki/Design.InputStreams.txt --- dovecot-2.2.22/doc/wiki/Design.InputStreams.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.InputStreams.txt 2016-04-26 04:43:14.000000000 +0000 @@ -129,4 +129,4 @@ less (or more), and calling the function again may or may not return a larger size. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.MailProcess.txt dovecot-2.2.24/doc/wiki/Design.MailProcess.txt --- dovecot-2.2.22/doc/wiki/Design.MailProcess.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.MailProcess.txt 2016-04-26 04:43:14.000000000 +0000 @@ -9,4 +9,4 @@ * Plugins * etc. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Memory.txt dovecot-2.2.24/doc/wiki/Design.Memory.txt --- dovecot-2.2.22/doc/wiki/Design.Memory.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Memory.txt 2016-04-26 04:43:14.000000000 +0000 @@ -190,4 +190,4 @@ location and accessed after it's already been freed. * Debugging invalid memory usage may be difficult using existing tools -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.OutputStreams.txt dovecot-2.2.24/doc/wiki/Design.OutputStreams.txt --- dovecot-2.2.22/doc/wiki/Design.OutputStreams.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.OutputStreams.txt 2016-04-26 04:43:14.000000000 +0000 @@ -29,4 +29,4 @@ write check if the buffer size becomes too large, and when it does it stops writing until more space is available. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Plugins.txt dovecot-2.2.24/doc/wiki/Design.Plugins.txt --- dovecot-2.2.22/doc/wiki/Design.Plugins.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Plugins.txt 2016-04-26 04:43:14.000000000 +0000 @@ -59,4 +59,4 @@ Error: Can't load plugin imap_quota_plugin: Plugin quota must be loaded also ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Processes.txt dovecot-2.2.24/doc/wiki/Design.Processes.txt --- dovecot-2.2.22/doc/wiki/Design.Processes.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Processes.txt 2016-04-26 04:43:14.000000000 +0000 @@ -134,4 +134,4 @@ See [Design.MailProcess.txt] for their internal design documentation. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.ErrorHandling.txt dovecot-2.2.24/doc/wiki/Design.Storage.ErrorHandling.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.ErrorHandling.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.ErrorHandling.txt 2016-04-26 04:43:14.000000000 +0000 @@ -60,4 +60,4 @@ * ENOENT, ENOTDIR: Not found * ELOOP: Directory structure is broken -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.MailboxList.txt dovecot-2.2.24/doc/wiki/Design.Storage.MailboxList.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.MailboxList.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.MailboxList.txt 2016-04-26 04:43:15.000000000 +0000 @@ -156,4 +156,4 @@ If changing the group fails with EPERM, 'eperm_error_get_chgrp()' can be used to log a nice and understandable error message. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Save.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Save.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Save.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Save.txt 2016-04-26 04:43:14.000000000 +0000 @@ -48,4 +48,4 @@ * 'mailbox_save_finish()' finishes saving the mail, or 'mailbox_save_cancel()' aborts it. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Search.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Search.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Search.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Search.txt 2016-04-26 04:43:14.000000000 +0000 @@ -98,4 +98,4 @@ 'mailbox_search_result_sync()', i.e. with this you can implement "what changed in search results since last time I checked". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Sync.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Sync.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Sync.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Sync.txt 2016-04-26 04:43:15.000000000 +0000 @@ -125,4 +125,4 @@ FIXME: talk about mail_index_sync_*() and how to change stuff and how to update internal state. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Transaction.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Transaction.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.Transaction.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.Transaction.txt 2016-04-26 04:43:15.000000000 +0000 @@ -49,4 +49,4 @@ max_modseq while transaction is being committed, the change isn't done and the message's sequence number is added to the given array. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mailbox.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mailbox.txt 2016-04-26 04:43:14.000000000 +0000 @@ -31,4 +31,4 @@ * [Design.Storage.Mailbox.Save.txt]: 'mailbox_save_*()' and 'mailbox_copy()' is used for saving/copying new messages to mailbox. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.MailNamespace.txt dovecot-2.2.24/doc/wiki/Design.Storage.MailNamespace.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.MailNamespace.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.MailNamespace.txt 2016-04-26 04:43:14.000000000 +0000 @@ -88,4 +88,4 @@ returns the storage that should be used. For other purposes you should find the storage via [Design.Storage.MailboxList.txt] functions. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.MailStorage.txt dovecot-2.2.24/doc/wiki/Design.Storage.MailStorage.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.MailStorage.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.MailStorage.txt 2016-04-26 04:43:14.000000000 +0000 @@ -38,4 +38,4 @@ * 'mailbox_alloc()': Allocate memory for [Design.Storage.Mailbox.txt]. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Mail.txt dovecot-2.2.24/doc/wiki/Design.Storage.Mail.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Mail.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Mail.txt 2016-04-26 04:43:14.000000000 +0000 @@ -97,4 +97,4 @@ body. If you wish to modify any of them, you need to create a new message and expunge the old one. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.MailUser.txt dovecot-2.2.24/doc/wiki/Design.Storage.MailUser.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.MailUser.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.MailUser.txt 2016-04-26 04:43:14.000000000 +0000 @@ -22,4 +22,4 @@ to list/access the user's mailboxes. Again there is no attempt to share the created mail user with other connections. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Storage.Plugins.txt dovecot-2.2.24/doc/wiki/Design.Storage.Plugins.txt --- dovecot-2.2.22/doc/wiki/Design.Storage.Plugins.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Storage.Plugins.txt 2016-04-26 04:43:15.000000000 +0000 @@ -121,4 +121,4 @@ (Yes, this API seems a bit too difficult to use and could use a redesign.) -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.Strings.txt dovecot-2.2.24/doc/wiki/Design.Strings.txt --- dovecot-2.2.22/doc/wiki/Design.Strings.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.Strings.txt 2016-04-26 04:43:15.000000000 +0000 @@ -5,7 +5,9 @@ actually only a simple wrapper on top of [Design.Buffers.txt]. Even the 'string_t' type is only a typedef of 'buffer_t', so it's possible to use 'buffer_*()' functions with strings (although it's ugly so it should be -avoided). +avoided). The decision of whether to use a string_t or a buffer_t is mainly for +human readability: if the buffer's contents are (ASCII/UTF8) text use string_t, +otherwise for binary data use buffer_t. Once you're done modifying a string with 'str_*()' functions, you can get it out as a NUL-terminated string with 'str_c()' or 'str_c_modifiable()'. These @@ -65,4 +67,4 @@ Dovecot's internal protocols are often line-based with TAB as the field separator. This file also contains functions to escape and unescape such data. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Design.txt dovecot-2.2.24/doc/wiki/Design.txt --- dovecot-2.2.22/doc/wiki/Design.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Design.txt 2016-04-26 04:43:13.000000000 +0000 @@ -51,4 +51,4 @@ * [Design.Storage.Plugins.txt] - how to hook into lib-storage functions. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Dictionary.txt dovecot-2.2.24/doc/wiki/Dictionary.txt --- dovecot-2.2.22/doc/wiki/Dictionary.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Dictionary.txt 2016-04-26 04:43:15.000000000 +0000 @@ -17,6 +17,7 @@ * Redis * Proxy * SQL + * LDAP Flat Files ---------- @@ -128,8 +129,8 @@ : ---%<------------------------------------------------------------------------- -The contains the SQL driver name, such as "mysql", "pgsql" or -"sqlite". +The contains the SQL driver name, such as "mysql", "pgsql", +"sqlite" or "cassandra". The dict-sql config file consists of SQL server configuration and mapping of keys to SQL tables/fields. @@ -148,6 +149,119 @@ SQL Mapping ----------- -FIXME: Write this. For now see 'example-config/dovecot-dict-sql.conf.ext' +SQL mapping is done with a dict key pattern and fields. When a dict lookup or +update is done, Dovecot goes through all the maps and uses the first one whose +pattern matches the dict key. + +For example when using dict for a per-user quota value the map looks like: + +---%<------------------------------------------------------------------------- +map { + pattern = priv/quota/storage + table = quota + username_field = username + value_field = quota_bytes +} +---%<------------------------------------------------------------------------- + +This means that: + + * The dict key must match exactly "priv/quota/storage". The dict keys are + hardcoded in the Dovecot code, so depending on what functionality you're + configuring you need to know the available dict keys used it. + * This is a private dict key ("priv/" prefix), which means that there must be + a username_field. The username_field is assumed to be (at least part of) the + primary key. In this example we don't have any other primary keys. + * With MySQL the above map translates to SQL queries: + * 'SELECT quota_bytes FROM quota WHERE username = '$username_field'' + * 'INSERT INTO quota (username, quota_bytes) VALUES ('$username_field', + '$value') ON DUPLICATE KEY UPDATE quota_bytes='$value'' + +You can also access multiple SQL fields. For example acl_shared_dict can +contain: + +---%<------------------------------------------------------------------------- +map { + pattern = shared/shared-boxes/user/$to/$from + table = user_shares + value_field = dummy + + fields { + from_user = $from + to_user = $to + } +} +---%<------------------------------------------------------------------------- + + * The acl_shared_dict always uses "1" as the value, so here the value_field is + called "dummy". + * The SQL from_user and to_user fields are the interesting ones. Typically the + extra fields would be part of the primary key. + * With MySQL the above map translates to SQL queries: + * 'SELECT dummy FROM user_shares WHERE from_user = '$from' AND to_user = + '$to'' + * 'INSERT INTO user_shares (from_user, to_user, dummy) VALUES ('$from', + '$to', '$value') ON DUPLICATE KEY UPDATE dummy='$value'' -(This file was created from the wiki on 2016-03-16 04:44) +LDAP (v2.3+) +------------ + +LDAP support is very similar to SQL support. + +Configuration +------------- + +---%<------------------------------------------------------------------------- +dict { + somedict = ldap:/path/to/dovecot-ldap-dict.conf.ext +} +---%<------------------------------------------------------------------------- + +Then in ext file put + +---%<------------------------------------------------------------------------- +uri = ldap://hostname +bind_dn = optional bind dn +password = optional password +timeout = optional timeout +debug = 0 or 1 (optional, as well) +tls = yes|try|no (default is try) +---%<------------------------------------------------------------------------- + + * uri - LDAP connection URI as expected by OpenLDAP. + * bind_dn - DN or upn to use for binding + * password - password to use, only SIMPLE auth is supported at the moment + * timeout - How long to wait for reply, default is 30 seconds + * debug - 0 off, 1 on, will produce metric ton of output + * tls - yes = require either ldaps or successful start TLS, try = send start + TLS if necessary, no = do not send start TLS + +To map some key to a search do + +---%<------------------------------------------------------------------------- +map { + pattern = priv/test/mail + filter = (mail=*) # the () is required + base_dn = ou=container,dc=domain + username_attribute = uid # default is cn + value_attribute = mail +} +---%<------------------------------------------------------------------------- + +To do some more complex search + +---%<------------------------------------------------------------------------- +map { + pattern = priv/test/mail/$location + filter = (&(mail=*)(location=%{location}) # the () is required + base_dn = ou=container,dc=domain + username_attribute = uid # default is cn + value_attribute = mail + + fields { + location=$location + } +} +---%<------------------------------------------------------------------------- + +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Dict.txt dovecot-2.2.24/doc/wiki/Dict.txt --- dovecot-2.2.22/doc/wiki/Dict.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Dict.txt 2016-04-26 04:43:15.000000000 +0000 @@ -42,4 +42,4 @@ However, it works with only if it's started as root. If this isn't possible, look into using instead. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Director.txt dovecot-2.2.24/doc/wiki/Director.txt --- dovecot-2.2.22/doc/wiki/Director.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Director.txt 2016-04-26 04:43:15.000000000 +0000 @@ -299,4 +299,4 @@ Have the passdb lookup return 'director_proxy_maybe=y'. LMTP however doesn't currently support mixing recipients to both being proxied and store locally. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/DomainLost.txt dovecot-2.2.24/doc/wiki/DomainLost.txt --- dovecot-2.2.22/doc/wiki/DomainLost.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/DomainLost.txt 2016-04-26 04:43:15.000000000 +0000 @@ -57,4 +57,4 @@ '%n' AND domain = '%d' ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Errors.ChgrpNoPerm.txt dovecot-2.2.24/doc/wiki/Errors.ChgrpNoPerm.txt --- dovecot-2.2.22/doc/wiki/Errors.ChgrpNoPerm.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Errors.ChgrpNoPerm.txt 2016-04-26 04:43:15.000000000 +0000 @@ -23,4 +23,4 @@ 2. Give the mail process access to the group (e.g. 'mail_access_groups=mail' setting). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/FindMailLocation.txt dovecot-2.2.24/doc/wiki/FindMailLocation.txt --- dovecot-2.2.22/doc/wiki/FindMailLocation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/FindMailLocation.txt 2016-04-26 04:43:16.000000000 +0000 @@ -62,4 +62,4 @@ If you can find the mail, but it's in more exotic location, see if can help you to configure it. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/FinishBasicConfiguration.txt dovecot-2.2.24/doc/wiki/FinishBasicConfiguration.txt --- dovecot-2.2.22/doc/wiki/FinishBasicConfiguration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/FinishBasicConfiguration.txt 2016-04-26 04:43:16.000000000 +0000 @@ -9,4 +9,4 @@ webmail application to connect to Dovecot without using SSL or even having to configure it. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HAProxy.txt dovecot-2.2.24/doc/wiki/HAProxy.txt --- dovecot-2.2.22/doc/wiki/HAProxy.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HAProxy.txt 2016-04-26 04:43:16.000000000 +0000 @@ -87,4 +87,4 @@ server s1 backend.example.com:10143 send-proxy-v2 ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.EximAndDovecotSASL.txt dovecot-2.2.24/doc/wiki/HowTo.EximAndDovecotSASL.txt --- dovecot-2.2.22/doc/wiki/HowTo.EximAndDovecotSASL.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.EximAndDovecotSASL.txt 2016-04-26 04:43:17.000000000 +0000 @@ -51,4 +51,4 @@ version 4.72 or greater of exim. Previous versions of exim have trouble with the version of the protocol used in Dovecot 2 -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.ImapcProxy.txt dovecot-2.2.24/doc/wiki/HowTo.ImapcProxy.txt --- dovecot-2.2.22/doc/wiki/HowTo.ImapcProxy.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.ImapcProxy.txt 2016-04-26 04:43:17.000000000 +0000 @@ -171,4 +171,4 @@ # only allow auth if it's encrypted ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.PopBSMTPAndDovecot.txt dovecot-2.2.24/doc/wiki/HowTo.PopBSMTPAndDovecot.txt --- dovecot-2.2.22/doc/wiki/HowTo.PopBSMTPAndDovecot.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.PopBSMTPAndDovecot.txt 2016-04-26 04:43:17.000000000 +0000 @@ -360,4 +360,4 @@ relay-ctrl has recorded your client IP. Hook 'relay-ctrl-check' into your SMTP service, as documented in the relay-ctrl README, and you're done. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.PopRelay.txt dovecot-2.2.24/doc/wiki/HowTo.PopRelay.txt --- dovecot-2.2.22/doc/wiki/HowTo.PopRelay.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.PopRelay.txt 2016-04-26 04:43:17.000000000 +0000 @@ -136,4 +136,4 @@ 1; ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.PostfixAndDovecotSASL.txt dovecot-2.2.24/doc/wiki/HowTo.PostfixAndDovecotSASL.txt --- dovecot-2.2.22/doc/wiki/HowTo.PostfixAndDovecotSASL.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.PostfixAndDovecotSASL.txt 2016-04-26 04:43:17.000000000 +0000 @@ -110,4 +110,4 @@ * http://www.postfix.org/SASL_README.html#server_dovecot -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.Rootless.txt dovecot-2.2.24/doc/wiki/HowTo.Rootless.txt --- dovecot-2.2.22/doc/wiki/HowTo.Rootless.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.Rootless.txt 2016-04-26 04:43:18.000000000 +0000 @@ -115,4 +115,4 @@ user:{PLAIN}pass ---%<---------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.SimpleVirtualInstall.txt dovecot-2.2.24/doc/wiki/HowTo.SimpleVirtualInstall.txt --- dovecot-2.2.22/doc/wiki/HowTo.SimpleVirtualInstall.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.SimpleVirtualInstall.txt 2016-04-26 04:43:18.000000000 +0000 @@ -183,4 +183,4 @@ Joe has now 100MB quota and Jane has 200MB quota. See for more information about quota settings. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.txt dovecot-2.2.24/doc/wiki/HowTo.txt --- dovecot-2.2.22/doc/wiki/HowTo.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.txt 2016-04-26 04:43:16.000000000 +0000 @@ -34,7 +34,6 @@ * [HowTo.DovecotLDAPostfixAdminMySQL.txt] - * MySQL, Postfix and CCC [http://postfix.pentachron.net/] * MySQL, Exim, SpamAssassin and ClamAV [http://struction.de/projects/HOWTO_VirtualMail_Exim-MySQL-Spamassassin-ClamAV-Dovecot/] * Postfix and Dovecot with MySQL and TLS/SSL, Postgrey and DSPAM @@ -82,4 +81,4 @@ [http://content.fens.org/index.php?q=admin-howto/mail/dovecot2dbmail-proxy] * [HowTo.WriteConfiguration.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/HowTo.WriteConfiguration.txt dovecot-2.2.24/doc/wiki/HowTo.WriteConfiguration.txt --- dovecot-2.2.22/doc/wiki/HowTo.WriteConfiguration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/HowTo.WriteConfiguration.txt 2016-04-26 04:43:18.000000000 +0000 @@ -53,4 +53,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/ImapMetadata.txt dovecot-2.2.24/doc/wiki/ImapMetadata.txt --- dovecot-2.2.22/doc/wiki/ImapMetadata.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/ImapMetadata.txt 2016-04-26 04:43:18.000000000 +0000 @@ -22,4 +22,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/IMAPServer.txt dovecot-2.2.24/doc/wiki/IMAPServer.txt --- dovecot-2.2.22/doc/wiki/IMAPServer.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/IMAPServer.txt 2016-04-26 04:43:18.000000000 +0000 @@ -13,4 +13,4 @@ * NOTIFY: Set mailbox_list_index=yes * URLAUTH: Set imap_urlauth_host and mail_attribute_dict -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/IndexFiles.txt dovecot-2.2.24/doc/wiki/IndexFiles.txt --- dovecot-2.2.22/doc/wiki/IndexFiles.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/IndexFiles.txt 2016-04-26 04:43:18.000000000 +0000 @@ -135,4 +135,4 @@ users) it would even be possible to delete the whole main index and keep only the transaction log (although this isn't done currently). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.Exim.txt dovecot-2.2.24/doc/wiki/LDA.Exim.txt --- dovecot-2.2.22/doc/wiki/LDA.Exim.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.Exim.txt 2016-04-26 04:43:18.000000000 +0000 @@ -160,4 +160,4 @@ You need to have [VirtualUsers.Home.txt] set to have duplicate database enabled, among other reasons. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.Indexing.txt dovecot-2.2.24/doc/wiki/LDA.Indexing.txt --- dovecot-2.2.22/doc/wiki/LDA.Indexing.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.Indexing.txt 2016-04-26 04:43:18.000000000 +0000 @@ -44,4 +44,4 @@ index such new mails without doing anything expensive like "rebuilding indexes". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.Postfix.txt dovecot-2.2.24/doc/wiki/LDA.Postfix.txt --- dovecot-2.2.22/doc/wiki/LDA.Postfix.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.Postfix.txt 2016-04-26 04:43:18.000000000 +0000 @@ -223,4 +223,4 @@ *Info:* you can not use "reject_unverified_recipient" with "pipe" so this doesn't work with the Dovecot LDA "deliver". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.Qmail.txt dovecot-2.2.24/doc/wiki/LDA.Qmail.txt --- dovecot-2.2.22/doc/wiki/LDA.Qmail.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.Qmail.txt 2016-04-26 04:43:18.000000000 +0000 @@ -28,4 +28,4 @@ |/var/qmail/bin/preline -f /usr/local/libexec/dovecot/dovecot-lda -d $EXT@$USER ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.Sendmail.txt dovecot-2.2.24/doc/wiki/LDA.Sendmail.txt --- dovecot-2.2.22/doc/wiki/LDA.Sendmail.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.Sendmail.txt 2016-04-26 04:43:19.000000000 +0000 @@ -102,4 +102,4 @@ dovecot.m4 [http://sites.google.com/site/mclroy/dovecot/dovecot-m4] can be a bit more complex. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LDA.txt dovecot-2.2.24/doc/wiki/LDA.txt --- dovecot-2.2.22/doc/wiki/LDA.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LDA.txt 2016-04-26 04:43:18.000000000 +0000 @@ -295,4 +295,4 @@ * Sieve language support can be added with the [Pigeonhole.Sieve.txt]. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LMTP.Exim.txt dovecot-2.2.24/doc/wiki/LMTP.Exim.txt --- dovecot-2.2.22/doc/wiki/LMTP.Exim.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LMTP.Exim.txt 2016-04-26 04:43:19.000000000 +0000 @@ -123,4 +123,4 @@ Make sure to reference the name you have chosen for your local delivery router within /redirect_router/. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LMTP.txt dovecot-2.2.24/doc/wiki/LMTP.txt --- dovecot-2.2.22/doc/wiki/LMTP.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LMTP.txt 2016-04-26 04:43:19.000000000 +0000 @@ -123,4 +123,4 @@ * [HowTo.PostfixDovecotLMTP.txt] * [LMTP.Exim.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Logging.txt dovecot-2.2.24/doc/wiki/Logging.txt --- dovecot-2.2.22/doc/wiki/Logging.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Logging.txt 2016-04-26 04:43:19.000000000 +0000 @@ -171,4 +171,4 @@ That's enough to know if the password is same or different between login attempts. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/LoginProcess.txt dovecot-2.2.24/doc/wiki/LoginProcess.txt --- dovecot-2.2.22/doc/wiki/LoginProcess.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/LoginProcess.txt 2016-04-26 04:43:19.000000000 +0000 @@ -115,4 +115,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.Cydir.txt dovecot-2.2.24/doc/wiki/MailboxFormat.Cydir.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.Cydir.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.Cydir.txt 2016-04-26 04:43:19.000000000 +0000 @@ -17,4 +17,4 @@ handling code. Its code is small and simple, so it can also act as an example for writing new mail storage backends. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.dbox.txt dovecot-2.2.24/doc/wiki/MailboxFormat.dbox.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.dbox.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.dbox.txt 2016-04-26 04:43:20.000000000 +0000 @@ -248,4 +248,4 @@ available. Instead, the MTA could be set up to use [LMTP.txt] or [LDA.txt]. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.imapc.txt dovecot-2.2.24/doc/wiki/MailboxFormat.imapc.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.imapc.txt 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.imapc.txt 2016-04-26 04:43:20.000000000 +0000 @@ -0,0 +1,149 @@ +imapc storage +============= + +The imapc storage accesses a remote IMAP server as if it were a regular Dovecot +mailbox format. Dovecot can treat it as a very dummy storage or optionally a +more capable storage. + +---%<------------------------------------------------------------------------- +# In-memory index files: +mail_location = imapc: + +# Store index files locally: +mail_location = imapc:~/imapc +---%<------------------------------------------------------------------------- + +Connection settings +------------------- + +Do a regular IMAP LOGIN to imap.example.com using 'a LOGIN user@example.com +secret': + +---%<------------------------------------------------------------------------- +imapc_host = imap.example.com +imapc_password = secret +imapc_port = 143 +imapc_user = user@example.com +---%<------------------------------------------------------------------------- + +If you want to use a master user login, set: + +---%<------------------------------------------------------------------------- +imapc_master_user = masteruser +---%<------------------------------------------------------------------------- + +For SSL, use either: + + * ---%<---------------------------------------------------------------------- + imapc_ssl = imaps + imapc_port = 993 + ---%<---------------------------------------------------------------------- + + * ---%<---------------------------------------------------------------------- + imapc_ssl = starttls + imapc_port = 143 + ---%<---------------------------------------------------------------------- + +For testing you may want to disable all SSL certificate checks: + +---%<------------------------------------------------------------------------- +imapc_ssl_verify = yes +---%<------------------------------------------------------------------------- + +You can use other SASL mechanisms besides PLAIN by specifying (the first one +advertised by IMAP server is used): + +---%<------------------------------------------------------------------------- +imapc_sasl_mechanisms = external plain login +---%<------------------------------------------------------------------------- + +The SASL client mechanisms are implemented in Dovecot's lib-sasl/ code. It's +possible to add more with plugins. + +Other settings +-------------- + +imapc_cmd_timeout: + How long to wait for an IMAP command to reply before disconnecting and + retrying (default: 5 mins). + +imapc_list_prefix: + Access only mailboxes under this prefix. For example + 'imapc_list_prefix=INBOX/' + +imapc_max_idle_time: + Send something (NOOP/DONE) to server after not sending anything for this + amount of time (default: 29 mins). + +imapc_rawlog_dir: + Log all IMAP traffic input/output to this directory. + +Features and workarounds +------------------------ + +'imapc_features' setting is a space-separated list of features and workarounds +that can be enabled. + +Optimizations +------------- + +rfc822.size: + Allow passing through message sizes using 'FETCH RFC822.SIZE' + +fetch-headers: + Allow fetching specific message headers using 'FETCH BODY.PEEK[HEADER.FIELDS + (..)]' + +search: + Allow using 'SEARCH' command. + +Features +-------- + +gmail-migration: + Enable GMail-specific migration: Use IMAP X-GM-MSGID as POP3 UIDL. Add + $GMailHaveLabels keyword to mails that have X-GM-LABELS except for \Muted (to + be used for migrating only archived emails in "All Mails"). Add + pop3_deleted_flag to mails that don't exist in POP3 server. + +proxyauth: + Use Sun/Oracle IMAP-server specific PROXYAUTH command to do master user + authentication. Normally this would be done using the SASL PLAIN + authentication. + +throttle:INIT:MAX:SHRINK: + When receiving [THROTTLED] response (from GMail), throttling is applied. INIT + = initial throttling msecs (default: 50 ms), afterwards each subsequent + [THROTTLED] doubles the throttling until MAX is reached (default: 16000 ms). + When [THROTTLED] is not received for a while, it's shrank again. The initial + shrinking is done after SHRINK (default: 500 ms). If [THROTTLED] is received + again within this timeout, it's doubled, otherwise both throttling and the + next shrinking timeout is shrank to 3/4. + +Workarounds +----------- + +zimbra-workarounds: + Fetch full message using 'BODY.PEEK[HEADER] BODY.PEEK[TEXT]' instead of just + 'BODY.PEEK[]' because the header differs between these two when there are + illegal control chars or 8bit chars. This mainly caused problems with dsync, + but as of v2.2.22+ this should no longer be a problem and there's probably no + need to enable this workaround. + +no-examine: + Use SELECT instead of EXAMINE even when we don't want to modify anything in + the mailbox. This is a Courier-workaround where it didn't permanently assign + UIDVALIDITY to an EXAMINEd mailbox, but assigned it for SELECTed mailbox. + +fetch-msn-workarounds: + Try to ignore wrong message sequence numbers in FETCH replies whenever + possible, preferring to use the returned UID number instead. + +fetch-fix-broken-mails: + If a FETCH returns 'NO' (but not 'NO [LIMIT]' or 'NO [SERVERBUG]'), assume + the mail is broken in server and just treat it as if it were an empty email. + NOTE: This is often a dangerous option! It's not safe to assume that NO means + a permanent error rather than a temporary error. This feature should be + enabled only for specific users who have been determined to be broken. + +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.Maildir.txt dovecot-2.2.24/doc/wiki/MailboxFormat.Maildir.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.Maildir.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.Maildir.txt 2016-04-26 04:43:20.000000000 +0000 @@ -375,4 +375,4 @@ * Maildir++ [http://www.inter7.com/courierimap/README.maildirquota.html] * Wikipedia [http://en.wikipedia.org/wiki/Maildir] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.mailstore.txt dovecot-2.2.24/doc/wiki/MailboxFormat.mailstore.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.mailstore.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.mailstore.txt 2016-04-26 04:43:20.000000000 +0000 @@ -14,4 +14,4 @@ * http://www.exim.org/exim-html-4.60/doc/html/spec.html/ch26.html#id2639666 -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.mbox.txt dovecot-2.2.24/doc/wiki/MailboxFormat.mbox.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.mbox.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.mbox.txt 2016-04-26 04:43:20.000000000 +0000 @@ -287,4 +287,4 @@ [http://www.communigate.com/CommuniGatePro/Mailboxes.html#mbox] * MBOX File Viewer [http://www.freeviewer.org/mbox/] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.mbx.txt dovecot-2.2.24/doc/wiki/MailboxFormat.mbx.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.mbx.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.mbx.txt 2016-04-26 04:43:20.000000000 +0000 @@ -21,4 +21,4 @@ of size on disk.) This is probably UW-IMAP -specific implementation problem rather than actual mailbox format issue. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.MH.txt dovecot-2.2.24/doc/wiki/MailboxFormat.MH.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.MH.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.MH.txt 2016-04-26 04:43:19.000000000 +0000 @@ -49,4 +49,4 @@ * Mutt Manual [http://www.mutt.org/doc/manual/manual-4.html#ss4.6]: Describing how it handles MH folders -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxFormat.txt dovecot-2.2.24/doc/wiki/MailboxFormat.txt --- dovecot-2.2.22/doc/wiki/MailboxFormat.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxFormat.txt 2016-04-26 04:43:19.000000000 +0000 @@ -62,6 +62,14 @@ | | | testing and | | | | benchmarking only.| +-----------------------------+---------------+-------------------+-------------+ +| | 'imapc' | Use remote IMAP | +| [MailboxFormat.imapc.txt] | | server as mail | +| | | storage. | ++-----------------------------+---------------+-------------------+-------------+ +| | 'pop3c' | Use remote POP3 | +| [MailboxFormat.pop3c.txt] | | server as mail | +| | | storage. | ++-----------------------------+---------------+-------------------+-------------+ The *Tag* column indicates the tag which is used at the beginning of a [MailLocation.txt]. @@ -136,4 +144,4 @@ http://www.linuxmail.info/mbox-maildir-mail-storage-formats/ [http://www.linux-mail.info/mbox-maildir-mail-storage-formats/] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailboxSettings.txt dovecot-2.2.24/doc/wiki/MailboxSettings.txt --- dovecot-2.2.22/doc/wiki/MailboxSettings.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailboxSettings.txt 2016-04-26 04:43:20.000000000 +0000 @@ -41,6 +41,7 @@ namespace inbox { #prefix = INBOX. # the namespace prefix isn't added again to the mailbox names. + inbox = yes # ... mailbox Trash { @@ -70,4 +71,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/maildrop.txt dovecot-2.2.24/doc/wiki/maildrop.txt --- dovecot-2.2.22/doc/wiki/maildrop.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/maildrop.txt 2016-04-26 04:44:00.000000000 +0000 @@ -68,4 +68,4 @@ (README.dovecotauth) together with patch with a little bit more information regarding the use of this extension. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:44) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.dbox.txt dovecot-2.2.24/doc/wiki/MailLocation.dbox.txt --- dovecot-2.2.22/doc/wiki/MailLocation.dbox.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.dbox.txt 2016-04-26 04:43:19.000000000 +0000 @@ -85,4 +85,4 @@ chances of clashing with mail folder names. In the example here, unusual upper/lower casing has been used. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.LocalDisk.txt dovecot-2.2.24/doc/wiki/MailLocation.LocalDisk.txt --- dovecot-2.2.22/doc/wiki/MailLocation.LocalDisk.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.LocalDisk.txt 2016-04-26 04:43:19.000000000 +0000 @@ -47,4 +47,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.Maildir.txt dovecot-2.2.24/doc/wiki/MailLocation.Maildir.txt --- dovecot-2.2.22/doc/wiki/MailLocation.Maildir.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.Maildir.txt 2016-04-26 04:43:19.000000000 +0000 @@ -139,4 +139,4 @@ chances of clashing with mail folder names. In the example here, unusual upper/lower casing has been used. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.mbox.txt dovecot-2.2.24/doc/wiki/MailLocation.mbox.txt --- dovecot-2.2.22/doc/wiki/MailLocation.mbox.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.mbox.txt 2016-04-26 04:43:19.000000000 +0000 @@ -191,4 +191,4 @@ There are, however, some further considerations when doing this; see for an example. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.SharedDisk.txt dovecot-2.2.24/doc/wiki/MailLocation.SharedDisk.txt --- dovecot-2.2.22/doc/wiki/MailLocation.SharedDisk.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.SharedDisk.txt 2016-04-26 04:43:19.000000000 +0000 @@ -72,4 +72,4 @@ Cifs/smbfs is unlikely to work as a remote filesystem. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MailLocation.txt dovecot-2.2.24/doc/wiki/MailLocation.txt --- dovecot-2.2.22/doc/wiki/MailLocation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MailLocation.txt 2016-04-26 04:43:19.000000000 +0000 @@ -41,8 +41,13 @@ parameters. Possible values for /key/ are: * 'INDEX' : specifies the location of [MailLocation.txt]. * 'INBOX' : specifies the location of the [MailLocation.txt]. - * 'LAYOUT' : specifies the directory layout under the - [MailLocation.mbox.txt] or [MailLocation.Maildir.txt] formats. + * 'LAYOUT' : specifies the directory layout to use: + * Maildir++: The default used by Maildir format + * fs: The default used by mbox and dbox formats + * index: Uses mailbox GUIDs as the directory names. The mapping between + mailbox names and GUIDs exists in dovecot.list.index* files. + * 'UTF-8' : Store mailbox names on disk using UTF-8 instead of modified + UTF-7. * 'CONTROL' : specifies the location of control files under the [MailLocation.mbox.txt] or [MailLocation.Maildir.txt] formats. * 'SUBSCRIPTIONS' : specifies the file used for storing subscriptions. The @@ -282,4 +287,4 @@ exec env "NAMESPACE/USER/LOCATION=$location" "$@" ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Makefile.am dovecot-2.2.24/doc/wiki/Makefile.am --- dovecot-2.2.22/doc/wiki/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Makefile.am 2016-04-26 15:10:43.000000000 +0000 @@ -116,6 +116,7 @@ MailboxFormat.MH.txt \ MailboxFormat.Maildir.txt \ MailboxFormat.dbox.txt \ + MailboxFormat.imapc.txt \ MailboxFormat.mailstore.txt \ MailboxFormat.mbox.txt \ MailboxFormat.mbx.txt \ @@ -241,6 +242,7 @@ Upgrading.2.0.txt \ Upgrading.2.1.txt \ Upgrading.2.2.txt \ + Upgrading.2.3.txt \ Upgrading.txt \ UserDatabase.ExtraFields.txt \ UserDatabase.NSS.txt \ diff -Nru dovecot-2.2.22/doc/wiki/Makefile.in dovecot-2.2.24/doc/wiki/Makefile.in --- dovecot-2.2.22/doc/wiki/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -207,7 +207,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -455,6 +457,7 @@ MailboxFormat.MH.txt \ MailboxFormat.Maildir.txt \ MailboxFormat.dbox.txt \ + MailboxFormat.imapc.txt \ MailboxFormat.mailstore.txt \ MailboxFormat.mbox.txt \ MailboxFormat.mbx.txt \ @@ -580,6 +583,7 @@ Upgrading.2.0.txt \ Upgrading.2.1.txt \ Upgrading.2.2.txt \ + Upgrading.2.3.txt \ Upgrading.txt \ UserDatabase.ExtraFields.txt \ UserDatabase.NSS.txt \ diff -Nru dovecot-2.2.22/doc/wiki/MboxChildFolders.txt dovecot-2.2.24/doc/wiki/MboxChildFolders.txt --- dovecot-2.2.22/doc/wiki/MboxChildFolders.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MboxChildFolders.txt 2016-04-26 04:43:20.000000000 +0000 @@ -184,4 +184,4 @@ Unlike the Maildir++ layout approach above, because we are still using "filesystem" layout, the hierarchy separator remains as a slash. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MboxLocking.txt dovecot-2.2.24/doc/wiki/MboxLocking.txt --- dovecot-2.2.22/doc/wiki/MboxLocking.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MboxLocking.txt 2016-04-26 04:43:20.000000000 +0000 @@ -67,4 +67,4 @@ Debian's policy specifies that all software should use "fcntl and then dotlock" locking, but this probably applies only to most commonly used software. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MboxProblems.txt dovecot-2.2.24/doc/wiki/MboxProblems.txt --- dovecot-2.2.22/doc/wiki/MboxProblems.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MboxProblems.txt 2016-04-26 04:43:20.000000000 +0000 @@ -131,4 +131,4 @@ * X-UID * X-UIDL (if you're using 'pop3_reuse_xuidl=yes') -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MDA.txt dovecot-2.2.24/doc/wiki/MDA.txt --- dovecot-2.2.22/doc/wiki/MDA.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MDA.txt 2016-04-26 04:43:19.000000000 +0000 @@ -14,4 +14,4 @@ * procmail [http://www.procmail.org/] (appears to be unmaintained) * [LDA.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.BincIMAP.txt dovecot-2.2.24/doc/wiki/Migration.BincIMAP.txt --- dovecot-2.2.22/doc/wiki/Migration.BincIMAP.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.BincIMAP.txt 2016-04-26 04:43:20.000000000 +0000 @@ -346,4 +346,4 @@ * Binc's message flags are compatible with Dovecot (as they are specified by the Maildir specification) -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Courier.txt dovecot-2.2.24/doc/wiki/Migration.Courier.txt --- dovecot-2.2.22/doc/wiki/Migration.Courier.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Courier.txt 2016-04-26 04:43:20.000000000 +0000 @@ -84,4 +84,4 @@ * Courier's message keywords implementation isn't Dovecot compatible. There doesn't exist a simple way to convert the keywords manually. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Cyrus.txt dovecot-2.2.24/doc/wiki/Migration.Cyrus.txt --- dovecot-2.2.22/doc/wiki/Migration.Cyrus.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Cyrus.txt 2016-04-26 04:43:20.000000000 +0000 @@ -78,4 +78,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Dsync.txt dovecot-2.2.24/doc/wiki/Migration.Dsync.txt --- dovecot-2.2.22/doc/wiki/Migration.Dsync.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Dsync.txt 2016-04-26 04:43:20.000000000 +0000 @@ -124,4 +124,4 @@ * If source IMAP and POP3 servers return messages somehow differently, pop3-migration plugin might not be able to match the messages -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Gmail.txt dovecot-2.2.24/doc/wiki/Migration.Gmail.txt --- dovecot-2.2.22/doc/wiki/Migration.Gmail.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Gmail.txt 2016-04-26 04:43:21.000000000 +0000 @@ -70,4 +70,4 @@ doveadm backup -a 'virtual/All' -O '-$GmailHaveLabels' -R -u user@domain imapc: ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Linuxconf.txt dovecot-2.2.24/doc/wiki/Migration.Linuxconf.txt --- dovecot-2.2.22/doc/wiki/Migration.Linuxconf.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Linuxconf.txt 2016-04-26 04:43:21.000000000 +0000 @@ -61,4 +61,4 @@ More information about Linuxconf can be found at their Home Site [http://www.solucorp.qc.ca/linuxconf/]. Exim [http://www.exim.org] info here. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.MailFormat.txt dovecot-2.2.24/doc/wiki/Migration.MailFormat.txt --- dovecot-2.2.22/doc/wiki/Migration.MailFormat.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.MailFormat.txt 2016-04-26 04:43:21.000000000 +0000 @@ -242,4 +242,4 @@ copy tmp/foo '#driver.unix'/tmp/foo.unix' = convert /tmp/foo file to mbox - Manwe, 2010-03-09 -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Online.txt dovecot-2.2.24/doc/wiki/Migration.Online.txt --- dovecot-2.2.22/doc/wiki/Migration.Online.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Online.txt 2016-04-26 04:43:21.000000000 +0000 @@ -83,4 +83,4 @@ $ postqueue -f ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Teapop.txt dovecot-2.2.24/doc/wiki/Migration.Teapop.txt --- dovecot-2.2.22/doc/wiki/Migration.Teapop.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Teapop.txt 2016-04-26 04:43:21.000000000 +0000 @@ -70,4 +70,4 @@ X-UIDL: after the Return-Path line. After that you can use the mb2md script.Important: You must set the 'pop3_reuse_xuidl=yes'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.txt dovecot-2.2.24/doc/wiki/Migration.txt --- dovecot-2.2.22/doc/wiki/Migration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.txt 2016-04-26 04:43:20.000000000 +0000 @@ -158,4 +158,4 @@ When run it will ask you for usernames and passwords that will be used for logging into servers, but you can also specify them on the command line. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.UW.txt dovecot-2.2.24/doc/wiki/Migration.UW.txt --- dovecot-2.2.22/doc/wiki/Migration.UW.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.UW.txt 2016-04-26 04:43:21.000000000 +0000 @@ -134,4 +134,4 @@ quit ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Migration.Vm-pop3d.txt dovecot-2.2.24/doc/wiki/Migration.Vm-pop3d.txt --- dovecot-2.2.22/doc/wiki/Migration.Vm-pop3d.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Migration.Vm-pop3d.txt 2016-04-26 04:43:21.000000000 +0000 @@ -39,4 +39,4 @@ When Dovecot now looks at newinbox, it will use the X-UIDL: header and clients will not redownload mail. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MissingMailboxes.txt dovecot-2.2.24/doc/wiki/MissingMailboxes.txt --- dovecot-2.2.22/doc/wiki/MissingMailboxes.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MissingMailboxes.txt 2016-04-26 04:43:21.000000000 +0000 @@ -51,4 +51,4 @@ If you see a list of expected mailboxes, the problem is with your IMAP client. If not, set 'mail_debug=yes' and look at the logs. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Mountpoints.txt dovecot-2.2.24/doc/wiki/Mountpoints.txt --- dovecot-2.2.22/doc/wiki/Mountpoints.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Mountpoints.txt 2016-04-26 04:43:21.000000000 +0000 @@ -52,4 +52,4 @@ doveadm mount add /mnt/foo ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/MTA.txt dovecot-2.2.24/doc/wiki/MTA.txt --- dovecot-2.2.22/doc/wiki/MTA.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/MTA.txt 2016-04-26 04:43:19.000000000 +0000 @@ -48,4 +48,4 @@ Contrast this to the [MDA.txt], sometimes called local delivery agent (LDA). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/mutt.txt dovecot-2.2.24/doc/wiki/mutt.txt --- dovecot-2.2.22/doc/wiki/mutt.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/mutt.txt 2016-04-26 04:44:00.000000000 +0000 @@ -101,4 +101,4 @@ * mutt with IMAP documentation [http://mutt.sourceforge.net/imap/] * http://jamespo.org.uk/blog/archives/000271.html -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:44) diff -Nru dovecot-2.2.22/doc/wiki/Namespaces.txt dovecot-2.2.24/doc/wiki/Namespaces.txt --- dovecot-2.2.22/doc/wiki/Namespaces.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Namespaces.txt 2016-04-26 04:43:21.000000000 +0000 @@ -279,4 +279,4 @@ .. ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/NFS.txt dovecot-2.2.24/doc/wiki/NFS.txt --- dovecot-2.2.22/doc/wiki/NFS.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/NFS.txt 2016-04-26 04:43:21.000000000 +0000 @@ -158,4 +158,4 @@ mounted for any reason and user access mails, a new empty user mail directory is created, which breaks things. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/OSCompatibility.txt dovecot-2.2.24/doc/wiki/OSCompatibility.txt --- dovecot-2.2.22/doc/wiki/OSCompatibility.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/OSCompatibility.txt 2016-04-26 04:43:21.000000000 +0000 @@ -48,4 +48,4 @@ * AIX xlC * HP-UX cc -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.BSDAuth.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.BSDAuth.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.BSDAuth.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.BSDAuth.txt 2016-04-26 04:43:32.000000000 +0000 @@ -4,4 +4,4 @@ This is similar to [PasswordDatabase.PAM.txt], but used by OpenBSD. It supports 'cache_key' parameter the same way as PAM. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.AllowNets.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.AllowNets.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.AllowNets.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.AllowNets.txt 2016-04-26 04:43:32.000000000 +0000 @@ -18,4 +18,4 @@ user:{plain}password::::::allow_nets=192.168.0.0/24 ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.Host.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.Host.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.Host.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.Host.txt 2016-04-26 04:43:32.000000000 +0000 @@ -72,4 +72,4 @@ 'Y' AS nodelay ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.NoDelay.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.NoDelay.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.NoDelay.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.NoDelay.txt 2016-04-26 04:43:32.000000000 +0000 @@ -10,4 +10,4 @@ Note that if PAM is used as the passdb, it adds an extra delay which can't be removed. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.NoLogin.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.NoLogin.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.NoLogin.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.NoLogin.txt 2016-04-26 04:43:32.000000000 +0000 @@ -19,4 +19,4 @@ neither 'proxy' nor 'host' are defined as one of the passdb extra fields. The order of preference is:'proxy', 'host', then 'nologin'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.Proxy.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.Proxy.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.Proxy.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.Proxy.txt 2016-04-26 04:43:33.000000000 +0000 @@ -116,6 +116,11 @@ See for more information how to configure this. +Example password forwarding static DB configuration +--------------------------------------------------- + +See + Example password forwarding SQL configuration --------------------------------------------- @@ -228,4 +233,4 @@ see: for more information, and a worked out example -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.txt 2016-04-26 04:43:32.000000000 +0000 @@ -22,6 +22,9 @@ * *nopassword*: If you want to allow all passwords, use an empty password and this field. * *fail*: If set, explicitly fails the passdb lookup. (v2.2.22+) + * *k5principals*: if using "auth_mechanisms = gssapi", may contain Kerberos v5 + principals allowed to map to the current user, bypassing the internal call + to krb5_kuserok(). The database must support credentials lookup. (v2.2+) How to return these extra fields depends on the password database you use. See the [PasswordDatabase.txt] pages on how to do it. Some @@ -83,4 +86,4 @@ user:{plain}pass::::::proxy=y host=127.0.0.1 ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.User.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.User.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.ExtraFields.User.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.ExtraFields.User.txt 2016-04-26 04:43:33.000000000 +0000 @@ -24,4 +24,4 @@ WHERE user = '%n' and domain = '%d' ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.IMAP.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.IMAP.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.IMAP.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.IMAP.txt 2016-04-26 04:43:33.000000000 +0000 @@ -26,4 +26,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.PAM.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.PAM.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.PAM.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.PAM.txt 2016-04-26 04:43:33.000000000 +0000 @@ -231,4 +231,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.Shadow.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.Shadow.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.Shadow.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.Shadow.txt 2016-04-26 04:43:33.000000000 +0000 @@ -35,4 +35,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.Static.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.Static.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.Static.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.Static.txt 2016-04-26 04:43:33.000000000 +0000 @@ -19,8 +19,9 @@ ---%<------------------------------------------------------------------------- passdb { driver = static - args = proxy=y nopassword=y + args = nopassword=y + default_fields = proxy=y host=127.0.0.1 } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PasswordDatabase.txt dovecot-2.2.24/doc/wiki/PasswordDatabase.txt --- dovecot-2.2.22/doc/wiki/PasswordDatabase.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PasswordDatabase.txt 2016-04-26 04:43:32.000000000 +0000 @@ -91,6 +91,9 @@ result_failure = continue result_internalfail = continue result_success = return-ok + + # v2.2.24+ + auth_verbose = default } ---%<------------------------------------------------------------------------- @@ -105,6 +108,9 @@ can contain <%variables> [Variables.txt]. * override_fields: Same as default_fields, but instead of providing the default values, these values override what the passdb backend returned. + * auth_verbose: If this is explicitly set to yes or no, it overrides the + global auth_verbose setting. (However, auth_debug=yes overrides the + auth_verbose setting.) (v2.2.24+) Then we have the settings which specify when the passdb is used: @@ -151,4 +157,4 @@ state. The initial state is failure. If this was set in result_success, the following passdbs will skip password verification. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PerformanceTuning.txt dovecot-2.2.24/doc/wiki/PerformanceTuning.txt --- dovecot-2.2.22/doc/wiki/PerformanceTuning.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PerformanceTuning.txt 2016-04-26 04:43:33.000000000 +0000 @@ -50,4 +50,4 @@ * 'service { process_limit, client_limit } ': These are mostly to avoid DoS attacks using up all your memory. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Installation.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Installation.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Installation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Installation.txt 2016-04-26 04:43:33.000000000 +0000 @@ -145,4 +145,4 @@ pkg_add dovecot-pigeonhole ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Clients.txt dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Clients.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Clients.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Clients.txt 2016-04-26 04:43:33.000000000 +0000 @@ -58,4 +58,4 @@ case, you must make sure that the issue is properly explained and that the author can contact you for more information. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Configuration.txt dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Configuration.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Configuration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Configuration.txt 2016-04-26 04:43:33.000000000 +0000 @@ -255,4 +255,4 @@ and the services are still called 'managesieve' and 'managesieve-login'. The example section demonstrates how this affects the configuration. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Install.txt dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Install.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Install.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Install.txt 2016-04-26 04:43:33.000000000 +0000 @@ -1,2 +1,2 @@ -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Troubleshooting.txt dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Troubleshooting.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.Troubleshooting.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.Troubleshooting.txt 2016-04-26 04:43:33.000000000 +0000 @@ -198,4 +198,4 @@ case, you must make sure that the issue is properly explained and that the author can contact you for more information. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.txt dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.ManageSieve.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.ManageSieve.txt 2016-04-26 04:43:33.000000000 +0000 @@ -24,4 +24,4 @@ * [Pigeonhole.ManageSieve.Troubleshooting.txt] * [Pigeonhole.ManageSieve.Clients.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.Dict.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.Dict.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.Dict.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.Dict.txt 2016-04-26 04:43:33.000000000 +0000 @@ -184,4 +184,4 @@ compile. Therefore, if a script is changed, then its ID must also be changed for it to be reloaded. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.File.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.File.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.File.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.File.txt 2016-04-26 04:43:33.000000000 +0000 @@ -49,4 +49,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.LDAP.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.LDAP.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.LDAP.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.LDAP.txt 2016-04-26 04:43:33.000000000 +0000 @@ -128,4 +128,4 @@ sieve_ldap_mod_attr = modifyTimestamp ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Configuration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Configuration.txt 2016-04-26 04:43:33.000000000 +0000 @@ -522,4 +522,4 @@ compatibility, it is recommended to update the setting to the new name, since the service also uses the 'recipient_delimiter' setting. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Examples.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Examples.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Examples.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Examples.txt 2016-04-26 04:43:34.000000000 +0000 @@ -402,4 +402,4 @@ Here's the original post announcing it: http://dovecot.org/list/dovecot/2007-March/020895.html -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Duplicate.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Duplicate.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Duplicate.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Duplicate.txt 2016-04-26 04:43:34.000000000 +0000 @@ -42,4 +42,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Editheader.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Editheader.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Editheader.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Editheader.txt 2016-04-26 04:43:34.000000000 +0000 @@ -58,4 +58,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Include.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Include.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Include.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Include.txt 2016-04-26 04:43:34.000000000 +0000 @@ -25,4 +25,4 @@ sieve_include_max_nesting_depth = 10 : The maximum nesting depth for the include tree. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt 2016-04-26 04:43:34.000000000 +0000 @@ -143,4 +143,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.txt 2016-04-26 04:43:34.000000000 +0000 @@ -11,4 +11,4 @@ * [Pigeonhole.Sieve.Extensions.Vacation.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Vacation.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Vacation.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Extensions.Vacation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Extensions.Vacation.txt 2016-04-26 04:43:34.000000000 +0000 @@ -103,4 +103,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Extdata.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Extdata.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Extdata.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Extdata.txt 2016-04-26 04:43:34.000000000 +0000 @@ -156,4 +156,4 @@ [http://hg.rename-it.nl/pigeonhole-0.2-sieve-extdata/raw-file/tip/doc/rfc/spec-bosch-sieve-external-data.txt] for more information. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Extprograms.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Extprograms.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Extprograms.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Extprograms.txt 2016-04-26 04:43:34.000000000 +0000 @@ -195,4 +195,4 @@ [http://hg.rename-it.nl/dovecot-2.2-pigeonhole/raw-file/tip/doc/rfc/spec-bosch-sieve-extprograms.txt]) for detailed information on how to use the new language extensions. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Pipe.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Pipe.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.Pipe.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.Pipe.txt 2016-04-26 04:43:34.000000000 +0000 @@ -184,4 +184,4 @@ password=PASSWORD ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Plugins.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Plugins.txt 2016-04-26 04:43:34.000000000 +0000 @@ -28,4 +28,4 @@ (typically shell scripts. Messages can be piped to or filtered through those programs and string data can be input to and retrieved from those programs. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Troubleshooting.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Troubleshooting.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Troubleshooting.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Troubleshooting.txt 2016-04-26 04:43:34.000000000 +0000 @@ -140,4 +140,4 @@ $sieverules_config['folder_encoding'] = 'UTF-8'; ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.txt 2016-04-26 04:43:33.000000000 +0000 @@ -278,4 +278,4 @@ available as a separate Dovecot service. Its configuration and use is explained on the [Pigeonhole.ManageSieve.txt]. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Usage.txt dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Usage.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.Sieve.Usage.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.Sieve.Usage.txt 2016-04-26 04:43:34.000000000 +0000 @@ -127,4 +127,4 @@ messages. Compile errors encountered in the user's private script are not logged here. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Pigeonhole.txt dovecot-2.2.24/doc/wiki/Pigeonhole.txt --- dovecot-2.2.22/doc/wiki/Pigeonhole.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Pigeonhole.txt 2016-04-26 04:43:33.000000000 +0000 @@ -43,4 +43,4 @@ [http://www.dovecot.org/mailinglists.html] for questions about the Pigeonhole. You don't have to subscribe to it. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Autocreate.txt dovecot-2.2.24/doc/wiki/Plugins.Autocreate.txt --- dovecot-2.2.22/doc/wiki/Plugins.Autocreate.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Autocreate.txt 2016-04-26 04:43:34.000000000 +0000 @@ -25,4 +25,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Compress.txt dovecot-2.2.24/doc/wiki/Plugins.Compress.txt --- dovecot-2.2.22/doc/wiki/Plugins.Compress.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Compress.txt 2016-04-26 04:43:34.000000000 +0000 @@ -13,4 +13,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Expire.txt dovecot-2.2.24/doc/wiki/Plugins.Expire.txt --- dovecot-2.2.22/doc/wiki/Plugins.Expire.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Expire.txt 2016-04-26 04:43:34.000000000 +0000 @@ -351,4 +351,4 @@ After running expire-tool without --test you'll see that the Trash mailbox is empty and the database row is deleted. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.FTS.Lucene.txt dovecot-2.2.24/doc/wiki/Plugins.FTS.Lucene.txt --- dovecot-2.2.22/doc/wiki/Plugins.FTS.Lucene.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.FTS.Lucene.txt 2016-04-26 04:43:34.000000000 +0000 @@ -1,6 +1,11 @@ Lucene Full Text Search Indexing ================================ +*NOTE*: Although the fts-lucene plugin works, it's using CLucene library, which +is very old and has some bugs. It's a much better idea to use +[Plugins.FTS.Solr.txt] instead, which has much more features and is more +stable. + Requires Dovecot v2.1+ to work properly. The CLucene version must be v2.3 (not v0.9).Dovecot builds only a single Lucene index for all mailboxes. The Lucene indexes are stored in 'lucene-indexes/' directory under the mail root index @@ -66,4 +71,4 @@ which you can rename to libstemmer.a * textcat [http://textcat.sourceforge.net/] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.FTS.Solr.txt dovecot-2.2.24/doc/wiki/Plugins.FTS.Solr.txt --- dovecot-2.2.22/doc/wiki/Plugins.FTS.Solr.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.FTS.Solr.txt 2016-04-26 04:43:34.000000000 +0000 @@ -166,4 +166,4 @@ support guide) [http://support.atmail.com/display/AKB/Installing+Apache+Solr+with+Dovecot+for+fulltext+search+results] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.FTS.Squat.txt dovecot-2.2.24/doc/wiki/Plugins.FTS.Squat.txt --- dovecot-2.2.22/doc/wiki/Plugins.FTS.Squat.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.FTS.Squat.txt 2016-04-26 04:43:34.000000000 +0000 @@ -125,4 +125,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.FTS.txt dovecot-2.2.24/doc/wiki/Plugins.FTS.txt --- dovecot-2.2.22/doc/wiki/Plugins.FTS.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.FTS.txt 2016-04-26 04:43:34.000000000 +0000 @@ -75,4 +75,4 @@ SEARCH fails with:'NO [INUSE] Timeout while waiting for indexing to finish' (v2.1+) -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.LastLogin.txt dovecot-2.2.24/doc/wiki/Plugins.LastLogin.txt --- dovecot-2.2.22/doc/wiki/Plugins.LastLogin.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.LastLogin.txt 2016-04-26 04:43:34.000000000 +0000 @@ -25,4 +25,4 @@ for user when new mails are delivered, you can do that by enabling the last_login plugin also for lda/lmtp and changing the last_login_key setting. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Lazyexpunge.txt dovecot-2.2.24/doc/wiki/Plugins.Lazyexpunge.txt --- dovecot-2.2.22/doc/wiki/Plugins.Lazyexpunge.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Lazyexpunge.txt 2016-04-26 04:43:34.000000000 +0000 @@ -167,4 +167,4 @@ amount of time. It keeps an internal database (e.g. SQL) of all such mailboxes, so it doesn't have to go through all the mailboxes for all the users. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Listescape.txt dovecot-2.2.24/doc/wiki/Plugins.Listescape.txt --- dovecot-2.2.22/doc/wiki/Plugins.Listescape.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Listescape.txt 2016-04-26 04:43:34.000000000 +0000 @@ -61,4 +61,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.MailboxAlias.txt dovecot-2.2.24/doc/wiki/Plugins.MailboxAlias.txt --- dovecot-2.2.22/doc/wiki/Plugins.MailboxAlias.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.MailboxAlias.txt 2016-04-26 04:43:34.000000000 +0000 @@ -43,4 +43,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.MailFilter.txt dovecot-2.2.24/doc/wiki/Plugins.MailFilter.txt --- dovecot-2.2.22/doc/wiki/Plugins.MailFilter.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.MailFilter.txt 2016-04-26 04:43:34.000000000 +0000 @@ -77,4 +77,4 @@ rm -f tempfile ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.MailLog.txt dovecot-2.2.24/doc/wiki/Plugins.MailLog.txt --- dovecot-2.2.22/doc/wiki/Plugins.MailLog.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.MailLog.txt 2016-04-26 04:43:34.000000000 +0000 @@ -47,4 +47,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Notify.txt dovecot-2.2.24/doc/wiki/Plugins.Notify.txt --- dovecot-2.2.22/doc/wiki/Plugins.Notify.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Notify.txt 2016-04-26 04:43:34.000000000 +0000 @@ -6,4 +6,4 @@ [Plugins.MailLog.txt] plugin as an example how to develop a plugin based on the notify plugin. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.QuotaClone.txt dovecot-2.2.24/doc/wiki/Plugins.QuotaClone.txt --- dovecot-2.2.22/doc/wiki/Plugins.QuotaClone.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.QuotaClone.txt 2016-04-26 04:43:34.000000000 +0000 @@ -28,4 +28,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Snarf.txt dovecot-2.2.24/doc/wiki/Plugins.Snarf.txt --- dovecot-2.2.22/doc/wiki/Plugins.Snarf.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Snarf.txt 2016-04-26 04:43:35.000000000 +0000 @@ -60,4 +60,4 @@ Now the snarfing is done only if '~/mbox' file exists. If it's not, the '/var/mail/user' is used directly as the INBOX. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Stats.txt dovecot-2.2.24/doc/wiki/Plugins.Stats.txt --- dovecot-2.2.22/doc/wiki/Plugins.Stats.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Stats.txt 2016-04-26 04:43:35.000000000 +0000 @@ -1,2 +1,2 @@ -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Trash.txt dovecot-2.2.24/doc/wiki/Plugins.Trash.txt --- dovecot-2.2.22/doc/wiki/Plugins.Trash.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Trash.txt 2016-04-26 04:43:35.000000000 +0000 @@ -38,4 +38,4 @@ 3 Sent Messages ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.txt dovecot-2.2.24/doc/wiki/Plugins.txt --- dovecot-2.2.22/doc/wiki/Plugins.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.txt 2016-04-26 04:43:34.000000000 +0000 @@ -79,4 +79,4 @@ To enable / disable plugins per user you can make your userdb return 'mail_plugins' extra field. See for examples. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Virtual.txt dovecot-2.2.24/doc/wiki/Plugins.Virtual.txt --- dovecot-2.2.22/doc/wiki/Plugins.Virtual.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Virtual.txt 2016-04-26 04:43:35.000000000 +0000 @@ -269,4 +269,4 @@ pop3_uidl_format = %g ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Plugins.Zlib.txt dovecot-2.2.24/doc/wiki/Plugins.Zlib.txt --- dovecot-2.2.22/doc/wiki/Plugins.Zlib.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Plugins.Zlib.txt 2016-04-26 04:43:35.000000000 +0000 @@ -97,4 +97,4 @@ 6. Unlock the maildir by sending a TERM signal to the maildirlock process (killing the PID it wrote to stdout). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/POP3Server.txt dovecot-2.2.24/doc/wiki/POP3Server.txt --- dovecot-2.2.22/doc/wiki/POP3Server.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/POP3Server.txt 2016-04-26 04:43:27.000000000 +0000 @@ -158,4 +158,4 @@ %m', it always appends the X-Delivery-ID: header to saved mailbox. Any existing X-Delivery-ID: headers in the saved mails are dropped. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PostLoginScripting.txt dovecot-2.2.24/doc/wiki/PostLoginScripting.txt --- dovecot-2.2.22/doc/wiki/PostLoginScripting.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PostLoginScripting.txt 2016-04-26 04:43:35.000000000 +0000 @@ -239,4 +239,4 @@ NAMESPACE/S-SPAMREP/LOCATION ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/PreAuth.txt dovecot-2.2.24/doc/wiki/PreAuth.txt --- dovecot-2.2.22/doc/wiki/PreAuth.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/PreAuth.txt 2016-04-26 04:43:35.000000000 +0000 @@ -19,4 +19,4 @@ Of course, you may need to run the above command as root if it needs to change process's uid/gid. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/QuickConfiguration.txt dovecot-2.2.24/doc/wiki/QuickConfiguration.txt --- dovecot-2.2.22/doc/wiki/QuickConfiguration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/QuickConfiguration.txt 2016-04-26 04:43:36.000000000 +0000 @@ -76,7 +76,7 @@ --------------------------------------- * Usually it does not matter in which file you write the setting, however, - later settings replace eatlier ones. If you use the same section multiple + later settings replace earlier ones. If you use the same section multiple times, the settings are merged together. * Boolean settings in the 'plugin' section interprete /any/ value as *true*, even '0', 'no' and 'false'. @@ -160,4 +160,4 @@ See and . -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.Configuration.txt dovecot-2.2.24/doc/wiki/Quota.Configuration.txt --- dovecot-2.2.22/doc/wiki/Quota.Configuration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.Configuration.txt 2016-04-26 04:43:36.000000000 +0000 @@ -480,4 +480,4 @@ a SETQUOTA "User quota" (STORAGE 12345 MESSAGES 123) ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.Count.txt dovecot-2.2.24/doc/wiki/Quota.Count.txt --- dovecot-2.2.22/doc/wiki/Quota.Count.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.Count.txt 2016-04-26 04:43:36.000000000 +0000 @@ -24,4 +24,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.Dict.txt dovecot-2.2.24/doc/wiki/Quota.Dict.txt --- dovecot-2.2.22/doc/wiki/Quota.Dict.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.Dict.txt 2016-04-26 04:43:36.000000000 +0000 @@ -61,7 +61,7 @@ ---%<------------------------------------------------------------------------- plugin { - quota = dict:User quota::file:%h/Maildir/dovecot-quota + quota = dict:User quota::file:%h/mdbox/dovecot-quota quota_rule = *:storage=10M:messages=1000 } ---%<------------------------------------------------------------------------- @@ -197,4 +197,4 @@ See for more information, especially about permission issues. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.Dirsize.txt dovecot-2.2.24/doc/wiki/Quota.Dirsize.txt --- dovecot-2.2.22/doc/wiki/Quota.Dirsize.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.Dirsize.txt 2016-04-26 04:43:36.000000000 +0000 @@ -18,4 +18,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.FS.txt dovecot-2.2.24/doc/wiki/Quota.FS.txt --- dovecot-2.2.22/doc/wiki/Quota.FS.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.FS.txt 2016-04-26 04:43:36.000000000 +0000 @@ -109,4 +109,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.Maildir.txt dovecot-2.2.24/doc/wiki/Quota.Maildir.txt --- dovecot-2.2.22/doc/wiki/Quota.Maildir.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.Maildir.txt 2016-04-26 04:43:36.000000000 +0000 @@ -48,4 +48,4 @@ file is recreated. This makes sure that if quota happens to be broken (e.g. externally deleted files) it won't stay that way forever. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Quota.txt dovecot-2.2.24/doc/wiki/Quota.txt --- dovecot-2.2.22/doc/wiki/Quota.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Quota.txt 2016-04-26 04:43:36.000000000 +0000 @@ -125,4 +125,4 @@ use a nightly [Plugins.Expire.txt] to expunge old messages from Trash mailbox. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Replication.txt dovecot-2.2.24/doc/wiki/Replication.txt --- dovecot-2.2.22/doc/wiki/Replication.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Replication.txt 2016-04-26 04:43:37.000000000 +0000 @@ -207,4 +207,4 @@ * v2.2.6+: If you're having trouble, verify that 'dovecot --hostdomain' returns different values for the servers. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/RunningDovecot.txt dovecot-2.2.24/doc/wiki/RunningDovecot.txt --- dovecot-2.2.22/doc/wiki/RunningDovecot.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/RunningDovecot.txt 2016-04-26 04:43:37.000000000 +0000 @@ -137,4 +137,4 @@ file and you just didn't find it. Try specifying the log file manually and make sure you're really looking at the correct file. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Sasl.txt dovecot-2.2.24/doc/wiki/Sasl.txt --- dovecot-2.2.22/doc/wiki/Sasl.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Sasl.txt 2016-04-26 04:43:37.000000000 +0000 @@ -22,4 +22,4 @@ Hopefully more software will follow. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SecurityTuning.txt dovecot-2.2.24/doc/wiki/SecurityTuning.txt --- dovecot-2.2.22/doc/wiki/SecurityTuning.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SecurityTuning.txt 2016-04-26 04:43:37.000000000 +0000 @@ -19,4 +19,4 @@ * Set 'first/last_valid_uid/gid' settings to contain only the range actually used by mail processes -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Services.txt dovecot-2.2.24/doc/wiki/Services.txt --- dovecot-2.2.22/doc/wiki/Services.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Services.txt 2016-04-26 04:43:38.000000000 +0000 @@ -487,4 +487,4 @@ process, but anvil's data is of higher importance and lower traffic than stats, so stats are tracked in a separate process. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.ClusterSetup.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.ClusterSetup.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.ClusterSetup.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.ClusterSetup.txt 2016-04-26 04:43:38.000000000 +0000 @@ -48,4 +48,4 @@ * sql: Shared SQL server * Any other [Dictionary.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.Permissions.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.Permissions.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.Permissions.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.Permissions.txt 2016-04-26 04:43:38.000000000 +0000 @@ -165,4 +165,4 @@ creation, the permissions are permanently preserved. So if you want to use different permissions, just chown/chmod the file. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.Public.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.Public.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.Public.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.Public.txt 2016-04-26 04:43:38.000000000 +0000 @@ -238,4 +238,4 @@ 'acl_shared_dict' setting is not relevant for public mailboxes (only for shared). -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.Shared.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.Shared.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.Shared.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.Shared.txt 2016-04-26 04:43:38.000000000 +0000 @@ -302,4 +302,4 @@ * 'doveadm acl debug -u user@domain shared/user/box' can be helpful in figuring out why a mailbox can't be accessed. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.Symlinks.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.Symlinks.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.Symlinks.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.Symlinks.txt 2016-04-26 04:43:38.000000000 +0000 @@ -39,4 +39,4 @@ symlinking an mbox file, put the shared mailboxes inside a directory and symlink the entire directory. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SharedMailboxes.txt dovecot-2.2.24/doc/wiki/SharedMailboxes.txt --- dovecot-2.2.22/doc/wiki/SharedMailboxes.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SharedMailboxes.txt 2016-04-26 04:43:38.000000000 +0000 @@ -14,4 +14,4 @@ See for common filesystem related permission problems that are common with all the sharing methods. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SocketUnavailable.txt dovecot-2.2.24/doc/wiki/SocketUnavailable.txt --- dovecot-2.2.22/doc/wiki/SocketUnavailable.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SocketUnavailable.txt 2016-04-26 04:43:38.000000000 +0000 @@ -68,4 +68,4 @@ an even lower limit, typically 128. In Linux you can increase this from '/proc/sys/net/core/somaxconn'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SSL.CertificateClientImporting.txt dovecot-2.2.24/doc/wiki/SSL.CertificateClientImporting.txt --- dovecot-2.2.22/doc/wiki/SSL.CertificateClientImporting.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SSL.CertificateClientImporting.txt 2016-04-26 04:43:37.000000000 +0000 @@ -62,4 +62,4 @@ Account -> SSL -> Certificate for receiving->Browse -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SSL.CertificateCreation.txt dovecot-2.2.24/doc/wiki/SSL.CertificateCreation.txt --- dovecot-2.2.22/doc/wiki/SSL.CertificateCreation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SSL.CertificateCreation.txt 2016-04-26 04:43:37.000000000 +0000 @@ -65,4 +65,4 @@ properties of the CA, you always can use OpenSSL, very much customizable, but however a bit cumbersome. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SSL.DovecotConfiguration.txt dovecot-2.2.24/doc/wiki/SSL.DovecotConfiguration.txt --- dovecot-2.2.22/doc/wiki/SSL.DovecotConfiguration.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SSL.DovecotConfiguration.txt 2016-04-26 04:43:37.000000000 +0000 @@ -424,4 +424,4 @@ Verify return code: 0 (ok) ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SSL.SNIClientSupport.txt dovecot-2.2.24/doc/wiki/SSL.SNIClientSupport.txt --- dovecot-2.2.22/doc/wiki/SSL.SNIClientSupport.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SSL.SNIClientSupport.txt 2016-04-26 04:43:37.000000000 +0000 @@ -8,5 +8,6 @@ Doesn't work: * K-9 on Droid X2 (any Android?) + * Apple Mail (Mac OS X 10.10 and lower AND iOS 9.3 and lower) -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SSL.txt dovecot-2.2.24/doc/wiki/SSL.txt --- dovecot-2.2.22/doc/wiki/SSL.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SSL.txt 2016-04-26 04:43:37.000000000 +0000 @@ -59,4 +59,4 @@ capabilities, insist on TLS, then start all over again inside the encrypted session. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Statistics.txt dovecot-2.2.24/doc/wiki/Statistics.txt --- dovecot-2.2.22/doc/wiki/Statistics.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Statistics.txt 2016-04-26 04:43:38.000000000 +0000 @@ -204,4 +204,4 @@ The output will be identical to 'doveadm stats dump session connected' command. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/SystemUsers.txt dovecot-2.2.24/doc/wiki/SystemUsers.txt --- dovecot-2.2.22/doc/wiki/SystemUsers.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/SystemUsers.txt 2016-04-26 04:43:38.000000000 +0000 @@ -109,4 +109,4 @@ 'valid_chroot_dirs' setting ('/home' in the previous example). If this isn't done, Dovecot just ignores the "/./". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/TestInstallation.txt dovecot-2.2.24/doc/wiki/TestInstallation.txt --- dovecot-2.2.22/doc/wiki/TestInstallation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/TestInstallation.txt 2016-04-26 04:43:38.000000000 +0000 @@ -232,4 +232,4 @@ e OK Logout completed. ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/TestPop3Installation.txt dovecot-2.2.24/doc/wiki/TestPop3Installation.txt --- dovecot-2.2.22/doc/wiki/TestPop3Installation.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/TestPop3Installation.txt 2016-04-26 04:43:38.000000000 +0000 @@ -146,4 +146,4 @@ +OK Logging out. ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/TimeMovedBackwards.txt dovecot-2.2.24/doc/wiki/TimeMovedBackwards.txt --- dovecot-2.2.22/doc/wiki/TimeMovedBackwards.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/TimeMovedBackwards.txt 2016-04-26 04:43:38.000000000 +0000 @@ -88,4 +88,4 @@ While killing mail processes doesn't fully solve any of those issues, they're at least less likely to happen then. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Timeouts.txt dovecot-2.2.24/doc/wiki/Timeouts.txt --- dovecot-2.2.22/doc/wiki/Timeouts.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Timeouts.txt 2016-04-26 04:43:38.000000000 +0000 @@ -58,4 +58,4 @@ CLIENT_LOGIN_TIMEOUT_MSECS = MASTER_LOGIN_TIMEOUT_SECS*1000 = 3 minutes (login-common/client-common.h and lib-master/master-interface.h) -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.1.0.txt dovecot-2.2.24/doc/wiki/Upgrading.1.0.txt --- dovecot-2.2.22/doc/wiki/Upgrading.1.0.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.1.0.txt 2016-04-26 04:43:46.000000000 +0000 @@ -134,4 +134,4 @@ rip=(\d+\.\d+\.\d+\.\d+),.*$/$2/i; ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.1.1.txt dovecot-2.2.24/doc/wiki/Upgrading.1.1.txt --- dovecot-2.2.22/doc/wiki/Upgrading.1.1.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.1.1.txt 2016-04-26 04:43:46.000000000 +0000 @@ -87,4 +87,4 @@ * mmap_no_write: OpenBSD users will have to settle for mmap_disable=yes for now. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.1.2.txt dovecot-2.2.24/doc/wiki/Upgrading.1.2.txt --- dovecot-2.2.22/doc/wiki/Upgrading.1.2.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.1.2.txt 2016-04-26 04:43:46.000000000 +0000 @@ -54,4 +54,4 @@ needs to be done is remove the 'sieve=' and 'sieve_storage=' settings from the ' protocol managesieve {} ' section. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.2.0.txt dovecot-2.2.24/doc/wiki/Upgrading.2.0.txt --- dovecot-2.2.22/doc/wiki/Upgrading.2.0.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.2.0.txt 2016-04-26 04:43:46.000000000 +0000 @@ -89,4 +89,4 @@ * -s parameter was replaced by lda_mailbox_autosubscribe setting. The default is "no", as before. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.2.1.txt dovecot-2.2.24/doc/wiki/Upgrading.2.1.txt --- dovecot-2.2.22/doc/wiki/Upgrading.2.1.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.2.1.txt 2016-04-26 04:43:46.000000000 +0000 @@ -32,4 +32,4 @@ * dsync protocol isn't compatible with v2.0's dsync, so you can't dsync between v2.0 and v2.1 servers. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.2.2.txt dovecot-2.2.24/doc/wiki/Upgrading.2.2.txt --- dovecot-2.2.22/doc/wiki/Upgrading.2.2.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.2.2.txt 2016-04-26 04:43:46.000000000 +0000 @@ -42,4 +42,4 @@ the 'dovecot.index.cache' files are corrupted and complain about "Invalid magic in hole header". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.2.3.txt dovecot-2.2.24/doc/wiki/Upgrading.2.3.txt --- dovecot-2.2.22/doc/wiki/Upgrading.2.3.txt 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.2.3.txt 2016-04-26 04:43:46.000000000 +0000 @@ -0,0 +1,15 @@ +Upgrading Dovecot v2.2 to v2.3 +============================== + +Settings changes +---------------- + + * director_doveadm_port setting removed. Name the inet_listener doveadm { .. } + instead. + +Setting default changes +----------------------- + + * mdbox_rotate_size=2M -> 10M + +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/Upgrading.txt dovecot-2.2.24/doc/wiki/Upgrading.txt --- dovecot-2.2.22/doc/wiki/Upgrading.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Upgrading.txt 2016-04-26 04:43:45.000000000 +0000 @@ -21,4 +21,4 @@ * [Upgrading.2.1.txt] * [Upgrading.2.2.txt] -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserDatabase.ExtraFields.txt dovecot-2.2.24/doc/wiki/UserDatabase.ExtraFields.txt --- dovecot-2.2.22/doc/wiki/UserDatabase.ExtraFields.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserDatabase.ExtraFields.txt 2016-04-26 04:43:46.000000000 +0000 @@ -105,4 +105,4 @@ userdb_quota_rule=*:storage=200M ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserDatabase.NSS.txt dovecot-2.2.24/doc/wiki/UserDatabase.NSS.txt --- dovecot-2.2.22/doc/wiki/UserDatabase.NSS.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserDatabase.NSS.txt 2016-04-26 04:43:46.000000000 +0000 @@ -31,4 +31,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserDatabase.Prefetch.txt dovecot-2.2.24/doc/wiki/UserDatabase.Prefetch.txt --- dovecot-2.2.22/doc/wiki/UserDatabase.Prefetch.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserDatabase.Prefetch.txt 2016-04-26 04:43:46.000000000 +0000 @@ -84,4 +84,4 @@ user_attrs = homeDirectory=home, uidNumber=uid, gidNumber=gid ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserDatabase.Static.txt dovecot-2.2.24/doc/wiki/UserDatabase.Static.txt --- dovecot-2.2.22/doc/wiki/UserDatabase.Static.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserDatabase.Static.txt 2016-04-26 04:43:46.000000000 +0000 @@ -38,4 +38,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserDatabase.txt dovecot-2.2.24/doc/wiki/UserDatabase.txt --- dovecot-2.2.22/doc/wiki/UserDatabase.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserDatabase.txt 2016-04-26 04:43:46.000000000 +0000 @@ -62,6 +62,9 @@ result_failure = continue result_internalfail = continue result_success = return-ok + + # v2.2.24+: + auth_verbose = default } ---%<------------------------------------------------------------------------- @@ -78,6 +81,9 @@ default values, these values override what the userdb backend returned. For example useful with [AuthDatabase.Passwd.txt] for overriding e.g. home directory or the uid/gid. + * auth_verbose: If this is explicitly set to yes or no, it overrides the + global auth_verbose setting. (However, auth_debug=yes overrides the + auth_verbose setting.) (v2.2.24+) Then we have the setting which specify when the userdb is used (v2.2.10+): @@ -115,4 +121,4 @@ * continue: Continue to the next userdb without changing the user existence state. The initial state is "not found". -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/UserIds.txt dovecot-2.2.24/doc/wiki/UserIds.txt --- dovecot-2.2.22/doc/wiki/UserIds.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/UserIds.txt 2016-04-26 04:43:46.000000000 +0000 @@ -144,4 +144,4 @@ } ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/uw2dovecot.sh.txt dovecot-2.2.24/doc/wiki/uw2dovecot.sh.txt --- dovecot-2.2.22/doc/wiki/uw2dovecot.sh.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/uw2dovecot.sh.txt 2016-04-26 04:44:00.000000000 +0000 @@ -10,4 +10,4 @@ done ---%<------------------------------------------------------------------------- -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:44) diff -Nru dovecot-2.2.22/doc/wiki/Variables.txt dovecot-2.2.24/doc/wiki/Variables.txt --- dovecot-2.2.22/doc/wiki/Variables.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/Variables.txt 2016-04-26 04:43:46.000000000 +0000 @@ -255,4 +255,4 @@ The modifiers are applied from left-to-right order, except the substring is always taken from the final string. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/VirtualUsers.Home.txt dovecot-2.2.24/doc/wiki/VirtualUsers.Home.txt --- dovecot-2.2.22/doc/wiki/VirtualUsers.Home.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/VirtualUsers.Home.txt 2016-04-26 04:43:46.000000000 +0000 @@ -86,4 +86,4 @@ Then just use 'mail_location = maildir:~/Maildir'. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/VirtualUsers.txt dovecot-2.2.24/doc/wiki/VirtualUsers.txt --- dovecot-2.2.22/doc/wiki/VirtualUsers.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/VirtualUsers.txt 2016-04-26 04:43:46.000000000 +0000 @@ -146,4 +146,4 @@ * Also see the page -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/doc/wiki/WhyDoesItNotWork.txt dovecot-2.2.24/doc/wiki/WhyDoesItNotWork.txt --- dovecot-2.2.22/doc/wiki/WhyDoesItNotWork.txt 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/doc/wiki/WhyDoesItNotWork.txt 2016-04-26 04:43:53.000000000 +0000 @@ -101,4 +101,4 @@ different access permissions or POSIX eXtended attributes may change the traditional permissions. -(This file was created from the wiki on 2016-03-16 04:44) +(This file was created from the wiki on 2016-04-26 04:43) diff -Nru dovecot-2.2.22/dovecot-version.h dovecot-2.2.24/dovecot-version.h --- dovecot-2.2.22/dovecot-version.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/dovecot-version.h 2016-04-26 14:30:14.000000000 +0000 @@ -1,6 +1,6 @@ #ifndef DOVECOT_VERSION_H #define DOVECOT_VERSION_H -#define DOVECOT_VERSION_FULL VERSION" (fe789d2)" +#define DOVECOT_VERSION_FULL VERSION" (a82c823)" #endif /* DOVECOT_VERSION_H */ diff -Nru dovecot-2.2.22/install-sh dovecot-2.2.24/install-sh --- dovecot-2.2.22/install-sh 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/install-sh 2015-12-09 15:53:17.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -41,19 +41,15 @@ # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,17 +64,6 @@ rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. @@ -97,7 +82,7 @@ dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -137,46 +122,57 @@ -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - -T) no_target_directory=true;; + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -208,6 +204,15 @@ fi if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 @@ -223,16 +228,16 @@ *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -269,41 +274,15 @@ # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi @@ -314,74 +293,81 @@ if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else @@ -391,53 +377,51 @@ # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue + test X"$d" = X && continue - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -472,15 +456,12 @@ # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -493,24 +474,24 @@ # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 diff -Nru dovecot-2.2.22/Makefile.in dovecot-2.2.24/Makefile.in --- dovecot-2.2.22/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -298,7 +298,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/missing dovecot-2.2.24/missing --- dovecot-2.2.22/missing 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/missing 2015-12-09 15:53:17.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff -Nru dovecot-2.2.22/NEWS dovecot-2.2.24/NEWS --- dovecot-2.2.22/NEWS 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/NEWS 2016-04-26 14:27:47.000000000 +0000 @@ -1,3 +1,58 @@ +v2.2.24 2016-04-26 Timo Sirainen + + * doveconf now warns if it sees a global setting being changed when + the same setting was already set inside some filters. (A common + mistake has been adding more plugins to a global mail_plugins + setting after it was already set inside protocol { .. }, which + caused the global setting to be ignored for that protocol.) + * LMTP proxy: Increased default timeout 30s -> 125s. This makes it + less likely to reach the timeout and cause duplicate deliveries. + * LMTP and indexer now append ":suffix" to session IDs to make it + unique for the specific user's delivery. (Fixes duplicate session + ID warnings in stats process.) + + + Added dict-ldap for performing read-only LDAP dict lookups. + + lazy-expunge: All mails can be saved to a single specified mailbox. + + mailbox { autoexpunge } supports now wildcards in mailbox names. + + doveadm HTTP API: Added support for proxy commands + + imapc: Reconnect when getting disconnected in non-selected state. + + imapc: Added imapc_features=modseq to access MODSEQs/HIGHESTMODSEQ. + This is especially useful for incremental dsync. + + doveadm auth/user: Auth lookup performs debug logging if + -o auth_debug=yes is given to doveadm. + + Added passdb/userdb { auth_verbose=yes|no } setting. + + Cassandra: Added user, password, num_threads, connect_timeout and + request_timeout settings. + + doveadm user -e : Print with %variables expanded. + - Huge header lines could have caused Dovecot to use too much memory + (depending on config and used IMAP commands). (Typically this would + result in only the single user's process dying with out of memory + due to reaching service { vsz_limit } - not a global DoS). + - dsync: Detect and handle invalid/stale -s state string better. + - dsync: Fixed crash caused by specific mailbox renames + - auth: Auth cache is now disabled passwd-file. It was unnecessary and + it broke %variables in extra fields. + - fts-tika: Don't crash if it returns 500 error + - dict-redis: Fixed timeout handling + - SEARCH INTHREAD was crashing + - stats: Only a single fifo_listeners was supported, making it + impossible to use both auth_stats=yes and mail stats plugin. + - SSL errors were logged in separate "Stacked error" log lines + instead of as part of the disconnection reason. + - MIME body parser didn't handle properly when a child MIME part's + --boundary had the same prefix as the parent. + +v2.2.23 2016-03-30 Timo Sirainen + + - Various fixes to doveadm. Especially running commands via + doveadm-server was broken. + - director: Fixed user weakness getting stuck in some situations + - director: Fixed a situation where directors keep re-sending + different states to each others and never becoming synced. + - director: Fixed assert-crash related to a slow "user killed" reply + - Fixed assert-crash related to istream-concat, which could have + been triggered at least by a Sieve script. + v2.2.22 2016-03-16 Timo Sirainen + Added doveadm HTTP API: See diff -Nru dovecot-2.2.22/src/anvil/Makefile.in dovecot-2.2.24/src/anvil/Makefile.in --- dovecot-2.2.22/src/anvil/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/anvil/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -237,7 +237,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/auth/auth-master-connection.c dovecot-2.2.24/src/auth/auth-master-connection.c --- dovecot-2.2.22/src/auth/auth-master-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-master-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -68,9 +68,8 @@ return t_strarray_join((void *)args, "\t"); } -void auth_master_request_callback(const char *reply, void *context) +void auth_master_request_callback(const char *reply, struct auth_master_connection *conn) { - struct auth_master_connection *conn = context; struct const_iovec iov[2]; if (conn->auth->set->debug) { diff -Nru dovecot-2.2.22/src/auth/auth-master-connection.h dovecot-2.2.24/src/auth/auth-master-connection.h --- dovecot-2.2.22/src/auth/auth-master-connection.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-master-connection.h 2016-04-26 13:01:20.000000000 +0000 @@ -34,7 +34,7 @@ void auth_master_connection_ref(struct auth_master_connection *conn); void auth_master_connection_unref(struct auth_master_connection **conn); -void auth_master_request_callback(const char *reply, void *context); +void auth_master_request_callback(const char *reply, struct auth_master_connection *conn); void auth_master_connections_destroy_all(void); diff -Nru dovecot-2.2.22/src/auth/auth-request.c dovecot-2.2.24/src/auth/auth-request.c --- dovecot-2.2.22/src/auth/auth-request.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-request.c 2016-04-26 13:01:20.000000000 +0000 @@ -64,6 +64,7 @@ request->session_pid = (pid_t)-1; request->set = global_auth_settings; + request->debug = request->set->debug; request->mech = mech; request->mech_name = mech->mech_name; request->extra_fields = auth_fields_init(request->pool); @@ -86,6 +87,7 @@ request->last_access = ioloop_time; request->session_pid = (pid_t)-1; request->set = global_auth_settings; + request->debug = request->set->debug; request->extra_fields = auth_fields_init(request->pool); return request; } @@ -110,6 +112,9 @@ auth = auth_request_get_auth(request); request->set = auth->set; + /* NOTE: request->debug may already be TRUE here */ + if (request->set->debug) + request->debug = TRUE; request->passdb = auth->passdbs; request->userdb = auth->userdbs; } @@ -260,6 +265,8 @@ str_printfa(dest, "\treal_lport=%u", request->real_local_port); if (request->real_remote_port != 0) str_printfa(dest, "\treal_rport=%u", request->real_remote_port); + if (request->debug) + str_append(dest, "\tdebug"); if (request->secured) str_append(dest, "\tsecured"); if (request->skip_password_check) @@ -307,6 +314,8 @@ (void)net_str2port(value, &request->real_remote_port); else if (strcmp(key, "session") == 0) request->session_id = p_strdup(request->pool, value); + else if (strcmp(key, "debug") == 0) + request->debug = TRUE; else return FALSE; return TRUE; @@ -2022,6 +2031,14 @@ str_append(str, "unknown user "); auth_request_append_password(request, str); + + if (request->userdb_lookup) { + if (request->userdb->next != NULL) + str_append(str, " - trying the next userdb"); + } else { + if (request->passdb->next != NULL) + str_append(str, " - trying the next passdb"); + } i_info("%s", str_c(str)); } @@ -2152,7 +2169,7 @@ { va_list va; - if (!auth_request->set->debug) + if (!auth_request->debug) return; va_start(va, format); @@ -2168,8 +2185,25 @@ { va_list va; - if (!auth_request->set->verbose) - return; + if (auth_request->set->debug) { + /* auth_debug=yes overrides auth_verbose settings */ + } else { + const char *db_auth_verbose = auth_request->userdb_lookup ? + auth_request->userdb->set->auth_verbose : + auth_request->passdb->set->auth_verbose; + switch (db_auth_verbose[0]) { + case 'y': + break; + case 'n': + return; + case 'd': + if (!auth_request->set->verbose) + return; + break; + default: + i_unreached(); + } + } va_start(va, format); T_BEGIN { diff -Nru dovecot-2.2.22/src/auth/auth-request.h dovecot-2.2.24/src/auth/auth-request.h --- dovecot-2.2.22/src/auth/auth-request.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-request.h 2016-04-26 13:01:20.000000000 +0000 @@ -102,6 +102,8 @@ unsigned int userdb_lookup:1; /* DIGEST-MD5 kludge */ unsigned int domain_is_realm:1; + /* auth_debug is enabled for this request */ + unsigned int debug:1; /* flags received from auth client: */ unsigned int secured:1; diff -Nru dovecot-2.2.22/src/auth/auth-request-handler.c dovecot-2.2.24/src/auth/auth-request-handler.c --- dovecot-2.2.22/src/auth/auth-request-handler.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-request-handler.c 2016-04-26 13:01:20.000000000 +0000 @@ -27,10 +27,10 @@ unsigned int connect_uid, client_pid; - auth_request_callback_t *callback; - void *context; + auth_client_request_callback_t *callback; + struct auth_client_connection *conn; - auth_request_callback_t *master_callback; + auth_master_request_callback_t *master_callback; unsigned int destroyed:1; unsigned int token_auth:1; @@ -42,10 +42,10 @@ static void auth_failure_timeout(void *context) ATTR_NULL(1); -#undef auth_request_handler_create struct auth_request_handler * -auth_request_handler_create(bool token_auth, auth_request_callback_t *callback, - void *context, auth_request_callback_t *master_callback) +auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback, + struct auth_client_connection *conn, + auth_master_request_callback_t *master_callback) { struct auth_request_handler *handler; pool_t pool; @@ -57,7 +57,7 @@ handler->pool = pool; hash_table_create_direct(&handler->requests, pool, 0); handler->callback = callback; - handler->context = context; + handler->conn = conn; handler->master_callback = master_callback; handler->token_auth = token_auth; return handler; @@ -108,7 +108,7 @@ i_assert(hash_table_count(handler->requests) == 0); /* notify parent that we're done with all requests */ - handler->callback(NULL, handler->context); + handler->callback(NULL, handler->conn); hash_table_destroy(&handler->requests); pool_unref(&handler->pool); @@ -207,7 +207,7 @@ if (request->in_delayed_failure_queue) { /* we came here from flush_failures() */ - handler->callback(reply, handler->context); + handler->callback(reply, handler->conn); return; } @@ -217,7 +217,7 @@ if (auth_fields_exists(request->extra_fields, "nodelay")) { /* passdb specifically requested not to delay the reply. */ - handler->callback(reply, handler->context); + handler->callback(reply, handler->conn); auth_request_unref(&request); return; } @@ -267,7 +267,7 @@ process to pick it up. delete it */ auth_request_handler_remove(handler, request); } - handler->callback(str_c(str), handler->context); + handler->callback(str_c(str), handler->conn); } static void @@ -353,7 +353,7 @@ base64_encode(auth_reply, reply_size, str); request->accept_cont_input = TRUE; - handler->callback(str_c(str), handler->context); + handler->callback(str_c(str), handler->conn); break; case AUTH_CLIENT_RESULT_SUCCESS: if (reply_size > 0) { @@ -399,7 +399,7 @@ str_printfa(str, "FAIL\t%u\treason=", request->id); str_append_tabescaped(str, reason); - handler->callback(str_c(str), handler->context); + handler->callback(str_c(str), handler->conn); auth_request_handler_remove(handler, request); } @@ -599,7 +599,7 @@ if (request == NULL) { const char *reply = t_strdup_printf( "FAIL\t%u\treason=Authentication request timed out", id); - handler->callback(reply, handler->context); + handler->callback(reply, handler->conn); return TRUE; } diff -Nru dovecot-2.2.22/src/auth/auth-request-handler.h dovecot-2.2.24/src/auth/auth-request-handler.h --- dovecot-2.2.22/src/auth/auth-request-handler.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-request-handler.h 2016-04-26 13:01:20.000000000 +0000 @@ -2,6 +2,7 @@ #define AUTH_REQUEST_HANDLER_H struct auth_request; +struct auth_client_connection; struct auth_master_connection; struct auth_stream_reply; @@ -12,18 +13,14 @@ }; typedef void -auth_request_callback_t(const char *reply, void *context); +auth_client_request_callback_t(const char *reply, struct auth_client_connection *conn); +typedef void +auth_master_request_callback_t(const char *reply, struct auth_master_connection *conn); struct auth_request_handler * -auth_request_handler_create(bool token_auth, auth_request_callback_t *callback, - void *context, auth_request_callback_t *master_callback); -#define auth_request_handler_create(token_auth, callback, context, master_callback)\ - auth_request_handler_create(token_auth, \ - (auth_request_callback_t *)callback, \ - (void *)((char*)context + \ - CALLBACK_TYPECHECK(callback, void (*)( \ - const char *, typeof(context)))), \ - master_callback) +auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback, + struct auth_client_connection *conn, + auth_master_request_callback_t *master_callback); void auth_request_handler_destroy(struct auth_request_handler **handler); void auth_request_handler_unref(struct auth_request_handler **handler); diff -Nru dovecot-2.2.22/src/auth/auth-settings.c dovecot-2.2.24/src/auth/auth-settings.c --- dovecot-2.2.22/src/auth/auth-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-settings.c 2016-04-26 13:01:20.000000000 +0000 @@ -121,6 +121,7 @@ DEF(SET_BOOL, deny), DEF(SET_BOOL, pass), DEF(SET_BOOL, master), + DEF(SET_ENUM, auth_verbose), SETTING_DEFINE_LIST_END }; @@ -139,7 +140,8 @@ .deny = FALSE, .pass = FALSE, - .master = FALSE + .master = FALSE, + .auth_verbose = "default:yes:no" }; const struct setting_parser_info auth_passdb_setting_parser_info = { @@ -171,6 +173,8 @@ DEF(SET_ENUM, result_failure), DEF(SET_ENUM, result_internalfail), + DEF(SET_ENUM, auth_verbose), + SETTING_DEFINE_LIST_END }; @@ -185,7 +189,9 @@ .skip = "never:found:notfound", .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail", .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail", - .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail" + .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail", + + .auth_verbose = "default:yes:no" }; const struct setting_parser_info auth_userdb_setting_parser_info = { diff -Nru dovecot-2.2.22/src/auth/auth-settings.h dovecot-2.2.24/src/auth/auth-settings.h --- dovecot-2.2.22/src/auth/auth-settings.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/auth-settings.h 2016-04-26 13:01:20.000000000 +0000 @@ -18,6 +18,7 @@ bool deny; bool pass; /* deprecated, use result_success=continue instead */ bool master; + const char *auth_verbose; }; struct auth_userdb_settings { @@ -31,6 +32,7 @@ const char *result_success; const char *result_failure; const char *result_internalfail; + const char *auth_verbose; }; struct auth_settings { diff -Nru dovecot-2.2.22/src/auth/db-ldap.c dovecot-2.2.24/src/auth/db-ldap.c --- dovecot-2.2.22/src/auth/db-ldap.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/db-ldap.c 2016-04-26 13:01:20.000000000 +0000 @@ -1552,7 +1552,7 @@ ctx->skip_null_values = skip_null_values; ctx->iter_dn_values = iter_dn_values; hash_table_create(&ctx->ldap_attrs, pool, 0, strcase_hash, strcasecmp); - if (ctx->auth_request->set->debug) + if (ctx->auth_request->debug) ctx->debug = t_str_new(256); get_ldap_fields(ctx, conn, res, ""); diff -Nru dovecot-2.2.22/src/auth/Makefile.in dovecot-2.2.24/src/auth/Makefile.in --- dovecot-2.2.22/src/auth/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -382,7 +382,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/auth/passdb-imap.c dovecot-2.2.24/src/auth/passdb-imap.c --- dovecot-2.2.22/src/auth/passdb-imap.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/passdb-imap.c 2016-04-26 13:01:20.000000000 +0000 @@ -79,7 +79,7 @@ string_t *str; set = module->set; - set.debug = auth_request->set->debug; + set.debug = auth_request->debug; set.dns_client_socket_path = t_strconcat(auth_request->set->base_dir, "/", DNS_CLIENT_SOCKET_NAME, NULL); diff -Nru dovecot-2.2.22/src/auth/passdb-passwd-file.c dovecot-2.2.24/src/auth/passdb-passwd-file.c --- dovecot-2.2.22/src/auth/passdb-passwd-file.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/passdb-passwd-file.c 2016-04-26 13:01:20.000000000 +0000 @@ -150,14 +150,6 @@ module->pwf = db_passwd_file_init(args, FALSE, global_auth_settings->debug); module->username_format = format; - - if (!module->pwf->vars) - module->module.default_cache_key = format; - else { - module->module.default_cache_key = auth_cache_parse_key(pool, - t_strconcat(format, module->pwf->path, NULL)); - } - module->module.default_pass_scheme = scheme; return &module->module; } diff -Nru dovecot-2.2.22/src/auth/userdb-passwd-file.c dovecot-2.2.24/src/auth/userdb-passwd-file.c --- dovecot-2.2.22/src/auth/userdb-passwd-file.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/userdb-passwd-file.c 2016-04-26 13:01:20.000000000 +0000 @@ -13,8 +13,6 @@ #include #include -#define PASSWD_FILE_CACHE_KEY "%u" - struct passwd_file_userdb_iterate_context { struct userdb_iterate_context ctx; struct istream *input; @@ -191,16 +189,6 @@ module->pwf = db_passwd_file_init(args, TRUE, global_auth_settings->debug); module->username_format = format; - - if (!module->pwf->vars) - module->module.default_cache_key = PASSWD_FILE_CACHE_KEY; - else { - module->module.default_cache_key = - auth_cache_parse_key(pool, - t_strconcat(PASSWD_FILE_CACHE_KEY, - module->pwf->path, - NULL)); - } return &module->module; } diff -Nru dovecot-2.2.22/src/auth/userdb-prefetch.c dovecot-2.2.24/src/auth/userdb-prefetch.c --- dovecot-2.2.22/src/auth/userdb-prefetch.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/auth/userdb-prefetch.c 2016-04-26 13:01:20.000000000 +0000 @@ -27,7 +27,7 @@ callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); return; } - if (!auth_request->userdb_lookup || auth_request->set->debug) { + if (!auth_request->userdb_lookup || auth_request->debug) { /* more userdbs, they may know the user */ auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "passdb didn't return userdb entries, " diff -Nru dovecot-2.2.22/src/config/all-settings.c dovecot-2.2.24/src/config/all-settings.c --- dovecot-2.2.22/src/config/all-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/all-settings.c 2016-04-26 14:30:50.000000000 +0000 @@ -158,7 +158,8 @@ IMAPC_FEATURE_NO_EXAMINE = 0x40, IMAPC_FEATURE_PROXYAUTH = 0x80, IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS = 0x100, - IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS = 0x200 + IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS = 0x200, + IMAPC_FEATURE_MODSEQ = 0x400 }; /* */ struct imapc_settings { @@ -342,6 +343,19 @@ unsigned int max_field_count; ARRAY(struct dict_sql_map) maps; }; +/* ../../src/lib-dict-extra/dict-ldap-settings.h */ +struct dict_ldap_settings { + const char *uri; + const char *bind_dn; + const char *password; + unsigned int timeout; + unsigned int max_idle_time; + unsigned int debug; + unsigned int max_attribute_count; + bool require_ssl; + bool start_tls; + ARRAY(struct dict_ldap_map) maps; +}; /* ../../src/lib-storage/mail-storage-settings.c */ extern const struct setting_parser_info mailbox_setting_parser_info; extern const struct setting_parser_info mail_namespace_setting_parser_info; @@ -972,6 +986,7 @@ { "proxyauth", IMAPC_FEATURE_PROXYAUTH }, { "fetch-msn-workarounds", IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS }, { "fetch-fix-broken-mails", IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS }, + { "modseq", IMAPC_FEATURE_MODSEQ }, { NULL, 0 } }; @@ -1149,7 +1164,7 @@ SETTING_DEFINE_LIST_END }; static const struct lda_settings lda_default_settings = { - .postmaster_address = "", + .postmaster_address = "postmaster@%d", .hostname = "", .submission_host = "", .sendmail_path = "/usr/sbin/sendmail", @@ -1185,6 +1200,13 @@ /* ../../src/lib-dict/dict-sql-settings.c */ #define DEF_STR(name) DEF_STRUCT_STR(name, dict_sql_map) #define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_sql_map) +/* ../../src/lib-dict-extra/dict-ldap-settings.c */ +#undef DEF_STR +#undef DEF_BOOL +#undef DEF_UINT +#define DEF_STR(name) DEF_STRUCT_STR(name, dict_ldap_map) +#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_ldap_map) +#define DEF_UINT(name) DEF_STRUCT_UINT(name ,dict_ldap_map) /* ../../src/stats/stats-settings.h */ extern const struct setting_parser_info stats_setting_parser_info; struct stats_settings { @@ -1397,6 +1419,7 @@ const char *libexec_dir; const char *mail_plugins; const char *mail_plugin_dir; + bool auth_debug; const char *auth_socket_path; const char *doveadm_socket_path; unsigned int doveadm_worker_count; @@ -1449,6 +1472,7 @@ bool deny; bool pass; /* deprecated, use result_success=continue instead */ bool master; + const char *auth_verbose; }; struct auth_userdb_settings { const char *name; @@ -1461,6 +1485,7 @@ const char *result_success; const char *result_failure; const char *result_internalfail; + const char *auth_verbose; }; struct auth_settings { const char *mechanisms; @@ -3496,6 +3521,7 @@ DEF(SET_STR, libexec_dir), DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), + DEF(SET_BOOL, auth_debug), DEF(SET_STR, auth_socket_path), DEF(SET_STR, doveadm_socket_path), DEF(SET_UINT, doveadm_worker_count), @@ -3520,6 +3546,7 @@ .libexec_dir = PKG_LIBEXECDIR, .mail_plugins = "", .mail_plugin_dir = MODULEDIR, + .auth_debug = FALSE, .auth_socket_path = "auth-userdb", .doveadm_socket_path = "doveadm-server", .doveadm_worker_count = 0, @@ -4078,6 +4105,7 @@ DEF(SET_BOOL, deny), DEF(SET_BOOL, pass), DEF(SET_BOOL, master), + DEF(SET_ENUM, auth_verbose), SETTING_DEFINE_LIST_END }; @@ -4095,7 +4123,8 @@ .deny = FALSE, .pass = FALSE, - .master = FALSE + .master = FALSE, + .auth_verbose = "default:yes:no" }; const struct setting_parser_info auth_passdb_setting_parser_info = { .defines = auth_passdb_setting_defines, @@ -4124,6 +4153,8 @@ DEF(SET_ENUM, result_failure), DEF(SET_ENUM, result_internalfail), + DEF(SET_ENUM, auth_verbose), + SETTING_DEFINE_LIST_END }; static const struct auth_userdb_settings auth_userdb_default_settings = { @@ -4137,7 +4168,9 @@ .skip = "never:found:notfound", .result_success = "return-ok:return:return-fail:continue:continue-ok:continue-fail", .result_failure = "continue:return:return-ok:return-fail:continue-ok:continue-fail", - .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail" + .result_internalfail = "continue:return:return-ok:return-fail:continue-ok:continue-fail", + + .auth_verbose = "default:yes:no" }; const struct setting_parser_info auth_userdb_setting_parser_info = { .defines = auth_userdb_setting_defines, @@ -4326,32 +4359,32 @@ const struct setting_parser_info *all_default_roots[] = { &master_service_setting_parser_info, &master_service_ssl_setting_parser_info, - &ssl_params_setting_parser_info, - &pop3c_setting_parser_info, - &replicator_setting_parser_info, - &maildir_setting_parser_info, - &dict_setting_parser_info, - &aggregator_setting_parser_info, - &imap_login_setting_parser_info, - &master_setting_parser_info, - &pop3_setting_parser_info, - &pop3_login_setting_parser_info, - &mbox_setting_parser_info, - &stats_setting_parser_info, &lmtp_setting_parser_info, &mail_user_setting_parser_info, &mdbox_setting_parser_info, - &imapc_setting_parser_info, - &imap_setting_parser_info, + &mbox_setting_parser_info, + &director_setting_parser_info, + &aggregator_setting_parser_info, + &imap_urlauth_setting_parser_info, + &ssl_params_setting_parser_info, &login_setting_parser_info, - &auth_setting_parser_info, - &mail_storage_setting_parser_info, + &imapc_setting_parser_info, + &pop3c_setting_parser_info, + &lda_setting_parser_info, &doveadm_setting_parser_info, + &imap_setting_parser_info, &imap_urlauth_login_setting_parser_info, - &imap_urlauth_setting_parser_info, - &lda_setting_parser_info, - &director_setting_parser_info, &imap_urlauth_worker_setting_parser_info, + &replicator_setting_parser_info, + &pop3_login_setting_parser_info, + &auth_setting_parser_info, + &mail_storage_setting_parser_info, + &maildir_setting_parser_info, + &imap_login_setting_parser_info, + &dict_setting_parser_info, + &master_setting_parser_info, + &stats_setting_parser_info, + &pop3_setting_parser_info, NULL }; const struct setting_parser_info *const *all_roots = all_default_roots; diff -Nru dovecot-2.2.22/src/config/config-parser.c dovecot-2.2.24/src/config/config-parser.c --- dovecot-2.2.22/src/config/config-parser.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/config-parser.c 2016-04-26 13:01:20.000000000 +0000 @@ -31,6 +31,8 @@ #define DNS_LOOKUP_TIMEOUT_SECS 30 #define DNS_LOOKUP_WARN_SECS 5 +ARRAY_DEFINE_TYPE(setting_parser_info_p, const struct setting_parser_info *); + static const enum settings_parser_flags settings_parser_flags = SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS | SETTINGS_PARSER_FLAG_TRACK_CHANGES; @@ -42,6 +44,9 @@ int (*hook_config_parser_end)(struct config_parser_context *ctx, const char **error_r); +static ARRAY_TYPE(service_settings) services_free_at_deinit = ARRAY_INIT; +static ARRAY_TYPE(setting_parser_info_p) roots_free_at_deinit = ARRAY_INIT; + static const char *info_type_name_find(const struct setting_parser_info *info) { unsigned int i; @@ -833,6 +838,31 @@ return 0; } +static void +config_parser_check_warnings(struct config_parser_context *ctx, const char *key) +{ + const char *path, *first_pos; + + first_pos = hash_table_lookup(ctx->seen_settings, str_c(ctx->str)); + if (ctx->cur_section->prev == NULL) { + /* changing a root setting. if we've already seen it inside + filters, log a warning. */ + if (first_pos == NULL) + return; + i_warning("%s line %u: Global setting %s won't change the setting inside an earlier filter at %s " + "(if this is intentional, avoid this warning by moving the global setting before %s)", + ctx->cur_input->path, ctx->cur_input->linenum, + key, first_pos, first_pos); + return; + } + if (first_pos != NULL) + return; + first_pos = p_strdup_printf(ctx->pool, "%s line %u", + ctx->cur_input->path, ctx->cur_input->linenum); + path = p_strdup(ctx->pool, str_c(ctx->str)); + hash_table_insert(ctx->seen_settings, path, first_pos); +} + void config_parser_apply_line(struct config_parser_context *ctx, enum config_line_type type, const char *key, const char *value) @@ -852,6 +882,7 @@ case CONFIG_LINE_TYPE_KEYFILE: case CONFIG_LINE_TYPE_KEYVARIABLE: str_append(ctx->str, key); + config_parser_check_warnings(ctx, key); str_append_c(ctx->str, '='); if (config_write_value(ctx, type, key, value) < 0) @@ -949,6 +980,7 @@ ctx.cur_input = &root; ctx.expand_values = expand_values; ctx.modules = modules; + hash_table_create(&ctx.seen_settings, ctx.pool, 0, str_hash, strcmp); p_array_init(&ctx.all_parsers, ctx.pool, 128); ctx.cur_section = p_new(ctx.pool, struct config_section_stack, 1); @@ -996,6 +1028,7 @@ if (line == NULL && ctx.cur_input != NULL) goto prevfile; + hash_table_destroy(&ctx.seen_settings); str_free(&full_line); if (ret == 0) ret = config_parse_finish(&ctx, error_r); @@ -1007,7 +1040,7 @@ struct module_dir_load_settings mod_set; struct module *m; const struct setting_parser_info **roots; - ARRAY(const struct setting_parser_info *) new_roots; + ARRAY_TYPE(setting_parser_info_p) new_roots; ARRAY_TYPE(service_settings) new_services; struct service_settings *const *services, *service_set; unsigned int i, count; @@ -1046,6 +1079,9 @@ array_append(&new_roots, &all_roots[i], 1); array_append_zero(&new_roots); all_roots = array_idx(&new_roots, 0); + roots_free_at_deinit = new_roots; + } else { + array_free(&new_roots); } if (array_count(&new_services) > 0) { /* module added new services. update the defaults. */ @@ -1053,6 +1089,9 @@ for (i = 0; i < count; i++) array_append(&new_services, &services[i], 1); *default_services = new_services; + services_free_at_deinit = new_services; + } else { + array_free(&new_services); } } @@ -1102,3 +1141,11 @@ } return FALSE; } + +void config_parser_deinit(void) +{ + if (array_is_created(&services_free_at_deinit)) + array_free(&services_free_at_deinit); + if (array_is_created(&roots_free_at_deinit)) + array_free(&roots_free_at_deinit); +} diff -Nru dovecot-2.2.22/src/config/config-parser.h dovecot-2.2.24/src/config/config-parser.h --- dovecot-2.2.22/src/config/config-parser.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/config-parser.h 2016-04-26 13:01:20.000000000 +0000 @@ -28,5 +28,6 @@ const char *const *modules, const struct setting_parser_info *root) ATTR_NULL(2); +void config_parser_deinit(void); #endif diff -Nru dovecot-2.2.22/src/config/config-parser-private.h dovecot-2.2.24/src/config/config-parser-private.h --- dovecot-2.2.22/src/config/config-parser-private.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/config-parser-private.h 2016-04-26 13:01:20.000000000 +0000 @@ -54,6 +54,7 @@ struct old_set_parser *old; + HASH_TABLE(const char *, const char *) seen_settings; struct config_filter_context *filter; unsigned int expand_values:1; unsigned int hide_errors:1; diff -Nru dovecot-2.2.22/src/config/doveconf.c dovecot-2.2.24/src/config/doveconf.c --- dovecot-2.2.22/src/config/doveconf.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/doveconf.c 2016-04-26 13:01:20.000000000 +0000 @@ -881,6 +881,7 @@ config_filter_deinit(&config_filter); module_dir_unload(&modules); + config_parser_deinit(); master_service_deinit(&master_service); return 0; } diff -Nru dovecot-2.2.22/src/config/main.c dovecot-2.2.24/src/config/main.c --- dovecot-2.2.22/src/config/main.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/main.c 2016-04-26 13:01:20.000000000 +0000 @@ -42,6 +42,7 @@ config_filter_deinit(&config_filter); module_dir_unload(&modules); + config_parser_deinit(); master_service_deinit(&master_service); return 0; } diff -Nru dovecot-2.2.22/src/config/Makefile.in dovecot-2.2.24/src/config/Makefile.in --- dovecot-2.2.22/src/config/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/config/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -266,7 +266,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/dict/Makefile.in dovecot-2.2.24/src/dict/Makefile.in --- dovecot-2.2.22/src/dict/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/dict/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -237,7 +237,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/director/director.c dovecot-2.2.24/src/director/director.c --- dovecot-2.2.22/src/director/director.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/director/director.c 2016-04-26 13:01:20.000000000 +0000 @@ -325,6 +325,9 @@ { string_t *str; + if (host == dir->self_host) + dir->last_sync_sent_ring_change_counter = dir->ring_change_counter; + str = t_str_new(128); str_printfa(str, "SYNC\t%s\t%u\t%u", net_ip2addr(&host->ip), host->port, seq); @@ -450,6 +453,7 @@ { const char *cmd; + added_host->dir->ring_change_counter++; cmd = t_strdup_printf("DIRECTOR\t%s\t%u\n", net_ip2addr(&added_host->ip), added_host->port); director_update_send(added_host->dir, src, cmd); @@ -724,6 +728,8 @@ static void director_finish_user_kill(struct director *dir, struct user *user, bool self) { + i_assert(user->kill_state != USER_KILL_STATE_DELAY); + if (dir->right == NULL) { /* we're alone */ director_user_kill_finish_delayed(dir, user); @@ -744,8 +750,12 @@ struct director_kill_context *ctx = context; struct user *user; + /* this is an asynchronous notification about user being killed. + there are no guarantees about what might have happened to the user + in the mean time. */ switch (state) { case IPC_CLIENT_CMD_STATE_REPLY: + /* shouldn't get here. the command reply isn't finished yet. */ return; case IPC_CLIENT_CMD_STATE_OK: break; @@ -757,14 +767,22 @@ } user = user_directory_lookup(ctx->dir->users, ctx->username_hash); - if (user == NULL || user->kill_state == USER_KILL_STATE_NONE) - return; - - director_finish_user_kill(ctx->dir, user, ctx->self); + if (user == NULL) { + /* user was already freed - ignore */ + } else if (user->kill_state == USER_KILL_STATE_KILLING || + user->kill_state == USER_KILL_STATE_KILLING_NOTIFY_RECEIVED) { + /* we were still waiting for the kill notification */ + director_finish_user_kill(ctx->dir, user, ctx->self); + } else { + /* we don't currently want to kill the user */ + } + i_free(ctx); } static void director_user_move_timeout(struct user *user) { + i_assert(user->kill_state != USER_KILL_STATE_DELAY); + i_error("Finishing user %u move timed out, " "its state may now be inconsistent", user->username_hash); diff -Nru dovecot-2.2.22/src/director/director-connection.c dovecot-2.2.24/src/director/director-connection.c --- dovecot-2.2.22/src/director/director-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/director/director-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -824,9 +824,16 @@ return TRUE; } - if (ret == 0) - ; - else if (dir_host == conn->dir->self_host) { + if (ret == 0) { + /* First time we're seeing this - forward it to others also. + We'll want to do it even if the user was already marked as + weak, because otherwise if two directors mark the user weak + at the same time both the USER-WEAK notifications reach + only half the directors until they collide and neither one + finishes going through the whole ring marking the user + non-weak. */ + weak_forward = TRUE; + } else if (dir_host == conn->dir->self_host) { /* We originated this USER-WEAK request. The entire ring has seen it and there weren't any conflicts. Make the user non-weak. */ dir_debug("user refresh: %u Our USER-WEAK seen by the entire ring", @@ -1437,7 +1444,14 @@ return TRUE; } + /* If directors got disconnected while we were waiting a SYNC reply, + it might have gotten lost. If we've received a DIRECTOR update since + the last time we sent a SYNC, retry sending it here to make sure + it doesn't get stuck. We don't want to do this too eagerly because + it may trigger desynced_hosts_hash != hosts_hash mismatch, which + causes unnecessary error logging and hosts-resending. */ if ((host == NULL || !host->self) && + dir->last_sync_sent_ring_change_counter != dir->ring_change_counter && (time_t)dir->self_host->last_sync_timestamp != ioloop_time) (void)director_resend_sync(dir); return TRUE; @@ -1458,8 +1472,6 @@ } host = director_host_get(conn->dir, &ip, port); - /* reset failure timestamp so we'll actually try to connect there. */ - host->last_network_failure = 0; /* remote suggests us to connect elsewhere */ if (dir->right != NULL && @@ -1471,6 +1483,11 @@ return TRUE; } + /* reset failure timestamp so we'll actually try to connect there. */ + host->last_network_failure = 0; + /* reset removed-flag, so we don't crash */ + host->removed = FALSE; + if (dir->right == NULL) { dir_debug("Received CONNECT request to %s, " "initializing right", host->name); diff -Nru dovecot-2.2.22/src/director/director.h dovecot-2.2.24/src/director/director.h --- dovecot-2.2.22/src/director/director.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/director/director.h 2016-04-26 13:01:20.000000000 +0000 @@ -77,6 +77,8 @@ struct ipc_client *ipc_proxy; unsigned int sync_seq; + unsigned int ring_change_counter; + unsigned int last_sync_sent_ring_change_counter; /* the lowest minor version supported by the ring */ unsigned int ring_min_version; time_t ring_last_sync_time; diff -Nru dovecot-2.2.22/src/director/Makefile.in dovecot-2.2.24/src/director/Makefile.in --- dovecot-2.2.22/src/director/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/director/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -244,7 +244,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/director/user-directory.c dovecot-2.2.24/src/director/user-directory.c --- dovecot-2.2.22/src/director/user-directory.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/director/user-directory.c 2016-04-26 13:01:20.000000000 +0000 @@ -54,6 +54,11 @@ i_assert(user->host->user_count > 0); user->host->user_count--; + if (user->to_move != NULL) { + /* director_user_expire is very short. user expired before + moving the user finished or timed out. */ + timeout_remove(&user->to_move); + } user_move_iters(dir, user); hash_table_remove(dir->hash, POINTER_CAST(user->username_hash)); diff -Nru dovecot-2.2.22/src/dns/Makefile.in dovecot-2.2.24/src/dns/Makefile.in --- dovecot-2.2.22/src/dns/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/dns/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -229,7 +229,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/doveadm/client-connection.c dovecot-2.2.24/src/doveadm/client-connection.c --- dovecot-2.2.22/src/doveadm/client-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/client-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -68,7 +68,7 @@ static void doveadm_cmd_server_run_ver2(struct client_connection *conn, - int argc, const char **argv, + int argc, const char *const argv[], struct doveadm_cmd_context *cctx) { i_getopt_reset(); @@ -80,7 +80,7 @@ static void doveadm_cmd_server_run(struct client_connection *conn, - int argc, const char **argv, + int argc, const char *const argv[], const struct doveadm_cmd *cmd) { i_getopt_reset(); @@ -92,7 +92,7 @@ static int doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, const struct doveadm_settings *set, - int argc, const char **argv, + int argc, const char *const argv[], struct doveadm_cmd_context *cctx, struct doveadm_mail_cmd_context **mctx_r) { @@ -104,7 +104,7 @@ mctx = doveadm_mail_cmd_init(cmd, set); mctx->full_args = argv+1; mctx->proxying = TRUE; - + mctx->cur_username = cctx->username; mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; @@ -149,6 +149,13 @@ } mctx->args = argv+optind; + if (mctx->cur_username != NULL) { + if (strchr(mctx->cur_username, '*') != NULL || + strchr(mctx->cur_username, '?') != NULL) { + add_username_header = TRUE; + } + } + if (doveadm_print_is_initialized() && add_username_header) { doveadm_print_header("username", "Username", DOVEADM_PRINT_HEADER_FLAG_STICKY | @@ -218,7 +225,7 @@ static int doveadm_cmd_handle(struct client_connection *conn, const char *cmd_name, - int argc, const char **argv, + int argc, const char *const argv[], struct doveadm_cmd_context *cctx) { struct ioloop *ioloop, *prev_ioloop = current_ioloop; @@ -227,7 +234,7 @@ struct doveadm_mail_cmd_context *mctx; const struct doveadm_cmd_ver2 *cmd_ver2; - if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, argc, argv)) == NULL) { + if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv)) == NULL) { mail_cmd = doveadm_mail_cmd_find(cmd_name); if (mail_cmd == NULL) { cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv); diff -Nru dovecot-2.2.22/src/doveadm/client-connection-http.c dovecot-2.2.24/src/doveadm/client-connection-http.c --- dovecot-2.2.22/src/doveadm/client-connection-http.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/client-connection-http.c 2016-04-26 13:01:20.000000000 +0000 @@ -651,13 +651,13 @@ char *value = p_strdup_printf(conn->client.pool, "doveadm:%s", conn->client.set->doveadm_password); base64_encode(value, strlen(value), b64_value); if (strcmp(creds.data, str_c(b64_value)) == 0) auth = TRUE; - else i_error("Invalid authencition attempt to HTTP API"); + else i_error("Invalid authentication attempt to HTTP API"); } - else if (strcasecmp(creds.scheme, "X-Doveadm-API") == 0 && doveadm_settings->doveadm_api_key[0] != '\0') { + else if (strcasecmp(creds.scheme, "X-Dovecot-API") == 0 && doveadm_settings->doveadm_api_key[0] != '\0') { string_t *b64_value = str_new(conn->client.pool, 32); base64_encode(doveadm_settings->doveadm_api_key, strlen(doveadm_settings->doveadm_api_key), b64_value); if (strcmp(creds.data, str_c(b64_value)) == 0) auth = TRUE; - else i_error("Invalid authencition attempt to HTTP API"); + else i_error("Invalid authentication attempt to HTTP API"); } else i_error("Unsupported authentication scheme to HTTP API"); } @@ -665,7 +665,7 @@ conn->http_response = http_server_response_create(conn->http_server_request, 401, "Authentication required"); if (doveadm_settings->doveadm_api_key[0] != '\0') http_server_response_add_header(conn->http_response, - "WWW-Authenticate", "X-Dovecot-API Realm=\"doveadm\"" + "WWW-Authenticate", "X-Dovecot-API" ); if (*conn->client.set->doveadm_password != '\0') http_server_response_add_header(conn->http_response, diff -Nru dovecot-2.2.22/src/doveadm/doveadm-auth.c dovecot-2.2.24/src/doveadm/doveadm-auth.c --- dovecot-2.2.22/src/doveadm/doveadm-auth.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-auth.c 2016-04-26 13:01:20.000000000 +0000 @@ -7,6 +7,7 @@ #include "base64.h" #include "hex-binary.h" #include "str.h" +#include "var-expand.h" #include "wildcard-match.h" #include "settings-parser.h" #include "master-service.h" @@ -176,6 +177,8 @@ info.remote_ip = input->info.remote_ip; info.remote_port = input->info.remote_port; info.initial_resp_base64 = str_c(base64_resp); + if (doveadm_settings->auth_debug) + info.flags |= AUTH_REQUEST_FLAG_DEBUG; input->request = auth_client_request_new(client, &info, auth_callback, input); @@ -280,15 +283,20 @@ auth_master_deinit(&conn); } +static void authtest_input_init(struct authtest_input *input) +{ + memset(input, 0, sizeof(*input)); + input->info.service = "doveadm"; + input->info.debug = doveadm_settings->auth_debug; +} + static void cmd_auth_test(int argc, char *argv[]) { const char *auth_socket_path = NULL; struct authtest_input input; int c; - memset(&input, 0, sizeof(input)); - input.info.service = "doveadm"; - + authtest_input_init(&input); while ((c = getopt(argc, argv, "a:M:x:")) > 0) { switch (c) { case 'a': @@ -374,9 +382,7 @@ struct authtest_input input; int c; - memset(&input, 0, sizeof(input)); - input.info.service = "doveadm"; - + authtest_input_init(&input); auth_login_socket_path = t_strconcat(doveadm_settings->base_dir, "/auth-login", NULL); auth_master_socket_path = t_strconcat(doveadm_settings->base_dir, @@ -433,9 +439,7 @@ bool first = TRUE; int c, ret; - memset(&input, 0, sizeof(input)); - input.info.service = "doveadm"; - + authtest_input_init(&input); while ((c = getopt(argc, argv, "a:f:x:")) > 0) { switch (c) { case 'a': @@ -486,16 +490,52 @@ } } -static int cmd_user_mail_input(struct mail_storage_service_ctx *storage_service, - const struct authtest_input *input, - const char *show_field) +static void +cmd_user_mail_print_fields(const struct authtest_input *input, + struct mail_user *user, + const char *const *userdb_fields, + const char *show_field) +{ + const struct mail_storage_settings *mail_set; + const char *key, *value; + unsigned int i; + + if (strcmp(input->username, user->username) != 0) + cmd_user_mail_input_field("user", user->username, show_field); + cmd_user_mail_input_field("uid", user->set->mail_uid, show_field); + cmd_user_mail_input_field("gid", user->set->mail_gid, show_field); + cmd_user_mail_input_field("home", user->set->mail_home, show_field); + + mail_set = mail_user_set_get_storage_set(user); + cmd_user_mail_input_field("mail", mail_set->mail_location, show_field); + + if (userdb_fields != NULL) { + for (i = 0; userdb_fields[i] != NULL; i++) { + value = strchr(userdb_fields[i], '='); + if (value != NULL) + key = t_strdup_until(userdb_fields[i], value++); + else { + key = userdb_fields[i]; + value = ""; + } + if (strcmp(key, "uid") != 0 && + strcmp(key, "gid") != 0 && + strcmp(key, "home") != 0 && + strcmp(key, "mail") != 0) + cmd_user_mail_input_field(key, value, show_field); + } + } +} + +static int +cmd_user_mail_input(struct mail_storage_service_ctx *storage_service, + const struct authtest_input *input, + const char *show_field, const char *expand_field) { struct mail_storage_service_input service_input; struct mail_storage_service_user *service_user; struct mail_user *user; - const struct mail_storage_settings *mail_set; - const char *key, *value, *error, *const *userdb_fields; - unsigned int i; + const char *error, *const *userdb_fields; pool_t pool; int ret; @@ -507,6 +547,7 @@ service_input.local_port = input->info.local_port; service_input.remote_ip = input->info.remote_ip; service_input.remote_port = input->info.remote_port; + service_input.debug = input->info.debug; pool = pool_alloconly_create("userdb fields", 1024); mail_storage_service_save_userdb_fields(storage_service, pool, @@ -518,36 +559,20 @@ pool_unref(&pool); if (ret < 0) return -1; - fprintf(show_field == NULL ? stdout : stderr, + fprintf(show_field == NULL && expand_field == NULL ? stdout : stderr, "userdb lookup: user %s doesn't exist\n", input->username); return 0; } - if (strcmp(input->username, user->username) != 0) - cmd_user_mail_input_field("user", user->username, show_field); - cmd_user_mail_input_field("uid", user->set->mail_uid, show_field); - cmd_user_mail_input_field("gid", user->set->mail_gid, show_field); - cmd_user_mail_input_field("home", user->set->mail_home, show_field); - - mail_set = mail_user_set_get_storage_set(user); - cmd_user_mail_input_field("mail", mail_set->mail_location, show_field); - - if (userdb_fields != NULL) { - for (i = 0; userdb_fields[i] != NULL; i++) { - value = strchr(userdb_fields[i], '='); - if (value != NULL) - key = t_strdup_until(userdb_fields[i], value++); - else { - key = userdb_fields[i]; - value = ""; - } - if (strcmp(key, "uid") != 0 && - strcmp(key, "gid") != 0 && - strcmp(key, "home") != 0 && - strcmp(key, "mail") != 0) - cmd_user_mail_input_field(key, value, show_field); - } + if (expand_field == NULL) + cmd_user_mail_print_fields(input, user, userdb_fields, show_field); + else { + string_t *str = t_str_new(128); + var_expand_with_funcs(str, expand_field, + mail_user_var_expand_table(user), + mail_user_var_expand_func_table, user); + printf("%s\n", str_c(str)); } mail_user_unref(&user); @@ -561,20 +586,21 @@ const char *auth_socket_path = doveadm_settings->auth_socket_path; struct auth_master_connection *conn; struct authtest_input input; - const char *show_field = NULL; + const char *show_field = NULL, *expand_field = NULL; struct mail_storage_service_ctx *storage_service = NULL; unsigned int i; bool have_wildcards, userdb_only = FALSE, first = TRUE; int c, ret; - memset(&input, 0, sizeof(input)); - input.info.service = "doveadm"; - - while ((c = getopt(argc, argv, "a:f:ux:")) > 0) { + authtest_input_init(&input); + while ((c = getopt(argc, argv, "a:e:f:ux:")) > 0) { switch (c) { case 'a': auth_socket_path = optarg; break; + case 'e': + expand_field = optarg; + break; case 'f': show_field = optarg; break; @@ -589,6 +615,17 @@ } } + if (expand_field != NULL && userdb_only) { + i_error("-e can't be used with -u"); + doveadm_exit_code = EX_USAGE; + return; + } + if (expand_field != NULL && show_field != NULL) { + i_error("-e can't be used with -f"); + doveadm_exit_code = EX_USAGE; + return; + } + if (optind == argc) auth_cmd_help(cmd_user); @@ -619,7 +656,7 @@ MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS); mail_storage_service_set_auth_conn(storage_service, conn); conn = NULL; - if (show_field == NULL) { + if (show_field == NULL && expand_field == NULL) { doveadm_print_init(DOVEADM_PRINT_TYPE_TAB); doveadm_print_header_simple("field"); doveadm_print_header_simple("value"); @@ -633,7 +670,7 @@ putchar('\n'); ret = !userdb_only ? - cmd_user_mail_input(storage_service, &input, show_field) : + cmd_user_mail_input(storage_service, &input, show_field, expand_field) : cmd_user_input(conn, &input, show_field, TRUE); switch (ret) { case -1: @@ -660,7 +697,7 @@ { cmd_auth_cache_flush, "auth cache flush", "[-a ] [ [...]]" }, { cmd_user, "user", - "[-a ] [-x ] [-f field] [-u] [...]" } + "[-a ] [-x ] [-f field] [-e ] [-u] [...]" } }; static void auth_cmd_help(doveadm_command_t *cmd) diff -Nru dovecot-2.2.22/src/doveadm/doveadm.c dovecot-2.2.24/src/doveadm/doveadm.c --- dovecot-2.2.22/src/doveadm/doveadm.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm.c 2016-04-26 13:01:20.000000000 +0000 @@ -210,7 +210,8 @@ i_fatal("execv(%s) failed: %m", argv[0]); } -static bool doveadm_try_run(const char *cmd_name, int argc, const char *argv[]) +static bool doveadm_try_run(const char *cmd_name, int argc, + const char *const argv[]) { const struct doveadm_cmd *cmd; @@ -368,6 +369,10 @@ i_set_debug_file("/dev/null"); } + /* this has to be done here because proctitle hack can break + the env pointer */ + cctx.username = getenv("USER"); + if (!doveadm_cmd_try_run_ver2(cmd_name, argc, (const char**)argv, &cctx) && !doveadm_try_run(cmd_name, argc, (const char **)argv) && !doveadm_mail_try_run(cmd_name, argc, argv)) { diff -Nru dovecot-2.2.22/src/doveadm/doveadm-cmd.c dovecot-2.2.24/src/doveadm/doveadm-cmd.c --- dovecot-2.2.22/src/doveadm/doveadm-cmd.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-cmd.c 2016-04-26 13:01:20.000000000 +0000 @@ -61,45 +61,53 @@ } const struct doveadm_cmd_ver2 * -doveadm_cmd_find_with_args_ver2(const char *cmd_name, int argc, const char *const argv[]) +doveadm_cmd_find_with_args_ver2(const char *cmd_name, int *argc, + const char *const *argv[]) { - int i; + int i, k; const struct doveadm_cmd_ver2 *cmd; const char *cptr; - for(i=0;iname; /* cannot reuse i here because this needs be done more than once */ - for(int k=0; *cptr != '\0' && i+k < argc; k++) { - size_t alen = strlen(argv[i+k]); + for (k=0; *cptr != '\0' && i+k < *argc; k++) { + size_t alen = strlen((*argv)[i+k]); /* make sure we don't overstep */ if (strlen(cptr) < alen) break; /* did not match */ - if (strncmp(cptr, argv[i+k], alen) != 0) break; + if (strncmp(cptr, (*argv)[i+k], alen) != 0) break; /* do not accept abbreviations */ if (cptr[alen] != ' ' && cptr[alen] != '\0') break; cptr += alen; if (*cptr != '\0') cptr++; /* consume space */ } /* name was fully consumed */ - if (*cptr == '\0') return cmd; + if (*cptr == '\0') { + if (k > 1) { + *argc -= k-1; + *argv += k-1; + } + return cmd; + } } return NULL; } static bool -doveadm_cmd_find_multi_word(const char *cmdname, int *_argc, const char **_argv[]) +doveadm_cmd_find_multi_word(const char *cmdname, int *_argc, + const char *const *_argv[]) { int argc = *_argc; - const char **argv = *_argv; + const char *const *argv = *_argv; unsigned int len; if (argc < 2) @@ -126,7 +134,8 @@ } const struct doveadm_cmd * -doveadm_cmd_find_with_args(const char *cmd_name, int *argc, const char **argv[]) +doveadm_cmd_find_with_args(const char *cmd_name, int *argc, + const char *const *argv[]) { const struct doveadm_cmd *cmd; unsigned int cmd_name_len; @@ -425,12 +434,12 @@ } bool doveadm_cmd_try_run_ver2(const char *cmd_name, - int argc, const char **argv, + int argc, const char *const argv[], struct doveadm_cmd_context *cctx) { const struct doveadm_cmd_ver2 *cmd; - cmd = doveadm_cmd_find_with_args_ver2(cmd_name, argc, argv); + cmd = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv); if (cmd == NULL) return FALSE; @@ -440,13 +449,12 @@ return TRUE; } -int doveadm_cmd_run_ver2(int argc, const char **argv, +int doveadm_cmd_run_ver2(int argc, const char *const argv[], struct doveadm_cmd_context *cctx) { struct doveadm_cmd_param *param; ARRAY_TYPE(doveadm_cmd_param_arr_t) pargv; ARRAY_TYPE(getopt_option_array) opts; - const char *cptr; unsigned int pargc; int c,li; pool_t pool = pool_datastack_create(); @@ -490,9 +498,6 @@ } } - cptr = cctx->cmd->name; - while((cptr = strchr(cptr+1, ' ')) != NULL) optind++; - /* process positional arguments */ for(;optindno_mailbox_renames) brain_flags |= DSYNC_BRAIN_FLAG_NO_MAILBOX_RENAMES; - if (ctx->reverse_backup) - brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV; - else if (ctx->backup) - brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND; + if (ctx->backup) { + if (ctx->reverse_backup) + brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV; + else + brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND; + } if (ctx->no_mail_sync) brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC; diff -Nru dovecot-2.2.22/src/doveadm/doveadm-mail-batch.c dovecot-2.2.24/src/doveadm/doveadm-mail-batch.c --- dovecot-2.2.22/src/doveadm/doveadm-mail-batch.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-mail-batch.c 2016-04-26 13:01:20.000000000 +0000 @@ -60,7 +60,7 @@ const char *getopt_args; int c; - cmd_ver2 = doveadm_cmd_find_with_args_ver2(argv[0], argc, argv); + cmd_ver2 = doveadm_cmd_find_with_args_ver2(argv[0], &argc, &argv); if (cmd_ver2 == NULL) cmd = doveadm_mail_cmd_find_from_argv(argv[0], &argc, &argv); @@ -72,10 +72,8 @@ cmd = &tmpcmd; } - if (cmd == NULL) { - i_fatal_status(EX_USAGE, "doveadm batch: Unknown subcommand %s", - argv[1]); - } + if (cmd == NULL) + i_fatal_status(EX_USAGE, "doveadm batch: '%s' mail command doesn't exist", argv[0]); subctx = doveadm_mail_cmd_init(cmd, doveadm_settings); subctx->full_args = argv + 1; diff -Nru dovecot-2.2.22/src/doveadm/doveadm-mail.c dovecot-2.2.24/src/doveadm/doveadm-mail.c --- dovecot-2.2.22/src/doveadm/doveadm-mail.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-mail.c 2016-04-26 13:01:20.000000000 +0000 @@ -433,18 +433,16 @@ static void doveadm_mail_all_users(struct doveadm_mail_cmd_context *ctx, + struct doveadm_cmd_context *cctx, const char *wildcard_user) { - struct doveadm_cmd_context cctx; unsigned int user_idx; const char *ip, *user, *error; int ret; ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; - memset(&cctx, 0, sizeof(cctx)); - - doveadm_cctx_to_storage_service_input(&cctx, &ctx->storage_service_input); + doveadm_cctx_to_storage_service_input(cctx, &ctx->storage_service_input); ctx->storage_service = mail_storage_service_init(master_service, NULL, ctx->service_flags); lib_signals_set_handler(SIGINT, 0, sig_die, NULL); @@ -452,7 +450,8 @@ ctx->v.init(ctx, ctx->args); - mail_storage_service_all_init(ctx->storage_service); + mail_storage_service_all_init_mask(ctx->storage_service, + wildcard_user != NULL ? wildcard_user : ""); if (hook_doveadm_mail_init != NULL) hook_doveadm_mail_init(ctx); @@ -463,11 +462,11 @@ if (!wildcard_match_icase(user, wildcard_user)) continue; } - cctx.username = user; + cctx->username = user; ctx->cur_username = user; doveadm_print_sticky("username", user); T_BEGIN { - ret = doveadm_mail_next_user(ctx, &cctx, &error); + ret = doveadm_mail_next_user(ctx, cctx, &error); if (ret < 0) i_error("%s", error); else if (ret == 0) @@ -557,12 +556,12 @@ ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; if (doveadm_debug) ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; - ctx->cur_username = getenv("USER"); return ctx; } static void doveadm_mail_cmd_exec(struct doveadm_mail_cmd_context *ctx, + struct doveadm_cmd_context *cctx, const char *wildcard_user) { int ret; @@ -580,8 +579,6 @@ } if (ctx->iterate_single_user) { - struct doveadm_cmd_context cctx; - if (ctx->cur_username == NULL) i_fatal_status(EX_USAGE, "USER environment is missing and -u option not used"); if (!ctx->cli) { @@ -589,9 +586,7 @@ ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; } - memset(&cctx, 0, sizeof(cctx)); - cctx.username = ctx->cur_username; - ret = doveadm_mail_single_user(ctx, &cctx, &error); + ret = doveadm_mail_single_user(ctx, cctx, &error); if (ret < 0) { /* user lookup/init failed somehow */ doveadm_exit_code = EX_TEMPFAIL; @@ -602,7 +597,7 @@ } } else { ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; - doveadm_mail_all_users(ctx, wildcard_user); + doveadm_mail_all_users(ctx, cctx, wildcard_user); } if (ctx->search_args != NULL) mail_search_args_unref(&ctx->search_args); @@ -629,6 +624,7 @@ static void doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[]) { + struct doveadm_cmd_context cctx; struct doveadm_mail_cmd_context *ctx; const char *getopt_args, *wildcard_user; int c; @@ -636,6 +632,9 @@ ctx = doveadm_mail_cmdline_init(cmd); ctx->full_args = (const void *)(argv + 1); ctx->cli = TRUE; + ctx->cur_username = getenv("USER"); + + memset(&cctx, 0, sizeof(cctx)); getopt_args = "AF:S:u:"; /* keep context's getopt_args first in case it contains '+' */ @@ -683,7 +682,8 @@ cmd->name, argv[0]); } ctx->args = (const void *)argv; - doveadm_mail_cmd_exec(ctx, wildcard_user); + cctx.username = ctx->cur_username; + doveadm_mail_cmd_exec(ctx, &cctx, wildcard_user); doveadm_mail_cmd_free(ctx); } @@ -923,8 +923,9 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) { struct doveadm_mail_cmd_context *mctx; - const char *wildcard_user; + const char *wildcard_user, *username_args[3] = { NULL, NULL, NULL }; const char *fieldstr; + unsigned int username_args_count; ARRAY_TYPE(const_string) pargv; int i; @@ -932,8 +933,14 @@ cctx->cmd->mail_cmd, cctx->cmd->name, cctx->cmd->usage }; - mctx = doveadm_mail_cmdline_init(&mail_cmd); - + if (!cctx->cli) { + mctx = doveadm_mail_cmd_init(&mail_cmd, doveadm_settings); + /* doveadm-server always does userdb lookups */ + mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + } else { + mctx = doveadm_mail_cmdline_init(&mail_cmd); + } + mctx->cur_username = cctx->username; mctx->iterate_all_users = FALSE; wildcard_user = NULL; p_array_init(&pargv, mctx->pool, 8); @@ -946,6 +953,7 @@ if (strcmp(arg->name, "all-users") == 0) { mctx->iterate_all_users = arg->value.v_bool; + username_args[0] = "-A"; } else if (strcmp(arg->name, "socket-path") == 0) { doveadm_settings->doveadm_socket_path = arg->value.v_string; if (doveadm_settings->doveadm_worker_count == 0) @@ -953,15 +961,21 @@ } else if (strcmp(arg->name, "user") == 0) { mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; mctx->cur_username = arg->value.v_string; + username_args[0] = "-u"; + username_args[1] = arg->value.v_string; if (strchr(mctx->cur_username, '*') != NULL || strchr(mctx->cur_username, '?') != NULL) { wildcard_user = mctx->cur_username; mctx->cur_username = NULL; + } else { + cctx->username = mctx->cur_username; } } else if (strcmp(arg->name, "user-file") == 0) { mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; wildcard_user = "*"; mctx->users_list_input = arg->value.v_istream; + username_args[0] = "-F"; + username_args[1] = ""; /* value doesn't really matter */ i_stream_ref(mctx->users_list_input); } else if (strcmp(arg->name, "field") == 0 || strcmp(arg->name, "flag") == 0) { @@ -1003,10 +1017,16 @@ } array_append_zero(&pargv); - mctx->args = array_idx(&pargv, 0); - mctx->full_args = mctx->args; + /* -A, -u and -F parameters need to be included in full_args so that + they're sent to doveadm-server. This is needed so that + doveadm-server returns the username header when needed. */ + username_args_count = str_array_length(username_args); + if (username_args_count > 0) + array_insert(&pargv, 0, username_args, username_args_count); + mctx->args = array_idx(&pargv, username_args_count); + mctx->full_args = array_idx(&pargv, 0); mctx->cli = cctx->cli; - doveadm_mail_cmd_exec(mctx, wildcard_user); + doveadm_mail_cmd_exec(mctx, cctx, wildcard_user); doveadm_mail_cmd_free(mctx); } diff -Nru dovecot-2.2.22/src/doveadm/doveadm-proxy.c dovecot-2.2.24/src/doveadm/doveadm-proxy.c --- dovecot-2.2.22/src/doveadm/doveadm-proxy.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-proxy.c 2016-04-26 13:01:20.000000000 +0000 @@ -13,7 +13,7 @@ struct ipc_client *ipc; }; -extern struct doveadm_cmd doveadm_cmd_proxy[]; +extern struct doveadm_cmd_ver2 doveadm_cmd_proxy[]; static void proxy_cmd_help(doveadm_command_t *cmd) ATTR_NORETURN; @@ -89,10 +89,11 @@ case IPC_CLIENT_CMD_STATE_REPLY: return; case IPC_CLIENT_CMD_STATE_OK: - printf("%s connections kicked\n", data); + doveadm_print(data); break; case IPC_CLIENT_CMD_STATE_ERROR: i_error("KICK failed: %s", data); + doveadm_exit_code = EX_TEMPFAIL; break; } io_loop_stop(current_ioloop); @@ -109,17 +110,33 @@ return; } + doveadm_print_init(DOVEADM_PRINT_TYPE_FORMATTED); + doveadm_print_formatted_set_format("{count} connections kicked"); + doveadm_print_header_simple("count"); ipc_client_cmd(ctx->ipc, t_strdup_printf("proxy\t*\tKICK\t%s", argv[optind]), cmd_proxy_kick_callback, NULL); io_loop_run(current_ioloop); ipc_client_deinit(&ctx->ipc); } -struct doveadm_cmd doveadm_cmd_proxy[] = { - { cmd_proxy_list, "proxy list", - "[-a ]" }, - { cmd_proxy_kick, "proxy kick", - "[-a ] " } +struct doveadm_cmd_ver2 doveadm_cmd_proxy[] = { +{ + .name = "proxy list", + .usage = "[-a ]", + .old_cmd = cmd_proxy_list, +DOVEADM_CMD_PARAMS_START +DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0) +DOVEADM_CMD_PARAMS_END +}, +{ + .name = "proxy kick", + .usage = "[-a ] ", + .old_cmd = cmd_proxy_kick, +DOVEADM_CMD_PARAMS_START +DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0) +DOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL) +DOVEADM_CMD_PARAMS_END +} }; static void proxy_cmd_help(doveadm_command_t *cmd) @@ -127,8 +144,8 @@ unsigned int i; for (i = 0; i < N_ELEMENTS(doveadm_cmd_proxy); i++) { - if (doveadm_cmd_proxy[i].cmd == cmd) - help(&doveadm_cmd_proxy[i]); + if (doveadm_cmd_proxy[i].old_cmd == cmd) + help_ver2(&doveadm_cmd_proxy[i]); } i_unreached(); } @@ -138,5 +155,5 @@ unsigned int i; for (i = 0; i < N_ELEMENTS(doveadm_cmd_proxy); i++) - doveadm_register_cmd(&doveadm_cmd_proxy[i]); + doveadm_cmd_register_ver2(&doveadm_cmd_proxy[i]); } diff -Nru dovecot-2.2.22/src/doveadm/doveadm-settings.c dovecot-2.2.24/src/doveadm/doveadm-settings.c --- dovecot-2.2.22/src/doveadm/doveadm-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-settings.c 2016-04-26 13:01:20.000000000 +0000 @@ -56,6 +56,7 @@ DEF(SET_STR, libexec_dir), DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), + DEF(SET_BOOL, auth_debug), DEF(SET_STR, auth_socket_path), DEF(SET_STR, doveadm_socket_path), DEF(SET_UINT, doveadm_worker_count), @@ -81,6 +82,7 @@ .libexec_dir = PKG_LIBEXECDIR, .mail_plugins = "", .mail_plugin_dir = MODULEDIR, + .auth_debug = FALSE, .auth_socket_path = "auth-userdb", .doveadm_socket_path = "doveadm-server", .doveadm_worker_count = 0, diff -Nru dovecot-2.2.22/src/doveadm/doveadm-settings.h dovecot-2.2.24/src/doveadm/doveadm-settings.h --- dovecot-2.2.22/src/doveadm/doveadm-settings.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/doveadm-settings.h 2016-04-26 13:01:20.000000000 +0000 @@ -8,6 +8,7 @@ const char *libexec_dir; const char *mail_plugins; const char *mail_plugin_dir; + bool auth_debug; const char *auth_socket_path; const char *doveadm_socket_path; unsigned int doveadm_worker_count; diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-brain.c dovecot-2.2.24/src/doveadm/dsync/dsync-brain.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-brain.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-brain.c 2016-04-26 13:01:20.000000000 +0000 @@ -705,6 +705,9 @@ const uint8_t *guid_p; uint8_t *guid; + if (brain->require_full_resync) + return; + /* update mailbox states */ array_foreach(&brain->remote_mailbox_states, new_state) { guid_p = new_state->mailbox_guid; diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mailbox.c dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mailbox.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mailbox.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mailbox.c 2016-04-26 13:01:20.000000000 +0000 @@ -322,6 +322,12 @@ exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS; if (brain->hdr_hash_v2) exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_HDR_HASH_V2; + if (remote_dsync_box->messages_count == 0) { + /* remote mailbox is empty - we don't really need to export + header hashes since they're not going to match anything + anyway. */ + exporter_flags |= DSYNC_MAILBOX_EXPORTER_FLAG_NO_HDR_HASHES; + } brain->box_exporter = brain->backup_recv ? NULL : dsync_mailbox_export_init(brain->box, brain->log_scan, @@ -354,7 +360,7 @@ if (brain->box_importer != NULL) { uint32_t last_common_uid, last_messages_count; uint64_t last_common_modseq, last_common_pvt_modseq; - bool changes_during_sync; + bool changes_during_sync, require_full_resync; i_assert(brain->failed); (void)dsync_mailbox_import_deinit(&brain->box_importer, @@ -364,7 +370,10 @@ &last_common_pvt_modseq, &last_messages_count, &changes_during_sync, + &require_full_resync, &brain->mail_error); + if (require_full_resync) + brain->require_full_resync = TRUE; } if (brain->log_scan != NULL) dsync_transaction_log_scan_deinit(&brain->log_scan); diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mailbox-tree.c dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mailbox-tree.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mailbox-tree.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mailbox-tree.c 2016-04-26 13:01:20.000000000 +0000 @@ -310,7 +310,8 @@ break; } } - dsync_mailbox_trees_sync_deinit(&ctx); + if (dsync_mailbox_trees_sync_deinit(&ctx) < 0) + brain->failed = TRUE; } bool dsync_brain_recv_mailbox_tree(struct dsync_brain *brain) diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mails.c dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mails.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-brain-mails.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-brain-mails.c 2016-04-26 13:01:20.000000000 +0000 @@ -219,6 +219,7 @@ static void dsync_brain_sync_half_finished(struct dsync_brain *brain) { struct dsync_mailbox_state state; + bool require_full_resync; if (brain->box_recv_state < DSYNC_BOX_STATE_RECV_LAST_COMMON || brain->box_send_state < DSYNC_BOX_STATE_RECV_LAST_COMMON) @@ -246,13 +247,25 @@ &state.last_common_pvt_modseq, &state.last_messages_count, &state.changes_during_sync, + &require_full_resync, &brain->mail_error) < 0) { - brain->failed = TRUE; - return; + if (require_full_resync) { + /* don't treat this as brain failure or the + state won't be sent to the other brain. + this also means we'll continue syncing the + following mailboxes. */ + brain->require_full_resync = TRUE; + } else { + brain->failed = TRUE; + } } if (state.changes_during_sync) brain->changes_during_sync = TRUE; } + if (brain->require_full_resync) { + state.last_uidvalidity = 0; + state.changes_during_sync = TRUE; + } brain->mailbox_state = state; dsync_ibc_send_mailbox_state(brain->ibc, &state); } diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-export.c dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-export.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-export.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-export.c 2016-04-26 13:01:20.000000000 +0000 @@ -63,6 +63,7 @@ unsigned int minimal_dmail_fill:1; unsigned int return_all_mails:1; unsigned int export_received_timestamps:1; + unsigned int no_hdr_hashes:1; }; static int dsync_mail_error(struct dsync_mailbox_exporter *exporter, @@ -163,6 +164,10 @@ if (!exporter->mails_have_guids) { /* get header hash also */ + if (exporter->no_hdr_hashes) { + *hdr_hash_r = ""; + return 1; + } if (dsync_mail_get_hdr_hash(mail, exporter->hdr_hash_version, hdr_hash_r) < 0) return dsync_mail_error(exporter, mail, "hdr-stream"); return 1; @@ -505,13 +510,15 @@ (flags & DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS) != 0; exporter->hdr_hash_version = (flags & DSYNC_MAILBOX_EXPORTER_FLAG_HDR_HASH_V2) ? 2 : 1; + exporter->no_hdr_hashes = + (flags & DSYNC_MAILBOX_EXPORTER_FLAG_NO_HDR_HASHES) != 0; p_array_init(&exporter->requested_uids, pool, 16); p_array_init(&exporter->search_uids, pool, 16); hash_table_create(&exporter->export_guids, pool, 0, str_hash, strcmp); p_array_init(&exporter->expunged_seqs, pool, 16); p_array_init(&exporter->expunged_guids, pool, 16); - if (!exporter->mails_have_guids) + if (!exporter->mails_have_guids && !exporter->no_hdr_hashes) exporter->wanted_headers = dsync_mail_get_hash_headers(box); /* first scan transaction log and save any expunges and flag changes */ diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-export.h dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-export.h --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-export.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-export.h 2016-04-26 13:01:20.000000000 +0000 @@ -6,7 +6,8 @@ DSYNC_MAILBOX_EXPORTER_FLAG_MAILS_HAVE_GUIDS = 0x02, DSYNC_MAILBOX_EXPORTER_FLAG_MINIMAL_DMAIL_FILL = 0x04, DSYNC_MAILBOX_EXPORTER_FLAG_TIMESTAMPS = 0x08, - DSYNC_MAILBOX_EXPORTER_FLAG_HDR_HASH_V2 = 0x10 + DSYNC_MAILBOX_EXPORTER_FLAG_HDR_HASH_V2 = 0x10, + DSYNC_MAILBOX_EXPORTER_FLAG_NO_HDR_HASHES = 0x20 }; struct dsync_mailbox_exporter * diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-import.c dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-import.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-import.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-import.c 2016-04-26 13:01:20.000000000 +0000 @@ -108,6 +108,7 @@ enum mail_error mail_error; unsigned int failed:1; + unsigned int require_full_resync:1; unsigned int debug:1; unsigned int stateful_import:1; unsigned int last_common_uid_found:1; @@ -146,6 +147,21 @@ } static void +dsync_import_unexpected_state(struct dsync_mailbox_importer *importer, + const char *error) +{ + if (!importer->stateful_import) { + i_error("Mailbox %s: %s", mailbox_get_vname(importer->box), + error); + } else { + i_warning("Mailbox %s doesn't match previous state: %s " + "(dsync must be run again without the state)", + mailbox_get_vname(importer->box), error); + } + importer->require_full_resync = TRUE; +} + +static void dsync_mailbox_import_search_init(struct dsync_mailbox_importer *importer) { struct mail_search_args *search_args; @@ -267,6 +283,24 @@ importer->local_initial_highestpvtmodseq = status.highest_pvt_modseq; dsync_mailbox_import_search_init(importer); + if (!importer->stateful_import) + ; + else if (importer->local_uid_next <= last_common_uid) { + dsync_import_unexpected_state(importer, t_strdup_printf( + "local UIDNEXT %u <= last common UID %u", + importer->local_uid_next, last_common_uid)); + } else if (importer->local_initial_highestmodseq < last_common_modseq) { + dsync_import_unexpected_state(importer, t_strdup_printf( + "local HIGHESTMODSEQ %llu < last common HIGHESTMODSEQ %llu", + (unsigned long long)importer->local_initial_highestmodseq, + (unsigned long long)last_common_modseq)); + } else if (importer->local_initial_highestpvtmodseq < last_common_pvt_modseq) { + dsync_import_unexpected_state(importer, t_strdup_printf( + "local HIGHESTMODSEQ %llu < last common HIGHESTMODSEQ %llu", + (unsigned long long)importer->local_initial_highestpvtmodseq, + (unsigned long long)last_common_pvt_modseq)); + } + importer->local_changes = dsync_transaction_log_scan_get_hash(log_scan); importer->local_attr_changes = dsync_transaction_log_scan_get_attr_hash(log_scan); return importer; @@ -829,20 +863,6 @@ while (!dsync_mailbox_try_save(importer, save_change)) ; } -static void -dsync_import_unexpected_state(struct dsync_mailbox_importer *importer, - const char *error) -{ - if (!importer->stateful_import) { - i_error("Mailbox %s: %s", mailbox_get_vname(importer->box), - error); - } else { - i_warning("Mailbox %s doesn't match previous state: %s " - "(dsync must be run again without the state)", - mailbox_get_vname(importer->box), error); - } -} - static bool dsync_import_set_mail(struct dsync_mailbox_importer *importer, const struct dsync_mail_change *change) @@ -871,8 +891,6 @@ dsync_import_unexpected_state(importer, t_strdup_printf( "Unexpected GUID mismatch for UID=%u: %s != %s", change->uid, guid, cmp_guid)); - importer->mail_error = MAIL_ERROR_TEMP; - importer->failed = TRUE; return FALSE; } return TRUE; @@ -891,8 +909,6 @@ dsync_import_unexpected_state(importer, t_strdup_printf( "Unexpected GUID mismatch (2) for UID=%u: %s != %s", change->uid, importer->cur_guid, cmp_guid)); - importer->mail_error = MAIL_ERROR_TEMP; - importer->failed = TRUE; return FALSE; } return TRUE; @@ -1682,6 +1698,8 @@ if (importer->failed) return -1; + if (importer->require_full_resync) + return 0; if (!importer->last_common_uid_found) { result = NULL; @@ -1697,6 +1715,8 @@ if (importer->failed) return -1; + if (importer->require_full_resync) + return 0; if (importer->last_common_uid_found) { /* a) uid <= last_common_uid for flag changes and expunges. @@ -2421,6 +2441,8 @@ if (importer->failed) return -1; + if (importer->require_full_resync) + return 0; imp_debug(importer, "Import mail body for GUID=%s UID=%u", mail->guid, mail->uid); @@ -2734,6 +2756,7 @@ uint64_t *last_common_pvt_modseq_r, uint32_t *last_messages_count_r, bool *changes_during_sync_r, + bool *require_full_resync_r, enum mail_error *error_r) { struct dsync_mailbox_importer *importer = *_importer; @@ -2742,8 +2765,9 @@ *_importer = NULL; *changes_during_sync_r = FALSE; + *require_full_resync_r = importer->require_full_resync; - if (!success && !importer->failed) { + if ((!success || importer->require_full_resync) && !importer->failed) { importer->mail_error = MAIL_ERROR_TEMP; importer->failed = TRUE; } diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-import.h dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-import.h --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-import.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-import.h 2016-04-26 13:01:20.000000000 +0000 @@ -49,6 +49,7 @@ uint64_t *last_common_pvt_modseq_r, uint32_t *last_messages_count_r, bool *changes_during_sync_r, + bool *require_full_resync_r, enum mail_error *error_r); const char *dsync_mailbox_import_get_proctitle(struct dsync_mailbox_importer *importer); diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-tree.h dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-tree.h --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-tree.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-tree.h 2016-04-26 13:01:20.000000000 +0000 @@ -194,7 +194,7 @@ enum dsync_mailbox_trees_sync_flags sync_flags); const struct dsync_mailbox_tree_sync_change * dsync_mailbox_trees_sync_next(struct dsync_mailbox_tree_sync_ctx *ctx); -void dsync_mailbox_trees_sync_deinit(struct dsync_mailbox_tree_sync_ctx **ctx); +int dsync_mailbox_trees_sync_deinit(struct dsync_mailbox_tree_sync_ctx **ctx); const char *dsync_mailbox_node_to_string(const struct dsync_mailbox_node *node); const char * diff -Nru dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-tree-sync.c dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-tree-sync.c --- dovecot-2.2.22/src/doveadm/dsync/dsync-mailbox-tree-sync.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/dsync-mailbox-tree-sync.c 2016-04-26 13:01:20.000000000 +0000 @@ -15,8 +15,6 @@ #define TEMP_SUFFIX_MAX_LEN (sizeof("temp-")-1 + 8) #define TEMP_SUFFIX_FORMAT "temp-%x" -#define MAX_RENAMES 100 - struct dsync_mailbox_tree_bfs_iter { struct dsync_mailbox_tree *tree; @@ -27,13 +25,14 @@ struct dsync_mailbox_tree_sync_ctx { pool_t pool; - struct dsync_brain *brain; struct dsync_mailbox_tree *local_tree, *remote_tree; enum dsync_mailbox_trees_sync_type sync_type; enum dsync_mailbox_trees_sync_flags sync_flags; + unsigned int combined_mailboxes_count; ARRAY(struct dsync_mailbox_tree_sync_change) changes; unsigned int change_idx; + bool failed; }; static struct dsync_mailbox_tree_bfs_iter * @@ -237,6 +236,7 @@ sync_set_node_deleted(tree, node); } } + ctx->combined_mailboxes_count++; array_append(&siblings, &node, 1); } sort_siblings(&siblings); @@ -1039,12 +1039,12 @@ static bool sync_rename_temp_mailboxes(struct dsync_mailbox_tree_sync_ctx *ctx, struct dsync_mailbox_tree *tree, - struct dsync_mailbox_node *node) + struct dsync_mailbox_node *node, bool *renames_r) { const char *reason; for (; node != NULL; node = node->next) { - while (sync_rename_temp_mailboxes(ctx, tree, node->first_child)) ; + while (sync_rename_temp_mailboxes(ctx, tree, node->first_child, renames_r)) ; if (!node->sync_temporary_name) { } else if (dsync_mailbox_node_is_dir(node) && @@ -1061,6 +1061,7 @@ sync_rename_delete_node_dirs(ctx, tree, node); } else { T_BEGIN { + *renames_r = TRUE; sync_rename_temp_mailbox_node(tree, node, &reason); if ((ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_DEBUG) != 0) { i_debug("brain %c: %s mailbox %s: %s", @@ -1075,12 +1076,16 @@ return FALSE; } -static void -dsync_mailbox_tree_handle_renames(struct dsync_mailbox_tree_sync_ctx *ctx) +static int +dsync_mailbox_tree_handle_renames(struct dsync_mailbox_tree_sync_ctx *ctx, + bool *renames_r) { - unsigned int count = 0; + unsigned int max_renames, count = 0; bool changed; + *renames_r = FALSE; + + max_renames = ctx->combined_mailboxes_count * 3; do { T_BEGIN { changed = sync_rename_mailboxes(ctx, &ctx->local_tree->root, @@ -1091,15 +1096,16 @@ i_debug("brain %c: -- Mailbox renamed, restart sync --", (ctx->sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_MASTER_BRAIN) != 0 ? 'M' : 'S'); } - } while (changed && ++count <= MAX_RENAMES); + } while (changed && ++count <= max_renames); if (changed) { i_error("BUG: Mailbox renaming algorithm got into a potentially infinite loop, aborting"); - ctx->brain->failed = TRUE; + return -1; } - while (sync_rename_temp_mailboxes(ctx, ctx->local_tree, &ctx->local_tree->root)) ; - while (sync_rename_temp_mailboxes(ctx, ctx->remote_tree, &ctx->remote_tree->root)) ; + while (sync_rename_temp_mailboxes(ctx, ctx->local_tree, &ctx->local_tree->root, renames_r)) ; + while (sync_rename_temp_mailboxes(ctx, ctx->remote_tree, &ctx->remote_tree->root, renames_r)) ; + return 0; } static bool sync_is_wrong_mailbox(struct dsync_mailbox_node *node, @@ -1389,6 +1395,8 @@ enum dsync_mailbox_trees_sync_flags sync_flags) { struct dsync_mailbox_tree_sync_ctx *ctx; + unsigned int rename_counter = 0; + bool renames; pool_t pool; i_assert(hash_table_is_created(local_tree->guid_hash)); @@ -1404,6 +1412,9 @@ ctx->sync_flags = sync_flags; i_array_init(&ctx->changes, 128); +again: + renames = FALSE; + ctx->combined_mailboxes_count = 0; sync_tree_sort_and_delete_mailboxes(ctx, remote_tree, sync_type == DSYNC_MAILBOX_TREES_SYNC_TYPE_TWOWAY); sync_tree_sort_and_delete_mailboxes(ctx, local_tree, @@ -1411,8 +1422,12 @@ dsync_mailbox_tree_update_child_timestamps(&local_tree->root, 0); dsync_mailbox_tree_update_child_timestamps(&remote_tree->root, 0); - if ((sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_NO_RENAMES) == 0) - dsync_mailbox_tree_handle_renames(ctx); + if ((sync_flags & DSYNC_MAILBOX_TREES_SYNC_FLAG_NO_RENAMES) == 0) { + if (dsync_mailbox_tree_handle_renames(ctx, &renames) < 0) { + ctx->failed = TRUE; + return ctx; + } + } /* if we're not doing a two-way sync, delete now any mailboxes, which a) shouldn't exist, b) doesn't have a matching GUID/UIDVALIDITY, @@ -1426,6 +1441,14 @@ sync_create_mailboxes(ctx, remote_tree); if (sync_type != DSYNC_MAILBOX_TREES_SYNC_TYPE_PRESERVE_REMOTE) sync_create_mailboxes(ctx, local_tree); + if (renames && rename_counter++ <= ctx->combined_mailboxes_count*3) { + /* this rename algorithm is just horrible. we're retrying this + because the final sync_rename_temp_mailbox_node() calls + give different names to local & remote mailbox trees. + something's not right here, but this looping is better than + a crash in sync_mailbox_dirs() due to trees not matching. */ + goto again; + } sync_mailbox_dirs(ctx); return ctx; } @@ -1438,12 +1461,14 @@ return array_idx(&ctx->changes, ctx->change_idx++); } -void dsync_mailbox_trees_sync_deinit(struct dsync_mailbox_tree_sync_ctx **_ctx) +int dsync_mailbox_trees_sync_deinit(struct dsync_mailbox_tree_sync_ctx **_ctx) { struct dsync_mailbox_tree_sync_ctx *ctx = *_ctx; + int ret = ctx->failed ? -1 : 0; *_ctx = NULL; array_free(&ctx->changes); pool_unref(&ctx->pool); + return ret; } diff -Nru dovecot-2.2.22/src/doveadm/dsync/Makefile.in dovecot-2.2.24/src/doveadm/dsync/Makefile.in --- dovecot-2.2.22/src/doveadm/dsync/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -282,7 +282,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c dovecot-2.2.24/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c --- dovecot-2.2.22/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/dsync/test-dsync-mailbox-tree-sync.c 2016-04-26 13:01:20.000000000 +0000 @@ -703,6 +703,28 @@ #endif } +static void test_dsync_mailbox_tree_sync_renames22(void) +{ + struct dsync_mailbox_tree *tree1, *tree2; + + test_begin("dsync mailbox tree sync renames 22"); + tree1 = dsync_mailbox_tree_init('/', '_'); + tree2 = dsync_mailbox_tree_init('/', '_'); + + node_create(tree1, 3, "p/a", 0); + node_create(tree1, 0, "p/2", 0); + node_create(tree1, 5, "p/2/h", 0); + + node_create(tree2, 4, "p/1/z", 0); + node_create(tree2, 1, "p/2", 0); + node_create(tree2, 2, "p/2/a", 0); + node_create(tree2, 5, "p/2/y", 0); + node_create(tree2, 3, "p/3", 0); + + test_trees(tree1, tree2); + test_end(); +} + static void test_dsync_mailbox_tree_sync_random(void) { struct dsync_mailbox_tree *tree1, *tree2; @@ -740,6 +762,7 @@ test_dsync_mailbox_tree_sync_renames19, test_dsync_mailbox_tree_sync_renames20, test_dsync_mailbox_tree_sync_renames21, + test_dsync_mailbox_tree_sync_renames22, test_dsync_mailbox_tree_sync_random, NULL }; diff -Nru dovecot-2.2.22/src/doveadm/main.c dovecot-2.2.24/src/doveadm/main.c --- dovecot-2.2.22/src/doveadm/main.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/main.c 2016-04-26 13:01:20.000000000 +0000 @@ -5,6 +5,7 @@ #include "master-service.h" #include "master-service-settings.h" #include "settings-parser.h" +#include "dict.h" #include "client-connection.h" #include "client-connection-private.h" #include "doveadm-settings.h" @@ -74,6 +75,7 @@ doveadm_cmds_init(); doveadm_dump_init(); doveadm_mail_init(); + dict_drivers_register_builtin(); doveadm_load_modules(); } @@ -84,6 +86,7 @@ doveadm_mail_deinit(); doveadm_dump_deinit(); doveadm_unload_modules(); + dict_drivers_unregister_builtin(); doveadm_print_deinit(); doveadm_cmds_deinit(); doveadm_http_server_deinit(); diff -Nru dovecot-2.2.22/src/doveadm/Makefile.in dovecot-2.2.24/src/doveadm/Makefile.in --- dovecot-2.2.22/src/doveadm/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/doveadm/Makefile.in 2016-04-26 15:10:49.000000000 +0000 @@ -345,7 +345,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/imap/imap-client.c dovecot-2.2.24/src/imap/imap-client.c --- dovecot-2.2.22/src/imap/imap-client.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap/imap-client.c 2016-04-26 13:01:20.000000000 +0000 @@ -79,7 +79,8 @@ struct client *client_create(int fd_in, int fd_out, const char *session_id, struct mail_user *user, struct mail_storage_service_user *service_user, - const struct imap_settings *set) + const struct imap_settings *set, + const struct lda_settings *lda_set) { const struct mail_storage_settings *mail_set; struct client *client; @@ -96,6 +97,7 @@ client->pool = pool; client->v = imap_client_vfuncs; client->set = set; + client->lda_set = lda_set; client->service_user = service_user; client->session_id = p_strdup(pool, session_id); client->fd_in = fd_in; diff -Nru dovecot-2.2.22/src/imap/imap-client.h dovecot-2.2.24/src/imap/imap-client.h --- dovecot-2.2.22/src/imap/imap-client.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap/imap-client.h 2016-04-26 13:01:20.000000000 +0000 @@ -13,6 +13,7 @@ struct client; struct mail_storage; struct mail_storage_service_ctx; +struct lda_settings; struct imap_parser; struct imap_arg; struct imap_urlauth_context; @@ -126,7 +127,8 @@ pool_t pool; struct mail_storage_service_user *service_user; - const struct imap_settings *set; + const struct imap_settings *set; + const struct lda_settings *lda_set; string_t *capability_string; struct mail_user *user; @@ -216,7 +218,8 @@ struct client *client_create(int fd_in, int fd_out, const char *session_id, struct mail_user *user, struct mail_storage_service_user *service_user, - const struct imap_settings *set); + const struct imap_settings *set, + const struct lda_settings *lda_set); void client_destroy(struct client *client, const char *reason) ATTR_NULL(2); /* Disconnect client connection */ diff -Nru dovecot-2.2.22/src/imap/main.c dovecot-2.2.24/src/imap/main.c --- dovecot-2.2.22/src/imap/main.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap/main.c 2016-04-26 13:01:20.000000000 +0000 @@ -17,6 +17,7 @@ #include "master-login.h" #include "mail-user.h" #include "mail-storage-service.h" +#include "lda-settings.h" #include "imap-master-client.h" #include "imap-resp-code.h" #include "imap-commands.h" @@ -219,7 +220,8 @@ struct mail_user *mail_user; struct mail_namespace *ns; struct client *client; - struct imap_settings *set; + struct imap_settings *imap_set; + struct lda_settings *lda_set; const char *errstr; enum mail_error mail_error; @@ -244,15 +246,18 @@ return -1; } - set = mail_storage_service_user_get_set(user)[1]; - if (set->verbose_proctitle) + imap_set = mail_storage_service_user_get_set(user)[1]; + if (imap_set->verbose_proctitle) verbose_proctitle = TRUE; + lda_set = mail_storage_service_user_get_set(user)[2]; - settings_var_expand(&imap_setting_parser_info, set, mail_user->pool, - mail_user_var_expand_table(mail_user)); + settings_var_expand(&imap_setting_parser_info, imap_set, + mail_user->pool, mail_user_var_expand_table(mail_user)); + settings_var_expand(&lda_setting_parser_info, lda_set, + mail_user->pool, mail_user_var_expand_table(mail_user)); client = client_create(fd_in, fd_out, input->session_id, - mail_user, user, set); + mail_user, user, imap_set, lda_set); client->userdb_fields = input->userdb_fields == NULL ? NULL : p_strarray_dup(client->pool, input->userdb_fields); *client_r = client; @@ -362,6 +367,7 @@ { static const struct setting_parser_info *set_roots[] = { &imap_setting_parser_info, + &lda_setting_parser_info, NULL }; struct master_login_settings login_set; diff -Nru dovecot-2.2.22/src/imap/Makefile.am dovecot-2.2.24/src/imap/Makefile.am --- dovecot-2.2.22/src/imap/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -8,6 +8,7 @@ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-mail \ + -I$(top_srcdir)/src/lib-lda \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-imap-urlauth \ -I$(top_srcdir)/src/lib-imap-storage \ @@ -18,10 +19,12 @@ imap_LDADD = \ ../lib-imap-urlauth/libimap-urlauth.la \ + $(LIBDOVECOT_LDA) \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) imap_DEPENDENCIES = \ ../lib-imap-urlauth/libimap-urlauth.la \ + $(LIBDOVECOT_LDA) \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) diff -Nru dovecot-2.2.22/src/imap/Makefile.in dovecot-2.2.24/src/imap/Makefile.in --- dovecot-2.2.22/src/imap/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -287,7 +287,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -426,6 +428,7 @@ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-mail \ + -I$(top_srcdir)/src/lib-lda \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-imap-urlauth \ -I$(top_srcdir)/src/lib-imap-storage \ @@ -435,11 +438,13 @@ imap_LDFLAGS = -export-dynamic imap_LDADD = \ ../lib-imap-urlauth/libimap-urlauth.la \ + $(LIBDOVECOT_LDA) \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) imap_DEPENDENCIES = \ ../lib-imap-urlauth/libimap-urlauth.la \ + $(LIBDOVECOT_LDA) \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) diff -Nru dovecot-2.2.22/src/imap-hibernate/Makefile.in dovecot-2.2.24/src/imap-hibernate/Makefile.in --- dovecot-2.2.22/src/imap-hibernate/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap-hibernate/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -234,7 +234,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/imap-login/Makefile.in dovecot-2.2.24/src/imap-login/Makefile.in --- dovecot-2.2.22/src/imap-login/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap-login/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -261,7 +261,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/imap-urlauth/Makefile.in dovecot-2.2.24/src/imap-urlauth/Makefile.in --- dovecot-2.2.22/src/imap-urlauth/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/imap-urlauth/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -251,7 +251,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/indexer/Makefile.in dovecot-2.2.24/src/indexer/Makefile.in --- dovecot-2.2.22/src/indexer/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/indexer/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/ipc/Makefile.in dovecot-2.2.24/src/ipc/Makefile.in --- dovecot-2.2.22/src/ipc/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/ipc/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -233,7 +233,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lda/Makefile.in dovecot-2.2.24/src/lda/Makefile.in --- dovecot-2.2.22/src/lda/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lda/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -231,7 +231,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib/fdpass.h dovecot-2.2.24/src/lib/fdpass.h --- dovecot-2.2.22/src/lib/fdpass.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/fdpass.h 2016-04-26 13:01:21.000000000 +0000 @@ -1,12 +1,15 @@ #ifndef FDPASS_H #define FDPASS_H -/* Returns number of bytes sent, -1 if error. send_fd can be -1 if we just - want to send the data with sendmsg(). */ +/* Send data and send_fd (unless it's -1) via sendmsg(). Returns number of + bytes sent, or -1 on error. If at least 1 byte was sent, the send_fd was + also sent. */ ssize_t fd_send(int handle, int send_fd, const void *data, size_t size); -/* Returns number of bytes read, or -1 if error. fd is set -1 if read was only - partial (returns 0) or data was received without a passed fd. */ -ssize_t fd_read(int handle, void *data, size_t size, int *fd); +/* Receive data and fd via recvmsg(). Returns number of bytes read, 0 on + disconnection, or -1 on error. If at least 1 byte was read, the fd is also + returned (if it had been sent). If there was no fd received, it's set to + -1. See test-istream-unix.c for different test cases. */ +ssize_t fd_read(int handle, void *data, size_t size, int *fd_r); #endif diff -Nru dovecot-2.2.22/src/lib/iostream-rawlog.h dovecot-2.2.24/src/lib/iostream-rawlog.h --- dovecot-2.2.22/src/lib/iostream-rawlog.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/iostream-rawlog.h 2016-04-26 13:01:21.000000000 +0000 @@ -1,6 +1,12 @@ #ifndef IOSTREAM_RAWLOG_H #define IOSTREAM_RAWLOG_H +enum iostream_rawlog_flags { + IOSTREAM_RAWLOG_FLAG_AUTOCLOSE = 0x01, + IOSTREAM_RAWLOG_FLAG_BUFFERED = 0x02, + IOSTREAM_RAWLOG_FLAG_TIMESTAMP = 0x04 +}; + /* Create rawlog *.in and *.out files to the given directory. */ int ATTR_NOWARN_UNUSED_RESULT iostream_rawlog_create(const char *dir, struct istream **input, diff -Nru dovecot-2.2.22/src/lib/iostream-rawlog-private.h dovecot-2.2.24/src/lib/iostream-rawlog-private.h --- dovecot-2.2.22/src/lib/iostream-rawlog-private.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/iostream-rawlog-private.h 2016-04-26 13:01:21.000000000 +0000 @@ -1,13 +1,9 @@ #ifndef IOSTREAM_RAWLOG_PRIVATE_H #define IOSTREAM_RAWLOG_PRIVATE_H -#define IOSTREAM_RAWLOG_MAX_PREFIX_LEN 3 +#include "iostream-rawlog.h" -enum iostream_rawlog_flags { - IOSTREAM_RAWLOG_FLAG_AUTOCLOSE = 0x01, - IOSTREAM_RAWLOG_FLAG_BUFFERED = 0x02, - IOSTREAM_RAWLOG_FLAG_TIMESTAMP = 0x04 -}; +#define IOSTREAM_RAWLOG_MAX_PREFIX_LEN 3 struct rawlog_iostream { struct iostream_private *iostream; diff -Nru dovecot-2.2.22/src/lib/istream-concat.c dovecot-2.2.24/src/lib/istream-concat.c --- dovecot-2.2.22/src/lib/istream-concat.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/istream-concat.c 2016-04-26 13:01:21.000000000 +0000 @@ -137,10 +137,7 @@ ssize_t ret; bool last_stream; - if (cstream->cur_input == NULL) { - stream->istream.stream_errno = EINVAL; - return -1; - } + i_assert(cstream->cur_input != NULL); i_stream_concat_skip(cstream); i_assert(stream->pos >= stream->skip + cstream->prev_stream_left); @@ -221,8 +218,9 @@ return ret; } -static unsigned int -find_v_offset(struct concat_istream *cstream, uoff_t *v_offset) +static int +find_v_offset(struct concat_istream *cstream, uoff_t *v_offset, + unsigned int *idx_r) { const struct stat *st; unsigned int i; @@ -244,7 +242,7 @@ i_stream_get_error(cstream->input[i])); cstream->istream.istream.stream_errno = cstream->input[i]->stream_errno; - return UINT_MAX; + return -1; } /* @UNSAFE */ @@ -256,7 +254,8 @@ *v_offset -= cstream->input_size[i]; } - return i; + *idx_r = i; + return 0; } static void i_stream_concat_seek(struct istream_private *stream, @@ -270,16 +269,25 @@ cstream->prev_stream_skip = 0; cstream->prev_skip = 0; - cstream->cur_idx = find_v_offset(cstream, &v_offset); - if (cstream->cur_idx == UINT_MAX) { + if (find_v_offset(cstream, &v_offset, &cstream->cur_idx) < 0) { /* failed */ - cstream->cur_input = NULL; stream->istream.stream_errno = EINVAL; return; } cstream->cur_input = cstream->input[cstream->cur_idx]; - if (cstream->cur_input != NULL) - i_stream_seek(cstream->cur_input, v_offset); + if (cstream->cur_input == NULL) { + /* we allow seeking to EOF, but not past it. */ + if (v_offset != 0) { + io_stream_set_error(&cstream->istream.iostream, + "Seeking past EOF by %"PRIuUOFF_T" bytes", v_offset); + cstream->istream.istream.stream_errno = EINVAL; + return; + } + i_assert(cstream->cur_idx > 0); + cstream->cur_input = cstream->input[cstream->cur_idx-1]; + v_offset = cstream->input_size[cstream->cur_idx-1]; + } + i_stream_seek(cstream->cur_input, v_offset); } static int @@ -287,10 +295,10 @@ { struct concat_istream *cstream = (struct concat_istream *)stream; uoff_t v_offset = (uoff_t)-1; - unsigned int i; + unsigned int i, cur_idx; /* make sure we have all sizes */ - if (find_v_offset(cstream, &v_offset) == UINT_MAX) + if (find_v_offset(cstream, &v_offset, &cur_idx) < 0) return -1; stream->statbuf.st_size = 0; diff -Nru dovecot-2.2.22/src/lib/istream-timeout.c dovecot-2.2.24/src/lib/istream-timeout.c --- dovecot-2.2.22/src/lib/istream-timeout.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/istream-timeout.c 2016-04-26 13:01:21.000000000 +0000 @@ -38,7 +38,7 @@ static void i_stream_timeout(struct timeout_istream *tstream) { - unsigned int msecs; + unsigned int over_msecs; int diff; if (tstream->update_timestamp) { @@ -59,13 +59,14 @@ i_stream_timeout, tstream); return; } + over_msecs = diff - tstream->timeout_msecs; - msecs = tstream->timeout_msecs % 1000; io_stream_set_error(&tstream->istream.iostream, - "Read timeout in %u%s s after %"PRIuUOFF_T" bytes", - tstream->timeout_msecs/1000, - msecs == 0 ? "" : t_strdup_printf(".%u", msecs), - tstream->istream.istream.v_offset); + "Read timeout in %u.%03u s after %"PRIuUOFF_T" bytes%s", + diff/1000, diff%1000, + tstream->istream.istream.v_offset, + over_msecs < 1000 ? "" : t_strdup_printf( + " (requested timeout in %u ms)", tstream->timeout_msecs)); tstream->istream.istream.stream_errno = ETIMEDOUT; i_stream_set_input_pending(tstream->istream.parent, TRUE); diff -Nru dovecot-2.2.22/src/lib/istream-unix.c dovecot-2.2.24/src/lib/istream-unix.c --- dovecot-2.2.22/src/lib/istream-unix.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/istream-unix.c 2016-04-26 13:01:21.000000000 +0000 @@ -44,6 +44,13 @@ if (ustream->read_fd != -1) ustream->next_read_fd = FALSE; + if (ret == 0) { + /* EOF */ + stream->istream.eof = TRUE; + ustream->fstream.seen_eof = TRUE; + return -1; + } + if (unlikely(ret < 0)) { if (errno == EINTR || errno == EAGAIN) { i_assert(!stream->istream.blocking); diff -Nru dovecot-2.2.22/src/lib/Makefile.am dovecot-2.2.24/src/lib/Makefile.am --- dovecot-2.2.22/src/lib/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/Makefile.am 2016-04-26 13:01:21.000000000 +0000 @@ -112,6 +112,7 @@ ostream-failure-at.c \ ostream-file.c \ ostream-hash.c \ + ostream-null.c \ ostream-rawlog.c \ primes.c \ printf-format-fix.c \ @@ -244,6 +245,7 @@ ostream-failure-at.h \ ostream-hash.h \ ostream-private.h \ + ostream-null.h \ ostream-rawlog.h \ primes.h \ printf-format-fix.h \ diff -Nru dovecot-2.2.22/src/lib/Makefile.in dovecot-2.2.24/src/lib/Makefile.in --- dovecot-2.2.22/src/lib/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -133,7 +133,7 @@ mmap-util.lo module-dir.lo mountpoint.lo net.lo \ nfs-workarounds.lo numpack.lo ostream.lo ostream-buffer.lo \ ostream-escaped.lo ostream-failure-at.lo ostream-file.lo \ - ostream-hash.lo ostream-rawlog.lo primes.lo \ + ostream-hash.lo ostream-null.lo ostream-rawlog.lo primes.lo \ printf-format-fix.lo process-title.lo priorityq.lo randgen.lo \ rand.lo read-full.lo restrict-access.lo \ restrict-process-size.lo safe-memset.lo safe-mkdir.lo \ @@ -347,7 +347,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -585,6 +587,7 @@ ostream-failure-at.c \ ostream-file.c \ ostream-hash.c \ + ostream-null.c \ ostream-rawlog.c \ primes.c \ printf-format-fix.c \ @@ -717,6 +720,7 @@ ostream-failure-at.h \ ostream-hash.h \ ostream-private.h \ + ostream-null.h \ ostream-rawlog.h \ primes.h \ printf-format-fix.h \ @@ -996,6 +1000,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-failure-at.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-null.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-rawlog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primes.Plo@am__quote@ diff -Nru dovecot-2.2.22/src/lib/ostream-null.c dovecot-2.2.24/src/lib/ostream-null.c --- dovecot-2.2.22/src/lib/ostream-null.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib/ostream-null.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,32 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ostream-private.h" +#include "ostream-null.h" + +static ssize_t +o_stream_null_sendv(struct ostream_private *stream, + const struct const_iovec *iov, unsigned int iov_count) +{ + unsigned int i; + size_t ret = 0; + + for (i = 0; i < iov_count; i++) + ret += iov[i].iov_len; + stream->ostream.offset += ret; + return ret; +} + +struct ostream *o_stream_create_null(void) +{ + struct ostream_private *stream; + struct ostream *output; + + stream = i_new(struct ostream_private, 1); + stream->sendv = o_stream_null_sendv; + + output = o_stream_create(stream, NULL, -1); + o_stream_set_no_error_handling(output, TRUE); + o_stream_set_name(output, "(/dev/null)"); + return output; +} diff -Nru dovecot-2.2.22/src/lib/ostream-null.h dovecot-2.2.24/src/lib/ostream-null.h --- dovecot-2.2.22/src/lib/ostream-null.h 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib/ostream-null.h 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,7 @@ +#ifndef OSTREAM_NULL_H +#define OSTREAM_NULL_H + +/* Create an output stream that ignores all the writes. */ +struct ostream *o_stream_create_null(void); + +#endif diff -Nru dovecot-2.2.22/src/lib/test-var-expand.c dovecot-2.2.24/src/lib/test-var-expand.c --- dovecot-2.2.22/src/lib/test-var-expand.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/test-var-expand.c 2016-04-26 13:01:21.000000000 +0000 @@ -52,7 +52,10 @@ { "%50Hv", "1f" }, { "%50Hw", "2e" }, { "%50Nv", "25" }, - { "%50Nw", "e" } + { "%50Nw", "e" }, + + { "%{nonexistent}", "UNSUPPORTED_VARIABLE_nonexistent" }, + { "%{nonexistent:default}", "UNSUPPORTED_VARIABLE_nonexistent" }, }; static struct var_expand_table table[] = { { 'v', "value", NULL }, diff -Nru dovecot-2.2.22/src/lib/utc-mktime.c dovecot-2.2.24/src/lib/utc-mktime.c --- dovecot-2.2.22/src/lib/utc-mktime.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/utc-mktime.c 2016-04-26 13:01:21.000000000 +0000 @@ -20,6 +20,18 @@ return tm1->tm_sec - tm2->tm_sec; } +#ifdef HAVE_TIMEGM +time_t utc_mktime(const struct tm *tm) +{ + struct tm mod_tm = *tm; + time_t t; + + t = timegm(&mod_tm); + if (tm_cmp(tm, &mod_tm) != 0) + return (time_t)-1; + return t; +} +#else time_t utc_mktime(const struct tm *tm) { const struct tm *try_tm; @@ -51,3 +63,4 @@ return (time_t)-1; } +#endif diff -Nru dovecot-2.2.22/src/lib/var-expand.c dovecot-2.2.24/src/lib/var-expand.c --- dovecot-2.2.22/src/lib/var-expand.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib/var-expand.c 2016-04-26 13:01:21.000000000 +0000 @@ -232,6 +232,8 @@ data = ""; value = var_expand_func(func_table, key, data, context); } + if (value == NULL) + return t_strdup_printf("UNSUPPORTED_VARIABLE_%s", key); return value; } @@ -325,8 +327,8 @@ len = end - (str + 1); var = var_expand_long(table, func_table, str+1, len, context); - if (var != NULL) - str = end; + i_assert(var != NULL); + str = end; } else if (table != NULL) { for (t = table; !TABLE_LAST(t); t++) { if (t->key == *str) { diff -Nru dovecot-2.2.22/src/lib-auth/auth-client.h dovecot-2.2.24/src/lib-auth/auth-client.h --- dovecot-2.2.22/src/lib-auth/auth-client.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-auth/auth-client.h 2016-04-26 13:01:20.000000000 +0000 @@ -13,7 +13,9 @@ /* Skip penalty checks for this request */ AUTH_REQUEST_FLAG_NO_PENALTY = 0x04, /* Support final SASL response */ - AUTH_REQUEST_FLAG_SUPPORT_FINAL_RESP = 0x08 + AUTH_REQUEST_FLAG_SUPPORT_FINAL_RESP = 0x08, + /* Enable auth_debug=yes logging for this request */ + AUTH_REQUEST_FLAG_DEBUG = 0x10 }; enum auth_request_status { diff -Nru dovecot-2.2.22/src/lib-auth/auth-client-request.c dovecot-2.2.24/src/lib-auth/auth-client-request.c --- dovecot-2.2.22/src/lib-auth/auth-client-request.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-auth/auth-client-request.c 2016-04-26 13:01:20.000000000 +0000 @@ -42,6 +42,8 @@ str_append(str, "\tno-penalty"); if ((info->flags & AUTH_REQUEST_FLAG_VALID_CLIENT_CERT) != 0) str_append(str, "\tvalid-client-cert"); + if ((info->flags & AUTH_REQUEST_FLAG_DEBUG) != 0) + str_append(str, "\tdebug"); if (info->session_id != NULL) { str_append(str, "\tsession="); diff -Nru dovecot-2.2.22/src/lib-auth/auth-master.c dovecot-2.2.24/src/lib-auth/auth-master.c --- dovecot-2.2.22/src/lib-auth/auth-master.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-auth/auth-master.c 2016-04-26 13:01:20.000000000 +0000 @@ -467,6 +467,8 @@ str_printfa(str, "\trip=%s", net_ip2addr(&info->remote_ip)); if (info->remote_port != 0) str_printfa(str, "\trport=%d", info->remote_port); + if (info->debug) + str_append(str, "\tdebug"); } int auth_master_user_lookup(struct auth_master_connection *conn, diff -Nru dovecot-2.2.22/src/lib-auth/auth-master.h dovecot-2.2.24/src/lib-auth/auth-master.h --- dovecot-2.2.22/src/lib-auth/auth-master.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-auth/auth-master.h 2016-04-26 13:01:20.000000000 +0000 @@ -14,6 +14,7 @@ const char *service; struct ip_addr local_ip, remote_ip; in_port_t local_port, remote_port; + bool debug; }; struct auth_user_reply { diff -Nru dovecot-2.2.22/src/lib-auth/Makefile.in dovecot-2.2.24/src/lib-auth/Makefile.in --- dovecot-2.2.22/src/lib-auth/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-auth/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-charset/Makefile.in dovecot-2.2.24/src/lib-charset/Makefile.in --- dovecot-2.2.22/src/lib-charset/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-charset/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -264,7 +264,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-compression/Makefile.in dovecot-2.2.24/src/lib-compression/Makefile.in --- dovecot-2.2.22/src/lib-compression/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-compression/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -279,7 +279,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-dict/dict-fs.c dovecot-2.2.24/src/lib-dict/dict-fs.c --- dovecot-2.2.22/src/lib-dict/dict-fs.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict/dict-fs.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,290 +0,0 @@ -/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "fs-api.h" -#include "istream.h" -#include "str.h" -#include "dict-transaction-memory.h" -#include "dict-private.h" - -struct fs_dict { - struct dict dict; - struct fs *fs; - char *username; -}; - -struct fs_dict_iterate_context { - struct dict_iterate_context ctx; - const char **paths; - unsigned int path_idx; - enum dict_iterate_flags flags; - pool_t value_pool; - struct fs_iter *fs_iter; - bool failed; -}; - -static int -fs_dict_init(struct dict *driver, const char *uri, - const struct dict_settings *set, - struct dict **dict_r, const char **error_r) -{ - struct fs_settings fs_set; - struct fs *fs; - struct fs_dict *dict; - const char *p, *fs_driver, *fs_args; - - p = strchr(uri, ':'); - if (p == NULL) { - fs_driver = uri; - fs_args = ""; - } else { - fs_driver = t_strdup_until(uri, p); - fs_args = p+1; - } - - memset(&fs_set, 0, sizeof(fs_set)); - fs_set.username = set->username; - fs_set.base_dir = set->base_dir; - if (fs_init(fs_driver, fs_args, &fs_set, &fs, error_r) < 0) - return -1; - - dict = i_new(struct fs_dict, 1); - dict->dict = *driver; - dict->fs = fs; - dict->username = i_strdup(set->username); - - *dict_r = &dict->dict; - return 0; -} - -static void fs_dict_deinit(struct dict *_dict) -{ - struct fs_dict *dict = (struct fs_dict *)_dict; - - fs_deinit(&dict->fs); - i_free(dict->username); - i_free(dict); -} - -static const char *fs_dict_get_full_key(struct fs_dict *dict, const char *key) -{ - if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) - return key + strlen(DICT_PATH_SHARED); - else if (strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE)) == 0) { - return t_strdup_printf("%s/%s", dict->username, - key + strlen(DICT_PATH_PRIVATE)); - } else { - i_unreached(); - } -} - -static int fs_dict_lookup(struct dict *_dict, pool_t pool, - const char *key, const char **value_r) -{ - struct fs_dict *dict = (struct fs_dict *)_dict; - struct fs_file *file; - struct istream *input; - const unsigned char *data; - size_t size; - string_t *str; - int ret; - - file = fs_file_init(dict->fs, fs_dict_get_full_key(dict, key), - FS_OPEN_MODE_READONLY); - input = fs_read_stream(file, IO_BLOCK_SIZE); - i_stream_read(input); - - str = str_new(pool, i_stream_get_data_size(input)+1); - while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { - str_append_n(str, data, size); - i_stream_skip(input, size); - } - i_assert(ret == -1); - - if (input->stream_errno == 0) { - *value_r = str_c(str); - ret = 1; - } else { - *value_r = NULL; - if (input->stream_errno == ENOENT) - ret = 0; - } - - i_stream_unref(&input); - fs_file_deinit(&file); - return ret; -} - -static struct dict_iterate_context * -fs_dict_iterate_init(struct dict *_dict, const char *const *paths, - enum dict_iterate_flags flags) -{ - struct fs_dict *dict = (struct fs_dict *)_dict; - struct fs_dict_iterate_context *iter; - - /* these flags are not supported for now */ - i_assert((flags & DICT_ITERATE_FLAG_RECURSE) == 0); - i_assert((flags & DICT_ITERATE_FLAG_EXACT_KEY) == 0); - i_assert((flags & (DICT_ITERATE_FLAG_SORT_BY_KEY | - DICT_ITERATE_FLAG_SORT_BY_VALUE)) == 0); - - iter = i_new(struct fs_dict_iterate_context, 1); - iter->ctx.dict = _dict; - iter->paths = p_strarray_dup(default_pool, paths); - iter->flags = flags; - iter->value_pool = pool_alloconly_create("iterate value pool", 128); - iter->fs_iter = fs_iter_init(dict->fs, - fs_dict_get_full_key(dict, paths[0]), 0); - return &iter->ctx; -} - -static bool fs_dict_iterate(struct dict_iterate_context *ctx, - const char **key_r, const char **value_r) -{ - struct fs_dict_iterate_context *iter = - (struct fs_dict_iterate_context *)ctx; - struct fs_dict *dict = (struct fs_dict *)ctx->dict; - const char *path; - int ret; - - *key_r = fs_iter_next(iter->fs_iter); - if (*key_r == NULL) { - if (fs_iter_deinit(&iter->fs_iter) < 0) { - iter->failed = TRUE; - return FALSE; - } - if (iter->paths[++iter->path_idx] == NULL) - return FALSE; - path = fs_dict_get_full_key(dict, iter->paths[iter->path_idx]); - iter->fs_iter = fs_iter_init(dict->fs, path, 0); - return fs_dict_iterate(ctx, key_r, value_r); - } - if ((iter->flags & DICT_ITERATE_FLAG_NO_VALUE) != 0) { - *value_r = NULL; - return TRUE; - } - p_clear(iter->value_pool); - path = t_strconcat(iter->paths[iter->path_idx], *key_r, NULL); - if ((ret = fs_dict_lookup(ctx->dict, iter->value_pool, path, value_r)) < 0) { - /* I/O error */ - iter->failed = TRUE; - return FALSE; - } else if (ret == 0) { - /* file was just deleted, just skip to next one */ - return fs_dict_iterate(ctx, key_r, value_r); - } - return TRUE; -} - -static int fs_dict_iterate_deinit(struct dict_iterate_context *ctx) -{ - struct fs_dict_iterate_context *iter = - (struct fs_dict_iterate_context *)ctx; - int ret; - - if (iter->fs_iter != NULL) { - if (fs_iter_deinit(&iter->fs_iter) < 0) - iter->failed = TRUE; - } - ret = iter->failed ? -1 : 0; - - pool_unref(&iter->value_pool); - i_free(iter->paths); - i_free(iter); - return ret; -} - -static struct dict_transaction_context * -fs_dict_transaction_init(struct dict *_dict) -{ - struct dict_transaction_memory_context *ctx; - pool_t pool; - - pool = pool_alloconly_create("file dict transaction", 2048); - ctx = p_new(pool, struct dict_transaction_memory_context, 1); - dict_transaction_memory_init(ctx, _dict, pool); - return &ctx->ctx; -} - -static int fs_dict_write_changes(struct dict_transaction_memory_context *ctx) -{ - struct fs_dict *dict = (struct fs_dict *)ctx->ctx.dict; - struct fs_file *file; - const struct dict_transaction_memory_change *change; - const char *key; - int ret = 0; - - array_foreach(&ctx->changes, change) { - key = fs_dict_get_full_key(dict, change->key); - switch (change->type) { - case DICT_CHANGE_TYPE_SET: - file = fs_file_init(dict->fs, key, - FS_OPEN_MODE_REPLACE); - if (fs_write(file, change->value.str, strlen(change->value.str)) < 0) { - i_error("fs_write(%s) failed: %s", key, - fs_file_last_error(file)); - ret = -1; - } - fs_file_deinit(&file); - break; - case DICT_CHANGE_TYPE_UNSET: - file = fs_file_init(dict->fs, key, FS_OPEN_MODE_READONLY); - if (fs_delete(file) < 0) { - i_error("fs_delete(%s) failed: %s", key, - fs_file_last_error(file)); - ret = -1; - } - fs_file_deinit(&file); - break; - case DICT_CHANGE_TYPE_APPEND: - case DICT_CHANGE_TYPE_INC: - i_unreached(); - } - if (ret < 0) - return -1; - } - return 0; -} - -static int -fs_dict_transaction_commit(struct dict_transaction_context *_ctx, - bool async ATTR_UNUSED, - dict_transaction_commit_callback_t *callback, - void *context) -{ - struct dict_transaction_memory_context *ctx = - (struct dict_transaction_memory_context *)_ctx; - int ret; - - if (fs_dict_write_changes(ctx) < 0) - ret = -1; - else - ret = 1; - pool_unref(&ctx->pool); - - if (callback != NULL) - callback(ret, context); - return ret; -} - -struct dict dict_driver_fs = { - .name = "fs", - { - fs_dict_init, - fs_dict_deinit, - NULL, - fs_dict_lookup, - fs_dict_iterate_init, - fs_dict_iterate, - fs_dict_iterate_deinit, - fs_dict_transaction_init, - fs_dict_transaction_commit, - dict_transaction_memory_rollback, - dict_transaction_memory_set, - dict_transaction_memory_unset, - NULL, - NULL, - NULL - } -}; diff -Nru dovecot-2.2.22/src/lib-dict/dict-redis.c dovecot-2.2.24/src/lib-dict/dict-redis.c --- dovecot-2.2.22/src/lib-dict/dict-redis.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict/dict-redis.c 2016-04-26 13:01:20.000000000 +0000 @@ -116,7 +116,7 @@ { i_error("redis: Commit timed out in %u.%03u secs", dict->timeout_msecs/1000, dict->timeout_msecs%1000); - io_loop_stop(dict->ioloop); + redis_conn_destroy(&dict->conn.conn); } static void redis_wait(struct redis_dict *dict) @@ -450,7 +450,7 @@ { i_error("redis: Lookup timed out in %u.%03u secs", dict->timeout_msecs/1000, dict->timeout_msecs%1000); - io_loop_stop(dict->ioloop); + redis_conn_destroy(&dict->conn.conn); } static const char * diff -Nru dovecot-2.2.22/src/lib-dict/dict-register.c dovecot-2.2.24/src/lib-dict/dict-register.c --- dovecot-2.2.22/src/lib-dict/dict-register.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict/dict-register.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "dict-private.h" - -static int refcount = 0; - -void dict_drivers_register_builtin(void) -{ - if (refcount++ > 0) - return; - dict_driver_register(&dict_driver_client); - dict_driver_register(&dict_driver_file); - dict_driver_register(&dict_driver_fs); - dict_driver_register(&dict_driver_memcached); - dict_driver_register(&dict_driver_memcached_ascii); - dict_driver_register(&dict_driver_redis); -} - -void dict_drivers_unregister_builtin(void) -{ - if (--refcount > 0) - return; - dict_driver_unregister(&dict_driver_client); - dict_driver_unregister(&dict_driver_file); - dict_driver_unregister(&dict_driver_fs); - dict_driver_unregister(&dict_driver_memcached); - dict_driver_unregister(&dict_driver_memcached_ascii); - dict_driver_unregister(&dict_driver_redis); -} diff -Nru dovecot-2.2.22/src/lib-dict/Makefile.am dovecot-2.2.24/src/lib-dict/Makefile.am --- dovecot-2.2.22/src/lib-dict/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -1,12 +1,9 @@ noinst_LTLIBRARIES = libdict.la noinst_LIBRARIES = libdict_backend.a -dict_drivers = @dict_drivers@ - AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-test \ - -I$(top_srcdir)/src/lib-fs \ -I$(top_srcdir)/src/lib-sql \ -I$(top_srcdir)/src/lib-settings \ $(SQL_CFLAGS) @@ -15,11 +12,9 @@ dict.c \ dict-client.c \ dict-file.c \ - dict-fs.c \ dict-memcached.c \ dict-memcached-ascii.c \ dict-redis.c \ - dict-register.c \ dict-transaction-memory.c libdict_la_SOURCES = \ diff -Nru dovecot-2.2.22/src/lib-dict/Makefile.in dovecot-2.2.24/src/lib-dict/Makefile.in --- dovecot-2.2.22/src/lib-dict/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -119,9 +119,9 @@ $(nodist_libdict_backend_a_OBJECTS) LTLIBRARIES = $(noinst_LTLIBRARIES) libdict_la_LIBADD = -am__objects_1 = dict.lo dict-client.lo dict-file.lo dict-fs.lo \ - dict-memcached.lo dict-memcached-ascii.lo dict-redis.lo \ - dict-register.lo dict-transaction-memory.lo +am__objects_1 = dict.lo dict-client.lo dict-file.lo dict-memcached.lo \ + dict-memcached-ascii.lo dict-redis.lo \ + dict-transaction-memory.lo am_libdict_la_OBJECTS = $(am__objects_1) libdict_la_OBJECTS = $(am_libdict_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -283,7 +283,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -421,7 +423,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-test \ - -I$(top_srcdir)/src/lib-fs \ -I$(top_srcdir)/src/lib-sql \ -I$(top_srcdir)/src/lib-settings \ $(SQL_CFLAGS) @@ -430,11 +431,9 @@ dict.c \ dict-client.c \ dict-file.c \ - dict-fs.c \ dict-memcached.c \ dict-memcached-ascii.c \ dict-redis.c \ - dict-register.c \ dict-transaction-memory.c libdict_la_SOURCES = \ @@ -549,11 +548,9 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-db.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-drivers-register.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-file.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-fs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-memcached-ascii.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-memcached.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-redis.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-register.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-sql-settings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-sql.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-transaction-memory.Plo@am__quote@ diff -Nru dovecot-2.2.22/src/lib-dict-extra/dict-fs.c dovecot-2.2.24/src/lib-dict-extra/dict-fs.c --- dovecot-2.2.22/src/lib-dict-extra/dict-fs.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/dict-fs.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,290 @@ +/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "fs-api.h" +#include "istream.h" +#include "str.h" +#include "dict-transaction-memory.h" +#include "dict-private.h" + +struct fs_dict { + struct dict dict; + struct fs *fs; + char *username; +}; + +struct fs_dict_iterate_context { + struct dict_iterate_context ctx; + const char **paths; + unsigned int path_idx; + enum dict_iterate_flags flags; + pool_t value_pool; + struct fs_iter *fs_iter; + bool failed; +}; + +static int +fs_dict_init(struct dict *driver, const char *uri, + const struct dict_settings *set, + struct dict **dict_r, const char **error_r) +{ + struct fs_settings fs_set; + struct fs *fs; + struct fs_dict *dict; + const char *p, *fs_driver, *fs_args; + + p = strchr(uri, ':'); + if (p == NULL) { + fs_driver = uri; + fs_args = ""; + } else { + fs_driver = t_strdup_until(uri, p); + fs_args = p+1; + } + + memset(&fs_set, 0, sizeof(fs_set)); + fs_set.username = set->username; + fs_set.base_dir = set->base_dir; + if (fs_init(fs_driver, fs_args, &fs_set, &fs, error_r) < 0) + return -1; + + dict = i_new(struct fs_dict, 1); + dict->dict = *driver; + dict->fs = fs; + dict->username = i_strdup(set->username); + + *dict_r = &dict->dict; + return 0; +} + +static void fs_dict_deinit(struct dict *_dict) +{ + struct fs_dict *dict = (struct fs_dict *)_dict; + + fs_deinit(&dict->fs); + i_free(dict->username); + i_free(dict); +} + +static const char *fs_dict_get_full_key(struct fs_dict *dict, const char *key) +{ + if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) + return key + strlen(DICT_PATH_SHARED); + else if (strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE)) == 0) { + return t_strdup_printf("%s/%s", dict->username, + key + strlen(DICT_PATH_PRIVATE)); + } else { + i_unreached(); + } +} + +static int fs_dict_lookup(struct dict *_dict, pool_t pool, + const char *key, const char **value_r) +{ + struct fs_dict *dict = (struct fs_dict *)_dict; + struct fs_file *file; + struct istream *input; + const unsigned char *data; + size_t size; + string_t *str; + int ret; + + file = fs_file_init(dict->fs, fs_dict_get_full_key(dict, key), + FS_OPEN_MODE_READONLY); + input = fs_read_stream(file, IO_BLOCK_SIZE); + i_stream_read(input); + + str = str_new(pool, i_stream_get_data_size(input)+1); + while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { + str_append_n(str, data, size); + i_stream_skip(input, size); + } + i_assert(ret == -1); + + if (input->stream_errno == 0) { + *value_r = str_c(str); + ret = 1; + } else { + *value_r = NULL; + if (input->stream_errno == ENOENT) + ret = 0; + } + + i_stream_unref(&input); + fs_file_deinit(&file); + return ret; +} + +static struct dict_iterate_context * +fs_dict_iterate_init(struct dict *_dict, const char *const *paths, + enum dict_iterate_flags flags) +{ + struct fs_dict *dict = (struct fs_dict *)_dict; + struct fs_dict_iterate_context *iter; + + /* these flags are not supported for now */ + i_assert((flags & DICT_ITERATE_FLAG_RECURSE) == 0); + i_assert((flags & DICT_ITERATE_FLAG_EXACT_KEY) == 0); + i_assert((flags & (DICT_ITERATE_FLAG_SORT_BY_KEY | + DICT_ITERATE_FLAG_SORT_BY_VALUE)) == 0); + + iter = i_new(struct fs_dict_iterate_context, 1); + iter->ctx.dict = _dict; + iter->paths = p_strarray_dup(default_pool, paths); + iter->flags = flags; + iter->value_pool = pool_alloconly_create("iterate value pool", 128); + iter->fs_iter = fs_iter_init(dict->fs, + fs_dict_get_full_key(dict, paths[0]), 0); + return &iter->ctx; +} + +static bool fs_dict_iterate(struct dict_iterate_context *ctx, + const char **key_r, const char **value_r) +{ + struct fs_dict_iterate_context *iter = + (struct fs_dict_iterate_context *)ctx; + struct fs_dict *dict = (struct fs_dict *)ctx->dict; + const char *path; + int ret; + + *key_r = fs_iter_next(iter->fs_iter); + if (*key_r == NULL) { + if (fs_iter_deinit(&iter->fs_iter) < 0) { + iter->failed = TRUE; + return FALSE; + } + if (iter->paths[++iter->path_idx] == NULL) + return FALSE; + path = fs_dict_get_full_key(dict, iter->paths[iter->path_idx]); + iter->fs_iter = fs_iter_init(dict->fs, path, 0); + return fs_dict_iterate(ctx, key_r, value_r); + } + if ((iter->flags & DICT_ITERATE_FLAG_NO_VALUE) != 0) { + *value_r = NULL; + return TRUE; + } + p_clear(iter->value_pool); + path = t_strconcat(iter->paths[iter->path_idx], *key_r, NULL); + if ((ret = fs_dict_lookup(ctx->dict, iter->value_pool, path, value_r)) < 0) { + /* I/O error */ + iter->failed = TRUE; + return FALSE; + } else if (ret == 0) { + /* file was just deleted, just skip to next one */ + return fs_dict_iterate(ctx, key_r, value_r); + } + return TRUE; +} + +static int fs_dict_iterate_deinit(struct dict_iterate_context *ctx) +{ + struct fs_dict_iterate_context *iter = + (struct fs_dict_iterate_context *)ctx; + int ret; + + if (iter->fs_iter != NULL) { + if (fs_iter_deinit(&iter->fs_iter) < 0) + iter->failed = TRUE; + } + ret = iter->failed ? -1 : 0; + + pool_unref(&iter->value_pool); + i_free(iter->paths); + i_free(iter); + return ret; +} + +static struct dict_transaction_context * +fs_dict_transaction_init(struct dict *_dict) +{ + struct dict_transaction_memory_context *ctx; + pool_t pool; + + pool = pool_alloconly_create("file dict transaction", 2048); + ctx = p_new(pool, struct dict_transaction_memory_context, 1); + dict_transaction_memory_init(ctx, _dict, pool); + return &ctx->ctx; +} + +static int fs_dict_write_changes(struct dict_transaction_memory_context *ctx) +{ + struct fs_dict *dict = (struct fs_dict *)ctx->ctx.dict; + struct fs_file *file; + const struct dict_transaction_memory_change *change; + const char *key; + int ret = 0; + + array_foreach(&ctx->changes, change) { + key = fs_dict_get_full_key(dict, change->key); + switch (change->type) { + case DICT_CHANGE_TYPE_SET: + file = fs_file_init(dict->fs, key, + FS_OPEN_MODE_REPLACE); + if (fs_write(file, change->value.str, strlen(change->value.str)) < 0) { + i_error("fs_write(%s) failed: %s", key, + fs_file_last_error(file)); + ret = -1; + } + fs_file_deinit(&file); + break; + case DICT_CHANGE_TYPE_UNSET: + file = fs_file_init(dict->fs, key, FS_OPEN_MODE_READONLY); + if (fs_delete(file) < 0) { + i_error("fs_delete(%s) failed: %s", key, + fs_file_last_error(file)); + ret = -1; + } + fs_file_deinit(&file); + break; + case DICT_CHANGE_TYPE_APPEND: + case DICT_CHANGE_TYPE_INC: + i_unreached(); + } + if (ret < 0) + return -1; + } + return 0; +} + +static int +fs_dict_transaction_commit(struct dict_transaction_context *_ctx, + bool async ATTR_UNUSED, + dict_transaction_commit_callback_t *callback, + void *context) +{ + struct dict_transaction_memory_context *ctx = + (struct dict_transaction_memory_context *)_ctx; + int ret; + + if (fs_dict_write_changes(ctx) < 0) + ret = -1; + else + ret = 1; + pool_unref(&ctx->pool); + + if (callback != NULL) + callback(ret, context); + return ret; +} + +struct dict dict_driver_fs = { + .name = "fs", + { + fs_dict_init, + fs_dict_deinit, + NULL, + fs_dict_lookup, + fs_dict_iterate_init, + fs_dict_iterate, + fs_dict_iterate_deinit, + fs_dict_transaction_init, + fs_dict_transaction_commit, + dict_transaction_memory_rollback, + dict_transaction_memory_set, + dict_transaction_memory_unset, + NULL, + NULL, + NULL + } +}; diff -Nru dovecot-2.2.22/src/lib-dict-extra/dict-ldap.c dovecot-2.2.24/src/lib-dict-extra/dict-ldap.c --- dovecot-2.2.22/src/lib-dict-extra/dict-ldap.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/dict-ldap.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,475 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING memcached */ + +#include "lib.h" +#include "array.h" +#include "module-dir.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "var-expand.h" +#include "connection.h" +#include "llist.h" +#include "ldap-client.h" +#include "dict.h" +#include "dict-private.h" +#include "dict-ldap-settings.h" + +struct ldap_dict; + +struct dict_ldap_op { + struct ldap_dict *dict; + const struct dict_ldap_map *map; + pool_t pool; + unsigned long txid; + struct dict_lookup_result res; + dict_lookup_callback_t *callback; + void *callback_ctx; +}; + +struct ldap_dict { + struct dict dict; + struct dict_ldap_settings *set; + + const char *uri; + const char *username; + const char *base_dn; + enum ldap_scope scope; + + pool_t pool; + + struct ldap_client *client; + struct ioloop *ioloop, *prev_ioloop; + + unsigned long last_txid; + unsigned int pending; + + struct ldap_dict *prev,*next; +}; + +static +struct ldap_dict *ldap_dict_list; + +static +void ldap_dict_lookup_async(struct dict *dict, const char *key, + dict_lookup_callback_t *callback, void *context); + + +static bool +dict_ldap_map_match(const struct dict_ldap_map *map, const char *path, + ARRAY_TYPE(const_string) *values, unsigned int *pat_len_r, + unsigned int *path_len_r, bool partial_ok, bool recurse) +{ + const char *path_start = path; + const char *pat, *attribute, *p; + unsigned int len; + + array_clear(values); + pat = map->pattern; + while (*pat != '\0' && *path != '\0') { + if (*pat == '$') { + /* variable */ + pat++; + if (*pat == '\0') { + /* pattern ended with this variable, + it'll match the rest of the path */ + len = strlen(path); + if (partial_ok) { + /* iterating - the last field never + matches fully. if there's a trailing + '/', drop it. */ + pat--; + if (path[len-1] == '/') { + attribute = t_strndup(path, len-1); + array_append(values, &attribute, 1); + } else { + array_append(values, &path, 1); + } + } else { + array_append(values, &path, 1); + path += len; + } + *path_len_r = path - path_start; + *pat_len_r = pat - map->pattern; + return TRUE; + } + /* pattern matches until the next '/' in path */ + p = strchr(path, '/'); + if (p != NULL) { + attribute = t_strdup_until(path, p); + array_append(values, &attribute, 1); + path = p; + } else { + /* no '/' anymore, but it'll still match a + partial */ + array_append(values, &path, 1); + path += strlen(path); + pat++; + } + } else if (*pat == *path) { + pat++; + path++; + } else { + return FALSE; + } + } + + *path_len_r = path - path_start; + *pat_len_r = pat - map->pattern; + + if (*pat == '\0') + return *path == '\0'; + else if (!partial_ok) + return FALSE; + else { + /* partial matches must end with '/'. */ + if (pat != map->pattern && pat[-1] != '/') + return FALSE; + /* if we're not recursing, there should be only one $variable + left. */ + if (recurse) + return TRUE; + return pat[0] == '$' && strchr(pat, '/') == NULL; + } +} + +static const struct dict_ldap_map * +ldap_dict_find_map(struct ldap_dict *dict, const char *path, + ARRAY_TYPE(const_string) *values) +{ + const struct dict_ldap_map *maps; + unsigned int i, count, len; + + t_array_init(values, dict->set->max_attribute_count); + maps = array_get(&dict->set->maps, &count); + for (i = 0; i < count; i++) { + if (dict_ldap_map_match(&maps[i], path, values, + &len, &len, FALSE, FALSE)) + return &maps[i]; + } + return NULL; +} + +static +int dict_ldap_connect(struct ldap_dict *dict, const char **error_r) +{ + struct ldap_client_settings set; + memset(&set, 0, sizeof(set)); + set.uri = dict->set->uri; + set.bind_dn = dict->set->bind_dn; + set.password = dict->set->password; + set.timeout_secs = dict->set->timeout; + set.max_idle_time_secs = dict->set->max_idle_time; + set.debug = dict->set->debug; + set.require_ssl = dict->set->require_ssl; + set.start_tls = dict->set->start_tls; + return ldap_client_init(&set, &dict->client, error_r); +} + +static +const char* ldap_dict_build_query(struct ldap_dict *dict, const struct dict_ldap_map *map, ARRAY_TYPE(const_string) *values, bool priv) +{ + const char *template; + ARRAY(struct var_expand_table) exp; + struct var_expand_table entry; + string_t *query = t_str_new(64); + + t_array_init(&exp, 8); + entry.key = '\0'; + entry.value = dict->username; + entry.long_key = "username"; + array_append(&exp, &entry, 1); + + if (priv) { + template = t_strdup_printf("(&(%s=%s)%s)", map->username_attribute, "%{username}", map->filter); + } else { + template = map->filter; + } + + for(size_t i = 0; i < array_count(values) && i < array_count(&(map->ldap_attributes)); i++) { + struct var_expand_table entry; + entry.value = *array_idx(values, i); + entry.long_key = *array_idx(&(map->ldap_attributes), i); + array_append(&exp, &entry, 1); + } + + array_append_zero(&exp); + + var_expand(query, template, array_idx(&exp, 0)); + + return str_c(query); +} + +static +int ldap_dict_create(struct dict *dict_driver, const char *uri, + const struct dict_settings *set, + struct dict **dict_r, const char **error_r) +{ + pool_t pool = pool_alloconly_create("ldap dict", 2048); + struct ldap_dict *dict = p_new(pool, struct ldap_dict, 1); + dict->pool = pool; + dict->dict = *dict_driver; + dict->username = p_strdup(pool, set->username); + dict->uri = p_strdup(pool, uri); + dict->set = dict_ldap_settings_read(pool, uri, error_r); + + if (dict->set == NULL) { + pool_unref(&pool); + return -1; + } + + if (dict_ldap_connect(dict, error_r) < 0) { + pool_unref(&pool); + return -1; + } + + *dict_r = (struct dict*)dict; + *error_r = NULL; + + DLLIST_PREPEND(&ldap_dict_list, dict); + + return 0; +} + +static +int ldap_dict_init(struct dict *dict_driver, const char *uri, + const struct dict_settings *set, + struct dict **dict_r, const char **error_r) +{ + /* reuse possible existing entry */ + for(struct ldap_dict *ptr = ldap_dict_list; + ptr != NULL; + ptr = ptr->next) { + if (strcmp(ptr->uri, uri) == 0) { + *dict_r = (struct dict*)ptr; + return 0; + } + } + return ldap_dict_create(dict_driver, uri, set, dict_r, error_r); +} + +static +void ldap_dict_deinit(struct dict *dict ATTR_UNUSED) { +} + +static +int ldap_dict_wait(struct dict *dict) { + struct ldap_dict *ctx = (struct ldap_dict *)dict; + + i_assert(ctx->ioloop == NULL); + + ctx->prev_ioloop = current_ioloop; + ctx->ioloop = io_loop_create(); + ldap_client_switch_ioloop(ctx->client); + + do { + io_loop_run(current_ioloop); + } while (ctx->pending > 0); + + io_loop_set_current(ctx->prev_ioloop); + ldap_client_switch_ioloop(ctx->client); + io_loop_set_current(ctx->ioloop); + io_loop_destroy(&ctx->ioloop); + ctx->prev_ioloop = NULL; + + return 0; +} + +static +void ldap_dict_lookup_done(const struct dict_lookup_result *result, void *ctx) +{ + struct dict_lookup_result *res = ctx; + *res = *result; +} + +static void +ldap_dict_lookup_callback(struct ldap_result *result, struct dict_ldap_op *op) +{ + pool_t pool = op->pool; + struct ldap_search_iterator *iter; + const struct ldap_entry *entry; + + op->dict->pending--; + + if (ldap_result_has_failed(result)) { + op->res.ret = -1; + op->res.error = ldap_result_get_error(result); + } else { + iter = ldap_search_iterator_init(result); + entry = ldap_search_iterator_next(iter); + if (entry != NULL) { + if (op->dict->set->debug > 0) + i_debug("ldap_dict_lookup_callback got dn %s", ldap_entry_dn(entry)); + /* try extract value */ + const char *const *values = ldap_entry_get_attribute(entry, op->map->value_attribute); + if (values != NULL) { + if (op->dict->set->debug > 0) + i_debug("ldap_dict_lookup_callback got attribute %s", op->map->value_attribute); + op->res.ret = 1; + op->res.value = p_strdup(op->pool, values[0]); + } else { + if (op->dict->set->debug > 0) + i_debug("ldap_dict_lookup_callback dit not get attribute %s", op->map->value_attribute); + op->res.value = NULL; + } + } + ldap_search_iterator_deinit(&iter); + } + op->callback(&(op->res), op->callback_ctx); + pool_unref(&pool); +} + +static +int ldap_dict_lookup(struct dict *dict, pool_t pool, + const char *key, const char **value_r) +{ + struct dict_lookup_result res; + pool_t orig_pool = pool; + int ret; + + T_BEGIN { + ldap_dict_lookup_async(dict, key, ldap_dict_lookup_done, &res); + + if ((ret = ldap_dict_wait(dict)) == 0) { + if (res.ret == 0) { + *value_r = p_strdup(orig_pool, res.value); + } else ret = res.ret; + } + } T_END; + return ret; +} + +/* +static +struct dict_iterate_context *ldap_dict_iterate_init(struct dict *dict, + const char *const *paths, + enum dict_iterate_flags flags) +{ + return NULL; +} + +static +bool ldap_dict_iterate(struct dict_iterate_context *ctx, + const char **key_r, const char **value_r) +{ + return FALSE; +} + +static +int ldap_dict_iterate_deinit(struct dict_iterate_context *ctx) +{ + return -1; +} + +static +struct dict_transaction_context ldap_dict_transaction_init(struct dict *dict); + +static +int ldap_dict_transaction_commit(struct dict_transaction_context *ctx, + bool async, + dict_transaction_commit_callback_t *callback, + void *context); +static +void ldap_dict_transaction_rollback(struct dict_transaction_context *ctx); + +static +void ldap_dict_set(struct dict_transaction_context *ctx, + const char *key, const char *value); +static +void ldap_dict_unset(struct dict_transaction_context *ctx, + const char *key); +static +void ldap_dict_append(struct dict_transaction_context *ctx, + const char *key, const char *value); +static +void ldap_dict_atomic_inc(struct dict_transaction_context *ctx, + const char *key, long long diff); +*/ + +static +void ldap_dict_lookup_async(struct dict *dict, const char *key, + dict_lookup_callback_t *callback, void *context) +{ + struct ldap_search_input input; + struct ldap_dict *ctx = (struct ldap_dict*)dict; + struct dict_ldap_op *op; + pool_t oppool = pool_alloconly_create("ldap dict lookup", 64); + op = p_new(oppool, struct dict_ldap_op, 1); + op->pool = oppool; + op->dict = ctx; + op->callback = callback; + op->callback_ctx = context; + op->txid = ctx->last_txid++; + + /* key needs to be transformed into something else */ + ARRAY_TYPE(const_string) values; + T_BEGIN { + const char *attributes[2] = {0, 0}; + t_array_init(&values, 8); + const struct dict_ldap_map *map = ldap_dict_find_map(ctx, key, &values); + + if (map != NULL) { + op->map = map; + attributes[0] = map->value_attribute; + /* build lookup */ + memset(&input, 0, sizeof(input)); + input.base_dn = map->base_dn; + input.scope = map->scope_val; + input.filter = ldap_dict_build_query(ctx, map, &values, strncmp(key, DICT_PATH_PRIVATE, strlen(DICT_PATH_PRIVATE))==0); + input.attributes = attributes; + input.timeout_secs = ctx->set->timeout; + ctx->pending++; + ldap_search_start(ctx->client, &input, ldap_dict_lookup_callback, op); + } else { + op->res.error = "no such key"; + callback(&(op->res), context); + pool_unref(&oppool); + } + } T_END; +} + +struct dict dict_driver_ldap = { + .name = "ldap", + { + ldap_dict_init, + ldap_dict_deinit, + ldap_dict_wait, + ldap_dict_lookup, + NULL, /*ldap_dict_iterate_init,*/ + NULL, /*ldap_dict_iterate,*/ + NULL, /*ldap_dict_iterate_deinit,*/ + NULL, /*ldap_transaction_init,*/ + NULL, /*ldap_transaction_commit,*/ + NULL, /*ldap_transaction_rollback,*/ + NULL, /*ldap_set,*/ + NULL, /*ldap_unset,*/ + NULL, /*ldap_append,*/ + NULL, /*ldap_atomic_inc,*/ + ldap_dict_lookup_async + } +}; + +void dict_ldap_init(struct module *module ATTR_UNUSED); +void dict_ldap_deinit(void); + +void dict_ldap_init(struct module *module ATTR_UNUSED) +{ + dict_driver_register(&dict_driver_ldap); + ldap_dict_list = NULL; +} + +void dict_ldap_deinit(void) +{ + dict_driver_unregister(&dict_driver_ldap); + /* destroy all server connections */ + struct ldap_dict *ptr = ldap_dict_list; + ldap_dict_list = NULL; + + while(ptr != NULL) { + ldap_client_deinit(&(ptr->client)); + pool_t pool = ptr->pool; + ptr = ptr->next; + pool_unref(&pool); + } +} + +const char *dict_ldap_plugin_dependencies[] = { NULL }; diff -Nru dovecot-2.2.22/src/lib-dict-extra/dict-ldap-settings.c dovecot-2.2.24/src/lib-dict-extra/dict-ldap-settings.c --- dovecot-2.2.22/src/lib-dict-extra/dict-ldap-settings.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/dict-ldap-settings.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,308 @@ +/* Copyright (c) 2008-2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "str.h" +#include "settings.h" +#include "dict-ldap-settings.h" + +#include + +static const char *dict_ldap_commonName = "cn"; +static const char *dict_ldap_empty_filter = ""; + +enum section_type { + SECTION_ROOT = 0, + SECTION_MAP, + SECTION_FIELDS +}; + +struct dict_ldap_map_attribute { + const char *name; + const char *variable; +}; + +struct setting_parser_ctx { + pool_t pool; + struct dict_ldap_settings *set; + enum section_type type; + + struct dict_ldap_map cur_map; + ARRAY(struct dict_ldap_map_attribute) cur_attributes; +}; + +#undef DEF_STR +#undef DEF_BOOL +#undef DEF_UINT + +#define DEF_STR(name) DEF_STRUCT_STR(name, dict_ldap_map) +#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, dict_ldap_map) +#define DEF_UINT(name) DEF_STRUCT_UINT(name ,dict_ldap_map) + +static const struct setting_def dict_ldap_map_setting_defs[] = { + DEF_STR(pattern), + DEF_STR(filter), + DEF_STR(filter_iter), + DEF_STR(username_attribute), + DEF_STR(value_attribute), + DEF_STR(base_dn), + DEF_STR(scope), + { 0, NULL, 0 } +}; + +static const char *pattern_read_name(const char **pattern) +{ + const char *p = *pattern, *name; + + if (*p == '{') { + /* ${name} */ + name = ++p; + p = strchr(p, '}'); + if (p == NULL) { + /* error, but allow anyway */ + *pattern += strlen(*pattern); + return ""; + } + *pattern = p + 1; + } else { + /* $name - ends at the first non-alnum_ character */ + name = p; + for (; *p != '\0'; p++) { + if (!i_isalnum(*p) && *p != '_') + break; + } + *pattern = p; + } + name = t_strdup_until(name, p); + return name; +} + +static const char *dict_ldap_attributes_map(struct setting_parser_ctx *ctx) +{ + struct dict_ldap_map_attribute *attributes; + string_t *pattern; + const char *p, *name; + unsigned int i, count; + + /* go through the variables in the pattern, replace them with plain + '$' character and add its ldap attribute */ + pattern = t_str_new(strlen(ctx->cur_map.pattern) + 1); + attributes = array_get_modifiable(&ctx->cur_attributes, &count); + + p_array_init(&ctx->cur_map.ldap_attributes, ctx->pool, count); + for (p = ctx->cur_map.pattern; *p != '\0';) { + if (*p != '$') { + str_append_c(pattern, *p); + p++; + continue; + } + p++; + str_append_c(pattern, '$'); + + name = pattern_read_name(&p); + for (i = 0; i < count; i++) { + if (attributes[i].variable != NULL && + strcmp(attributes[i].variable, name) == 0) + break; + } + if (i == count) { + return t_strconcat("Missing LDAP attribute for variable: ", + name, NULL); + } + + /* mark this attribute as used */ + attributes[i].variable = NULL; + array_append(&ctx->cur_map.ldap_attributes, + &attributes[i].name, 1); + } + + /* make sure there aren't any unused attributes */ + for (i = 0; i < count; i++) { + if (attributes[i].variable != NULL) { + return t_strconcat("Unused variable: ", + attributes[i].variable, NULL); + } + } + + if (ctx->set->max_attribute_count < count) + ctx->set->max_attribute_count = count; + ctx->cur_map.pattern = p_strdup(ctx->pool, str_c(pattern)); + return NULL; +} + +static const char *dict_ldap_map_finish(struct setting_parser_ctx *ctx) +{ + if (ctx->cur_map.pattern == NULL) + return "Missing setting: pattern"; + if (ctx->cur_map.filter == NULL) + ctx->cur_map.filter = dict_ldap_empty_filter; + if (*ctx->cur_map.filter != '\0') { + const char *ptr = ctx->cur_map.filter; + if (*ptr != '(') + return "Filter must start with ("; + while(*ptr != '\0') ptr++; + ptr--; + if (*ptr != ')') + return "Filter must end with )"; + } + if (ctx->cur_map.value_attribute == NULL) + return "Missing setting: value_attribute"; + + if (ctx->cur_map.username_attribute == NULL) { + /* default to commonName */ + ctx->cur_map.username_attribute = dict_ldap_commonName; + } + if (ctx->cur_map.scope == NULL) { + ctx->cur_map.scope_val = 2; /* subtree */ + } else { + if (!strcasecmp(ctx->cur_map.scope, "one")) ctx->cur_map.scope_val = 1; + else if (!strcasecmp(ctx->cur_map.scope, "base")) ctx->cur_map.scope_val = 0; + else if (!strcasecmp(ctx->cur_map.scope, "subtree")) ctx->cur_map.scope_val = 2; + else return "Scope must be one, base or subtree"; + } + if (!array_is_created(&ctx->cur_map.ldap_attributes)) { + /* no attributes besides value. allocate the array anyway. */ + p_array_init(&ctx->cur_map.ldap_attributes, ctx->pool, 1); + if (strchr(ctx->cur_map.pattern, '$') != NULL) + return "Missing attributes for pattern variables"; + } + array_append(&ctx->set->maps, &ctx->cur_map, 1); + memset(&ctx->cur_map, 0, sizeof(ctx->cur_map)); + return NULL; +} + +static const char * +parse_setting(const char *key, const char *value, + struct setting_parser_ctx *ctx) +{ + struct dict_ldap_map_attribute *attribute; + + switch (ctx->type) { + case SECTION_ROOT: + if (strcmp(key, "uri") == 0) { + ctx->set->uri = p_strdup(ctx->pool, value); + return NULL; + } + if (strcmp(key, "bind_dn") == 0) { + ctx->set->bind_dn = p_strdup(ctx->pool, value); + return NULL; + } + if (strcmp(key, "password") == 0) { + ctx->set->password = p_strdup(ctx->pool, value); + return NULL; + } + if (strcmp(key, "timeout") == 0) { + if (str_to_uint(value, &ctx->set->timeout) != 0) { + return "Invalid timeout value"; + } + return NULL; + } + if (strcmp(key, "max_idle_time") == 0) { + if (str_to_uint(value, &ctx->set->max_idle_time) != 0) { + return "Invalid max_idle_time value"; + } + return NULL; + } + if (strcmp(key, "debug") == 0) { + if (str_to_uint(value, &ctx->set->debug) != 0) { + return "invalid debug value"; + } + return NULL; + } + if (strcmp(key, "tls") == 0) { + if (strcasecmp(value, "yes") == 0) { + ctx->set->require_ssl = TRUE; + ctx->set->start_tls = TRUE; + } else if (strcasecmp(value, "no") == 0) { + ctx->set->require_ssl = FALSE; + ctx->set->start_tls = FALSE; + } else if (strcasecmp(value, "try") == 0) { + ctx->set->require_ssl = FALSE; + ctx->set->start_tls = TRUE; + } else { + return "tls must be yes, try or no"; + } + return NULL; + } + break; + case SECTION_MAP: + return parse_setting_from_defs(ctx->pool, + dict_ldap_map_setting_defs, + &ctx->cur_map, key, value); + case SECTION_FIELDS: + if (*value != '$') { + return t_strconcat("Value is missing '$' for attribute: ", + key, NULL); + } + attribute = array_append_space(&ctx->cur_attributes); + attribute->name = p_strdup(ctx->pool, key); + attribute->variable = p_strdup(ctx->pool, value + 1); + return NULL; + } + return t_strconcat("Unknown setting: ", key, NULL); +} + +static bool +parse_section(const char *type, const char *name ATTR_UNUSED, + struct setting_parser_ctx *ctx, const char **error_r) +{ + switch (ctx->type) { + case SECTION_ROOT: + if (type == NULL) + return FALSE; + if (strcmp(type, "map") == 0) { + array_clear(&ctx->cur_attributes); + ctx->type = SECTION_MAP; + return TRUE; + } + break; + case SECTION_MAP: + if (type == NULL) { + ctx->type = SECTION_ROOT; + *error_r = dict_ldap_map_finish(ctx); + return FALSE; + } + if (strcmp(type, "fields") == 0) { + ctx->type = SECTION_FIELDS; + return TRUE; + } + break; + case SECTION_FIELDS: + if (type == NULL) { + ctx->type = SECTION_MAP; + *error_r = dict_ldap_attributes_map(ctx); + return FALSE; + } + break; + } + *error_r = t_strconcat("Unknown section: ", type, NULL); + return FALSE; +} + +struct dict_ldap_settings * +dict_ldap_settings_read(pool_t pool, const char *path, const char **error_r) +{ + struct setting_parser_ctx ctx; + + memset(&ctx, 0, sizeof(ctx)); + ctx.pool = pool; + ctx.set = p_new(pool, struct dict_ldap_settings, 1); + t_array_init(&ctx.cur_attributes, 16); + p_array_init(&ctx.set->maps, pool, 8); + + ctx.set->timeout = 30; /* default timeout */ + ctx.set->require_ssl = FALSE; /* try to start SSL */ + ctx.set->start_tls = TRUE; + + if (!settings_read(path, NULL, parse_setting, parse_section, + &ctx, error_r)) + return NULL; + + if (ctx.set->uri == NULL) { + *error_r = t_strdup_printf("Error in configuration file %s: " + "Missing ldap uri", path); + return NULL; + } + + return ctx.set; +} diff -Nru dovecot-2.2.22/src/lib-dict-extra/dict-ldap-settings.h dovecot-2.2.24/src/lib-dict-extra/dict-ldap-settings.h --- dovecot-2.2.22/src/lib-dict-extra/dict-ldap-settings.h 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/dict-ldap-settings.h 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,36 @@ +#ifndef DICT_LDAP_SETTINGS_H +#define DICT_LDAP_SETTINGS_H + +struct dict_ldap_map { + /* pattern is in simplified form: all variables are stored as simple + '$' character. fields array is sorted by the variable index. */ + const char *pattern; + const char *filter; + const char *filter_iter; + const char *username_attribute; + const char *value_attribute; + const char *base_dn; + const char *scope; + int scope_val; + unsigned int timeout; + + ARRAY_TYPE(const_string) ldap_attributes; +}; + +struct dict_ldap_settings { + const char *uri; + const char *bind_dn; + const char *password; + unsigned int timeout; + unsigned int max_idle_time; + unsigned int debug; + unsigned int max_attribute_count; + bool require_ssl; + bool start_tls; + ARRAY(struct dict_ldap_map) maps; +}; + +struct dict_ldap_settings * +dict_ldap_settings_read(pool_t pool, const char *path, const char **error_r); + +#endif diff -Nru dovecot-2.2.22/src/lib-dict-extra/dict-register.c dovecot-2.2.24/src/lib-dict-extra/dict-register.c --- dovecot-2.2.22/src/lib-dict-extra/dict-register.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/dict-register.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,30 @@ +/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "dict-private.h" + +static int refcount = 0; + +void dict_drivers_register_builtin(void) +{ + if (refcount++ > 0) + return; + dict_driver_register(&dict_driver_client); + dict_driver_register(&dict_driver_file); + dict_driver_register(&dict_driver_fs); + dict_driver_register(&dict_driver_memcached); + dict_driver_register(&dict_driver_memcached_ascii); + dict_driver_register(&dict_driver_redis); +} + +void dict_drivers_unregister_builtin(void) +{ + if (--refcount > 0) + return; + dict_driver_unregister(&dict_driver_client); + dict_driver_unregister(&dict_driver_file); + dict_driver_unregister(&dict_driver_fs); + dict_driver_unregister(&dict_driver_memcached); + dict_driver_unregister(&dict_driver_memcached_ascii); + dict_driver_unregister(&dict_driver_redis); +} diff -Nru dovecot-2.2.22/src/lib-dict-extra/Makefile.am dovecot-2.2.24/src/lib-dict-extra/Makefile.am --- dovecot-2.2.22/src/lib-dict-extra/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,32 @@ +noinst_LTLIBRARIES = libdict_extra.la + +dict_drivers = @dict_drivers@ + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-dict \ + -I$(top_srcdir)/src/lib-fs \ + -I$(top_srcdir)/src/lib-ldap \ + -I$(top_srcdir)/src/lib-settings + +libdict_extra_la_SOURCES = \ + dict-fs.c \ + dict-register.c + +NOPLUGIN_LDFLAGS = + +if HAVE_LDAP +LIBDICT_LDAP = libdict_ldap.la +endif +libdict_ldap_la_LDFLAGS = -module -avoid-version $(LIBDOVECOT_LDAP) + +module_dictdir = $(moduledir)/dict +module_dict_LTLIBRARIES = \ + $(LIBDICT_LDAP) + +libdict_ldap_la_SOURCES = \ + dict-ldap.c \ + dict-ldap-settings.c + +noinst_HEADERS = \ + dict-ldap-settings.h diff -Nru dovecot-2.2.22/src/lib-dict-extra/Makefile.in dovecot-2.2.24/src/lib-dict-extra/Makefile.in --- dovecot-2.2.22/src/lib-dict-extra/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-dict-extra/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -0,0 +1,765 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/lib-dict-extra +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/dovecot.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(module_dictdir)" +LTLIBRARIES = $(module_dict_LTLIBRARIES) $(noinst_LTLIBRARIES) +libdict_extra_la_LIBADD = +am_libdict_extra_la_OBJECTS = dict-fs.lo dict-register.lo +libdict_extra_la_OBJECTS = $(am_libdict_extra_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libdict_ldap_la_LIBADD = +am_libdict_ldap_la_OBJECTS = dict-ldap.lo dict-ldap-settings.lo +libdict_ldap_la_OBJECTS = $(am_libdict_ldap_la_OBJECTS) +libdict_ldap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libdict_ldap_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +@HAVE_LDAP_TRUE@am_libdict_ldap_la_rpath = -rpath $(module_dictdir) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdict_extra_la_SOURCES) $(libdict_ldap_la_SOURCES) +DIST_SOURCES = $(libdict_extra_la_SOURCES) $(libdict_ldap_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTH_CFLAGS = @AUTH_CFLAGS@ +AUTH_LIBS = @AUTH_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CASSANDRA_CFLAGS = @CASSANDRA_CFLAGS@ +CASSANDRA_LIBS = @CASSANDRA_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CDB_LIBS = @CDB_LIBS@ +CFLAGS = @CFLAGS@ +CLUCENE_CFLAGS = @CLUCENE_CFLAGS@ +CLUCENE_LIBS = @CLUCENE_LIBS@ +COMPRESS_LIBS = @COMPRESS_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPT_LIBS = @CRYPT_LIBS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DICT_LIBS = @DICT_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KRB5CONFIG = @KRB5CONFIG@ +KRB5_CFLAGS = @KRB5_CFLAGS@ +KRB5_LIBS = @KRB5_LIBS@ +LD = @LD@ +LDAP_LIBS = @LDAP_LIBS@ +LDFLAGS = @LDFLAGS@ +LIBCAP = @LIBCAP@ +LIBDOVECOT = @LIBDOVECOT@ +LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ +LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ +LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ +LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ +LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ +LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ +LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ +LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ +LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ +LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ +LIBEXTTEXTCAT_CFLAGS = @LIBEXTTEXTCAT_CFLAGS@ +LIBEXTTEXTCAT_LIBS = @LIBEXTTEXTCAT_LIBS@ +LIBICONV = @LIBICONV@ +LIBICU_CFLAGS = @LIBICU_CFLAGS@ +LIBICU_LIBS = @LIBICU_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LINKED_STORAGE_LDADD = @LINKED_STORAGE_LDADD@ +LINKED_STORAGE_LIBS = @LINKED_STORAGE_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MODULE_LIBS = @MODULE_LIBS@ +MODULE_SUFFIX = @MODULE_SUFFIX@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOPLUGIN_LDFLAGS = +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +QUOTA_LIBS = @QUOTA_LIBS@ +RANLIB = @RANLIB@ +RPCGEN = @RPCGEN@ +RUN_TEST = @RUN_TEST@ +SED = @SED@ +SETTING_FILES = @SETTING_FILES@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CFLAGS = @SQLITE_CFLAGS@ +SQLITE_LIBS = @SQLITE_LIBS@ +SQL_CFLAGS = @SQL_CFLAGS@ +SQL_LIBS = @SQL_LIBS@ +SSL_CFLAGS = @SSL_CFLAGS@ +SSL_LIBS = @SSL_LIBS@ +STRIP = @STRIP@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dict_drivers = @dict_drivers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mail_storages = @mail_storages@ +mailbox_list_drivers = @mailbox_list_drivers@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +rundir = @rundir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sql_drivers = @sql_drivers@ +srcdir = @srcdir@ +ssldir = @ssldir@ +statedir = @statedir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libdict_extra.la +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-dict \ + -I$(top_srcdir)/src/lib-fs \ + -I$(top_srcdir)/src/lib-ldap \ + -I$(top_srcdir)/src/lib-settings + +libdict_extra_la_SOURCES = \ + dict-fs.c \ + dict-register.c + +@HAVE_LDAP_TRUE@LIBDICT_LDAP = libdict_ldap.la +libdict_ldap_la_LDFLAGS = -module -avoid-version $(LIBDOVECOT_LDAP) +module_dictdir = $(moduledir)/dict +module_dict_LTLIBRARIES = \ + $(LIBDICT_LDAP) + +libdict_ldap_la_SOURCES = \ + dict-ldap.c \ + dict-ldap-settings.c + +noinst_HEADERS = \ + dict-ldap-settings.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib-dict-extra/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib-dict-extra/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-module_dictLTLIBRARIES: $(module_dict_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(module_dict_LTLIBRARIES)'; test -n "$(module_dictdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(module_dictdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(module_dictdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(module_dictdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(module_dictdir)"; \ + } + +uninstall-module_dictLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(module_dict_LTLIBRARIES)'; test -n "$(module_dictdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(module_dictdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(module_dictdir)/$$f"; \ + done + +clean-module_dictLTLIBRARIES: + -test -z "$(module_dict_LTLIBRARIES)" || rm -f $(module_dict_LTLIBRARIES) + @list='$(module_dict_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdict_extra.la: $(libdict_extra_la_OBJECTS) $(libdict_extra_la_DEPENDENCIES) $(EXTRA_libdict_extra_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libdict_extra_la_OBJECTS) $(libdict_extra_la_LIBADD) $(LIBS) + +libdict_ldap.la: $(libdict_ldap_la_OBJECTS) $(libdict_ldap_la_DEPENDENCIES) $(EXTRA_libdict_ldap_la_DEPENDENCIES) + $(AM_V_CCLD)$(libdict_ldap_la_LINK) $(am_libdict_ldap_la_rpath) $(libdict_ldap_la_OBJECTS) $(libdict_ldap_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-fs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-ldap-settings.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-ldap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-register.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(module_dictdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-module_dictLTLIBRARIES \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-module_dictLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-module_dictLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-module_dictLTLIBRARIES \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-module_dictLTLIBRARIES install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-module_dictLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru dovecot-2.2.22/src/lib-dns/Makefile.in dovecot-2.2.24/src/lib-dns/Makefile.in --- dovecot-2.2.22/src/lib-dns/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dns/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-dovecot/Makefile.am dovecot-2.2.24/src/lib-dovecot/Makefile.am --- dovecot-2.2.22/src/lib-dovecot/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dovecot/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -1,28 +1,10 @@ -# when adding libraries, update LIBDOVECOT also in configure.in -libs = \ - ../lib-master/libmaster.la \ - ../lib-fs/libfs.la \ - ../lib-settings/libsettings.la \ - ../lib-stats/libstats.la \ - ../lib-http/libhttp.la \ - ../lib-dict/libdict.la \ - ../lib-imap/libimap.la \ - ../lib-mail/libmail.la \ - ../lib-sasl/libsasl.la \ - ../lib-auth/libauth.la \ - ../lib-dns/libdns.la \ - ../lib-charset/libcharset.la \ - ../lib-ssl-iostream/libssl_iostream.la \ - ../lib-test/libtest.la \ - ../lib/liblib.la - pkglib_LTLIBRARIES = libdovecot.la libdovecot_la_SOURCES = libdovecot_la_LIBADD = \ - $(libs) \ + $(LIBDOVECOT_LA_LIBS) \ $(MODULE_LIBS) -libdovecot_la_DEPENDENCIES = $(libs) +libdovecot_la_DEPENDENCIES = $(LIBDOVECOT_LA_LIBS) libdovecot_la_LDFLAGS = -export-dynamic diff -Nru dovecot-2.2.22/src/lib-dovecot/Makefile.in dovecot-2.2.24/src/lib-dovecot/Makefile.in --- dovecot-2.2.22/src/lib-dovecot/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-dovecot/Makefile.in 2016-04-26 14:29:25.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -369,32 +371,13 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ - -# when adding libraries, update LIBDOVECOT also in configure.in -libs = \ - ../lib-master/libmaster.la \ - ../lib-fs/libfs.la \ - ../lib-settings/libsettings.la \ - ../lib-stats/libstats.la \ - ../lib-http/libhttp.la \ - ../lib-dict/libdict.la \ - ../lib-imap/libimap.la \ - ../lib-mail/libmail.la \ - ../lib-sasl/libsasl.la \ - ../lib-auth/libauth.la \ - ../lib-dns/libdns.la \ - ../lib-charset/libcharset.la \ - ../lib-ssl-iostream/libssl_iostream.la \ - ../lib-test/libtest.la \ - ../lib/liblib.la - pkglib_LTLIBRARIES = libdovecot.la libdovecot_la_SOURCES = libdovecot_la_LIBADD = \ - $(libs) \ + $(LIBDOVECOT_LA_LIBS) \ $(MODULE_LIBS) -libdovecot_la_DEPENDENCIES = $(libs) +libdovecot_la_DEPENDENCIES = $(LIBDOVECOT_LA_LIBS) libdovecot_la_LDFLAGS = -export-dynamic all: all-am diff -Nru dovecot-2.2.22/src/lib-fs/fs-api.c dovecot-2.2.24/src/lib-fs/fs-api.c --- dovecot-2.2.22/src/lib-fs/fs-api.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-api.c 2016-04-26 13:01:20.000000000 +0000 @@ -74,6 +74,7 @@ fs_class_register(&fs_class_metawrap); fs_class_register(&fs_class_sis); fs_class_register(&fs_class_sis_queue); + fs_class_register(&fs_class_test); lib_atexit(fs_classes_deinit); } diff -Nru dovecot-2.2.22/src/lib-fs/fs-api-private.h dovecot-2.2.24/src/lib-fs/fs-api-private.h --- dovecot-2.2.22/src/lib-fs/fs-api-private.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-api-private.h 2016-04-26 13:01:20.000000000 +0000 @@ -145,6 +145,7 @@ extern const struct fs fs_class_metawrap; extern const struct fs fs_class_sis; extern const struct fs fs_class_sis_queue; +extern const struct fs fs_class_test; void fs_class_register(const struct fs *fs_class); diff -Nru dovecot-2.2.22/src/lib-fs/fs-metawrap.c dovecot-2.2.24/src/lib-fs/fs-metawrap.c --- dovecot-2.2.22/src/lib-fs/fs-metawrap.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-metawrap.c 2016-04-26 13:01:20.000000000 +0000 @@ -199,14 +199,30 @@ const ARRAY_TYPE(fs_metadata) **metadata_r) { struct metawrap_fs_file *file = (struct metawrap_fs_file *)_file; + ssize_t ret; char c; if (!file->fs->wrap_metadata) return fs_get_metadata(file->super, metadata_r); - if (!file->metadata_read) { + if (file->metadata_read) { + /* we have the metadata */ + } else if (file->input == NULL) { if (fs_read(_file, &c, 1) < 0) return -1; + } else { + /* use the existing istream to read it */ + while ((ret = i_stream_read(file->input)) == 0) { + if (file->metadata_read) + break; + + i_assert(!file->input->blocking); + if (fs_wait_async(_file->fs) < 0) + return -1; + } + if (ret == -1) + return -1; + i_assert(file->metadata_read); } *metadata_r = &_file->metadata; return 0; @@ -469,7 +485,12 @@ return 0; } - input = fs_read_stream(_file, IO_BLOCK_SIZE); + if (file->input == NULL) + input = fs_read_stream(_file, IO_BLOCK_SIZE); + else { + input = file->input; + i_stream_ref(input); + } if ((ret = i_stream_get_size(input, TRUE, &input_size)) < 0) { fs_set_error(_file->fs, "i_stream_get_size(%s) failed: %s", fs_file_path(_file), i_stream_get_error(input)); diff -Nru dovecot-2.2.22/src/lib-fs/fs-posix.c dovecot-2.2.24/src/lib-fs/fs-posix.c --- dovecot-2.2.22/src/lib-fs/fs-posix.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-posix.c 2016-04-26 13:01:20.000000000 +0000 @@ -47,7 +47,6 @@ buffer_t *write_buf; bool seek_to_beginning; - bool success; }; struct posix_fs_lock { @@ -345,7 +344,7 @@ case FS_OPEN_MODE_CREATE_UNIQUE_128: case FS_OPEN_MODE_CREATE: case FS_OPEN_MODE_REPLACE: - if (file->success || file->temp_path == NULL) + if (file->temp_path == NULL) break; /* failed to create/replace this. delete the temp file */ if (unlink(file->temp_path) < 0) { @@ -432,7 +431,7 @@ static int fs_posix_write_finish(struct posix_fs_file *file) { - int ret; + int ret, old_errno; if ((file->open_flags & FS_OPEN_FLAG_FSYNC) != 0) { if (fdatasync(file->fd) < 0) { @@ -449,10 +448,12 @@ fs_set_error(file->file.fs, "link(%s, %s) failed: %m", file->temp_path, file->full_path); } + old_errno = errno; if (unlink(file->temp_path) < 0) { fs_set_error(file->file.fs, "unlink(%s) failed: %m", file->temp_path); } + errno = old_errno; if (ret < 0) { fs_posix_file_close(&file->file); i_free_and_null(file->temp_path); @@ -470,7 +471,6 @@ i_unreached(); } i_free_and_null(file->temp_path); - file->success = TRUE; file->seek_to_beginning = TRUE; /* allow opening the file after writing to it */ file->open_mode = FS_OPEN_MODE_READONLY; diff -Nru dovecot-2.2.22/src/lib-fs/fs-test.c dovecot-2.2.24/src/lib-fs/fs-test.c --- dovecot-2.2.22/src/lib-fs/fs-test.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-test.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,355 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "istream.h" +#include "ostream.h" +#include "test-common.h" +#include "fs-test.h" + +static struct fs *fs_test_alloc(void) +{ + struct test_fs *fs; + + fs = i_new(struct test_fs, 1); + fs->fs = fs_class_test; + i_array_init(&fs->iter_files, 32); + return &fs->fs; +} + +static int +fs_test_init(struct fs *_fs ATTR_UNUSED, const char *args ATTR_UNUSED, + const struct fs_settings *set ATTR_UNUSED) +{ + return 0; +} + +static void fs_test_deinit(struct fs *_fs) +{ + struct test_fs *fs = (struct test_fs *)_fs; + + array_free(&fs->iter_files); + i_free(fs); +} + +static enum fs_properties fs_test_get_properties(struct fs *_fs) +{ + struct test_fs *fs = (struct test_fs *)_fs; + + return fs->properties; +} + +static struct fs_file * +fs_test_file_init(struct fs *_fs, const char *path, + enum fs_open_mode mode, enum fs_open_flags flags ATTR_UNUSED) +{ + struct test_fs_file *file; + + file = i_new(struct test_fs_file, 1); + file->file.fs = _fs; + file->file.path = i_strdup(path); + file->mode = mode; + file->contents = buffer_create_dynamic(default_pool, 1024); + file->exists = TRUE; + file->seekable = TRUE; + return &file->file; +} + +static void fs_test_file_deinit(struct fs_file *_file) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + buffer_free(&file->contents); + i_free(file->file.path); + i_free(file); +} + +static void fs_test_file_close(struct fs_file *_file) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + file->closed = TRUE; +} + +static const char *fs_test_file_get_path(struct fs_file *_file) +{ + return _file->path; +} + +static void +fs_test_set_async_callback(struct fs_file *_file, + fs_file_async_callback_t *callback, + void *context) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + file->async_callback = callback; + file->async_context = context; +} + +static int fs_test_wait_async(struct fs *_fs ATTR_UNUSED) +{ + return 0; +} + +static void +fs_test_set_metadata(struct fs_file *_file, const char *key, + const char *value) +{ + fs_default_set_metadata(_file, key, value); +} + +static int +fs_test_get_metadata(struct fs_file *_file, + const ARRAY_TYPE(fs_metadata) **metadata_r) +{ + fs_metadata_init(_file); + *metadata_r = &_file->metadata; + return 0; +} + +static bool fs_test_prefetch(struct fs_file *_file ATTR_UNUSED, + uoff_t length ATTR_UNUSED) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + file->prefetched = TRUE; + return TRUE; +} + +static void fs_test_stream_destroyed(struct test_fs_file *file) +{ + i_assert(file->input != NULL); + file->input = NULL; +} + +static struct istream * +fs_test_read_stream(struct fs_file *_file, size_t max_buffer_size ATTR_UNUSED) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + struct istream *input; + + i_assert(file->input == NULL); + + if (!file->exists) + return i_stream_create_error(ENOENT); + input = test_istream_create_data(file->contents->data, + file->contents->used); + i_stream_add_destroy_callback(input, fs_test_stream_destroyed, file); + if (!file->seekable) + input->seekable = FALSE; + file->input = input; + return input; +} + +static void fs_test_write_stream(struct fs_file *_file) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + i_assert(_file->output == NULL); + + buffer_set_used_size(file->contents, 0); + _file->output = o_stream_create_buffer(file->contents); +} + +static int fs_test_write_stream_finish(struct fs_file *_file, bool success) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + if (!success) + buffer_set_used_size(file->contents, 0); + return success ? 1 : -1; +} + +static int +fs_test_lock(struct fs_file *_file, unsigned int secs ATTR_UNUSED, + struct fs_lock **lock_r) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + if (file->locked) + return 0; + file->locked = TRUE; + *lock_r = i_new(struct fs_lock, 1); + (*lock_r)->file = _file; + return 1; +} + +static void fs_test_unlock(struct fs_lock *lock) +{ + struct test_fs_file *file = (struct test_fs_file *)lock->file; + + file->locked = FALSE; + i_free(lock); +} + +static int fs_test_exists(struct fs_file *_file) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + return file->exists ? 1 : 0; +} + +static int fs_test_stat(struct fs_file *_file, struct stat *st_r) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + if (!file->exists) { + errno = ENOENT; + return -1; + } + memset(st_r, 0, sizeof(*st_r)); + st_r->st_size = file->contents->used; + return 0; +} + +static int fs_test_copy(struct fs_file *_src, struct fs_file *_dest) +{ + struct test_fs_file *src = (struct test_fs_file *)_src; + struct test_fs_file *dest = (struct test_fs_file *)_dest; + + if (!src->exists) { + errno = ENOENT; + return -1; + } + buffer_set_used_size(dest->contents, 0); + buffer_append_buf(dest->contents, src->contents, 0, (size_t)-1); + dest->exists = TRUE; + return 0; +} + +static int fs_test_rename(struct fs_file *_src, struct fs_file *_dest) +{ + struct test_fs_file *src = (struct test_fs_file *)_src; + + if (fs_test_copy(_src, _dest) < 0) + return -1; + src->exists = FALSE; + return 0; +} + +static int fs_test_delete(struct fs_file *_file) +{ + struct test_fs_file *file = (struct test_fs_file *)_file; + + if (!file->exists) { + errno = ENOENT; + return -1; + } + return 0; +} + +static struct fs_iter * +fs_test_iter_init(struct fs *_fs, const char *path, + enum fs_iter_flags flags) +{ + struct test_fs *fs = (struct test_fs *)_fs; + struct test_fs_iter *iter; + + iter = i_new(struct test_fs_iter, 1); + iter->iter.fs = _fs; + iter->iter.flags = flags; + iter->prefix = i_strdup(path); + iter->prefix_len = strlen(iter->prefix); + iter->prev_dir = i_strdup(""); + array_sort(&fs->iter_files, i_strcmp_p); + return &iter->iter; +} + +static const char *fs_test_iter_next(struct fs_iter *_iter) +{ + struct test_fs_iter *iter = (struct test_fs_iter *)_iter; + struct test_fs *fs = (struct test_fs *)_iter->fs; + const char *const *files, *p; + unsigned int count, len, prev_dir_len = strlen(iter->prev_dir); + + files = array_get(&fs->iter_files, &count); + for (; iter->idx < count; iter->idx++) { + const char *fname = files[iter->idx]; + + if (strncmp(fname, iter->prefix, iter->prefix_len) != 0) + continue; + p = strrchr(fname, '/'); + if ((_iter->flags & FS_ITER_FLAG_DIRS) == 0) { + if (p == NULL) + return fname; + if (p[1] == '\0') + continue; /* dir/ */ + return p+1; + } + + if (p == NULL) + continue; + len = p - fname; + if (len == 0) + continue; + if (len == prev_dir_len && + strncmp(fname, iter->prev_dir, len) == 0) + continue; + i_free(iter->prev_dir); + iter->prev_dir = i_strndup(fname, len); + return iter->prev_dir; + } + return NULL; +} + +static int fs_test_iter_deinit(struct fs_iter *_iter) +{ + struct test_fs_iter *iter = (struct test_fs_iter *)_iter; + int ret = iter->failed ? -1 : 0; + + i_free(iter->prefix); + i_free(iter); + return ret; +} + +struct test_fs_file *test_fs_file_get(struct fs *fs, unsigned int n) +{ + struct fs_file *file; + + while (strcmp(fs->name, "test") != 0) { + i_assert(fs->parent != NULL); + fs = fs->parent; + } + + file = fs->files; + for (; n > 0; n--) { + i_assert(file != NULL); + file = file->next; + } + i_assert(file != NULL); + return (struct test_fs_file *)file; +} + +const struct fs fs_class_test = { + .name = "test", + .v = { + fs_test_alloc, + fs_test_init, + fs_test_deinit, + fs_test_get_properties, + fs_test_file_init, + fs_test_file_deinit, + fs_test_file_close, + fs_test_file_get_path, + fs_test_set_async_callback, + fs_test_wait_async, + fs_test_set_metadata, + fs_test_get_metadata, + fs_test_prefetch, + NULL, + fs_test_read_stream, + NULL, + fs_test_write_stream, + fs_test_write_stream_finish, + fs_test_lock, + fs_test_unlock, + fs_test_exists, + fs_test_stat, + fs_test_copy, + fs_test_rename, + fs_test_delete, + fs_test_iter_init, + fs_test_iter_next, + fs_test_iter_deinit + } +}; diff -Nru dovecot-2.2.22/src/lib-fs/fs-test.h dovecot-2.2.24/src/lib-fs/fs-test.h --- dovecot-2.2.22/src/lib-fs/fs-test.h 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/fs-test.h 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,38 @@ +#ifndef FS_TEST_H +#define FS_TEST_H + +#include "fs-api-private.h" + +struct test_fs { + struct fs fs; + enum fs_properties properties; + ARRAY_TYPE(const_string) iter_files; +}; + +struct test_fs_file { + struct fs_file file; + enum fs_open_mode mode; + + fs_file_async_callback_t *async_callback; + void *async_context; + + buffer_t *contents; + struct istream *input; + + bool prefetched; + bool locked; + bool exists; + bool seekable; + bool closed; +}; + +struct test_fs_iter { + struct fs_iter iter; + char *prefix, *prev_dir; + unsigned int prefix_len, idx; + bool failed; +}; + +struct test_fs_file *test_fs_file_get(struct fs *fs, unsigned int n); + +#endif diff -Nru dovecot-2.2.22/src/lib-fs/Makefile.am dovecot-2.2.24/src/lib-fs/Makefile.am --- dovecot-2.2.22/src/lib-fs/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -2,6 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-ssl-iostream \ -DMODULE_DIR=\""$(moduledir)"\" @@ -12,6 +13,7 @@ fs-metawrap.c \ fs-randomfail.c \ fs-posix.c \ + fs-test.c \ fs-sis.c \ fs-sis-common.c \ fs-sis-queue.c \ @@ -25,6 +27,7 @@ fs-api.h \ fs-api-private.h \ fs-sis-common.h \ + fs-test.h \ istream-fs-file.h \ istream-fs-stats.h \ istream-metawrap.h \ @@ -33,3 +36,28 @@ pkginc_libdir=$(pkgincludedir) pkginc_lib_HEADERS = $(headers) + +noinst_PROGRAMS = $(test_programs) + +test_programs = \ + test-fs-metawrap + +test_deps = \ + $(noinst_LTLIBRARIES) \ + ../lib-dict/libdict.la \ + ../lib-test/libtest.la \ + ../lib/liblib.la + +test_libs = \ + $(test_deps) \ + $(MODULE_LIBS) + +test_fs_metawrap_SOURCES = test-fs-metawrap.c +test_fs_metawrap_LDADD = $(test_libs) +test_fs_metawrap_DEPENDENCIES = $(test_deps) + +check: check-am check-test +check-test: all-am + for bin in $(test_programs); do \ + if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ + done diff -Nru dovecot-2.2.22/src/lib-fs/Makefile.in dovecot-2.2.24/src/lib-fs/Makefile.in --- dovecot-2.2.22/src/lib-fs/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -15,6 +15,7 @@ @SET_MAKE@ + VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -89,6 +90,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +noinst_PROGRAMS = $(am__EXEEXT_1) subdir = src/lib-fs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/dovecot.m4 \ @@ -104,14 +106,21 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) libfs_la_LIBADD = am_libfs_la_OBJECTS = fs-api.lo fs-dict.lo fs-metawrap.lo \ - fs-randomfail.lo fs-posix.lo fs-sis.lo fs-sis-common.lo \ - fs-sis-queue.lo istream-fs-file.lo istream-fs-stats.lo \ - istream-metawrap.lo ostream-metawrap.lo ostream-cmp.lo + fs-randomfail.lo fs-posix.lo fs-test.lo fs-sis.lo \ + fs-sis-common.lo fs-sis-queue.lo istream-fs-file.lo \ + istream-fs-stats.lo istream-metawrap.lo ostream-metawrap.lo \ + ostream-cmp.lo libfs_la_OBJECTS = $(am_libfs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +am__EXEEXT_1 = test-fs-metawrap$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_test_fs_metawrap_OBJECTS = test-fs-metawrap.$(OBJEXT) +test_fs_metawrap_OBJECTS = $(am_test_fs_metawrap_OBJECTS) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(test_deps) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -146,8 +155,8 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libfs_la_SOURCES) -DIST_SOURCES = $(libfs_la_SOURCES) +SOURCES = $(libfs_la_SOURCES) $(test_fs_metawrap_SOURCES) +DIST_SOURCES = $(libfs_la_SOURCES) $(test_fs_metawrap_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -260,7 +269,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -396,6 +407,7 @@ noinst_LTLIBRARIES = libfs.la AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-ssl-iostream \ -DMODULE_DIR=\""$(moduledir)"\" @@ -406,6 +418,7 @@ fs-metawrap.c \ fs-randomfail.c \ fs-posix.c \ + fs-test.c \ fs-sis.c \ fs-sis-common.c \ fs-sis-queue.c \ @@ -419,6 +432,7 @@ fs-api.h \ fs-api-private.h \ fs-sis-common.h \ + fs-test.h \ istream-fs-file.h \ istream-fs-stats.h \ istream-metawrap.h \ @@ -427,6 +441,22 @@ pkginc_libdir = $(pkgincludedir) pkginc_lib_HEADERS = $(headers) +test_programs = \ + test-fs-metawrap + +test_deps = \ + $(noinst_LTLIBRARIES) \ + ../lib-dict/libdict.la \ + ../lib-test/libtest.la \ + ../lib/liblib.la + +test_libs = \ + $(test_deps) \ + $(MODULE_LIBS) + +test_fs_metawrap_SOURCES = test-fs-metawrap.c +test_fs_metawrap_LDADD = $(test_libs) +test_fs_metawrap_DEPENDENCIES = $(test_deps) all: all-am .SUFFIXES: @@ -475,6 +505,19 @@ libfs.la: $(libfs_la_OBJECTS) $(libfs_la_DEPENDENCIES) $(EXTRA_libfs_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libfs_la_OBJECTS) $(libfs_la_LIBADD) $(LIBS) +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +test-fs-metawrap$(EXEEXT): $(test_fs_metawrap_OBJECTS) $(test_fs_metawrap_DEPENDENCIES) $(EXTRA_test_fs_metawrap_DEPENDENCIES) + @rm -f test-fs-metawrap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_fs_metawrap_OBJECTS) $(test_fs_metawrap_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -489,11 +532,13 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-sis-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-sis-queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-sis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-test.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/istream-fs-file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/istream-fs-stats.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/istream-metawrap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-cmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ostream-metawrap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fs-metawrap.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -627,7 +672,7 @@ done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkginc_libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -665,7 +710,7 @@ clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am + clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -736,23 +781,29 @@ .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-pkginc_libHEADERS install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-pkginc_libHEADERS + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkginc_libHEADERS install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkginc_libHEADERS .PRECIOUS: Makefile +check: check-am check-test +check-test: all-am + for bin in $(test_programs); do \ + if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ + done + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru dovecot-2.2.22/src/lib-fs/test-fs-metawrap.c dovecot-2.2.24/src/lib-fs/test-fs-metawrap.c --- dovecot-2.2.22/src/lib-fs/test-fs-metawrap.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-fs/test-fs-metawrap.c 2016-04-26 13:01:20.000000000 +0000 @@ -0,0 +1,56 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "istream.h" +#include "fs-test.h" +#include "test-common.h" + +static void test_fs_metawrap_stat(void) +{ + struct fs_settings fs_set; + struct fs *fs; + struct fs_file *file; + struct test_fs_file *test_file; + struct istream *input; + struct stat st; + const char *error; + unsigned int i; + + test_begin("fs metawrap stat"); + + memset(&fs_set, 0, sizeof(fs_set)); + if (fs_init("metawrap", "test", &fs_set, &fs, &error) < 0) + i_fatal("fs_init() failed: %s", error); + + for (i = 0; i < 2; i++) { + file = fs_file_init(fs, "foo", FS_OPEN_MODE_READONLY); + + test_file = test_fs_file_get(fs, 0); + str_append(test_file->contents, "key:value\n\n12345678901234567890"); + + if (i == 0) { + input = fs_read_stream(file, 2); + test_istream_set_max_buffer_size(test_file->input, 2); + } else { + input = NULL; + } + + test_assert_idx(fs_stat(file, &st) == 0 && st.st_size == 20, i); + + if (input != NULL) + i_stream_unref(&input); + fs_file_deinit(&file); + } + fs_deinit(&fs); + test_end(); +} + +int main(void) +{ + static void (*test_functions[])(void) = { + test_fs_metawrap_stat, + NULL + }; + return test_run(test_functions); +} diff -Nru dovecot-2.2.22/src/lib-fts/Makefile.in dovecot-2.2.24/src/lib-fts/Makefile.in --- dovecot-2.2.22/src/lib-fts/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-fts/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -305,7 +305,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-http/http-client-connection.c dovecot-2.2.24/src/lib-http/http-client-connection.c --- dovecot-2.2.22/src/lib-http/http-client-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-client-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -353,10 +353,13 @@ static void http_client_connection_continue_timeout(struct http_client_connection *conn) { - struct http_client_request *const *req_idx; + struct http_client_request *const *wait_reqs; struct http_client_request *req; + unsigned int wait_count; const char *error; + i_assert(conn->pending_request == NULL); + if (conn->to_response != NULL) timeout_remove(&conn->to_response); conn->peer->no_payload_sync = TRUE; @@ -364,13 +367,12 @@ http_client_connection_debug(conn, "Expected 100-continue response timed out; sending payload anyway"); - i_assert(array_count(&conn->request_wait_list) > 0); - req_idx = array_idx(&conn->request_wait_list, - array_count(&conn->request_wait_list)-1); - req = req_idx[0]; + wait_reqs = array_get(&conn->request_wait_list, &wait_count); + i_assert(wait_count == 1); + req = wait_reqs[wait_count-1]; req->payload_sync_continue = TRUE; - if (http_client_request_send_more(req, &error) < 0) { + if (http_client_request_send_more(req, FALSE, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, t_strdup_printf("Failed to send request: %s", error)); @@ -381,7 +383,7 @@ { struct http_client_request *req = NULL; const char *error; - bool have_pending_requests; + bool pipelined; if (!http_client_connection_is_ready(conn)) { http_client_connection_debug(conn, "Not ready for next request"); @@ -389,9 +391,9 @@ } /* claim request, but no urgent request can be second in line */ - have_pending_requests = array_count(&conn->request_wait_list) > 0 || + pipelined = array_count(&conn->request_wait_list) > 0 || conn->pending_request != NULL; - req = http_client_peer_claim_request(conn->peer, have_pending_requests); + req = http_client_peer_claim_request(conn->peer, pipelined); if (req == NULL) return 0; @@ -411,7 +413,7 @@ http_client_connection_debug(conn, "Claimed request %s", http_client_request_label(req)); - if (http_client_request_send(req, &error) < 0) { + if (http_client_request_send(req, pipelined, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, t_strdup_printf("Failed to send request: %s", error)); @@ -431,6 +433,7 @@ indefinite period before sending the message body. */ if (req->payload_sync && !conn->peer->seen_100_response) { + i_assert(!pipelined); i_assert(req->payload_chunked || req->payload_size > 0); i_assert(conn->to_response == NULL); conn->to_response = timeout_add(HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS, @@ -485,6 +488,8 @@ timeout_remove(&conn->to_input); conn->conn.io = io_add_istream(conn->conn.input, http_client_connection_input, &conn->conn); + if (array_count(&conn->request_wait_list) > 0) + http_client_connection_start_request_timeout(conn); } static void @@ -762,7 +767,7 @@ return; } - if (http_client_request_send_more(req, &error) < 0) { + if (http_client_request_send_more(req, FALSE, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, t_strdup_printf("Failed to send request: %s", error)); @@ -889,7 +894,6 @@ payload_type = http_client_request_get_payload_type(req); } else { /* no more requests waiting for the connection */ - http_client_connection_stop_request_timeout(conn); req = NULL; payload_type = HTTP_RESPONSE_PAYLOAD_TYPE_ALLOWED; } @@ -964,6 +968,7 @@ reqs = array_get(&conn->request_wait_list, &count); if (count > 0 && conn->output_locked) { struct http_client_request *req = reqs[count-1]; + bool pipelined = (count > 1 || conn->pending_request != NULL); if (req->state == HTTP_REQUEST_STATE_ABORTED) { http_client_connection_debug(conn, @@ -978,7 +983,7 @@ } if (!req->payload_sync || req->payload_sync_continue) { - if (http_client_request_send_more(req, &error) < 0) { + if (http_client_request_send_more(req, pipelined, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, t_strdup_printf("Connection lost: %s", error)); diff -Nru dovecot-2.2.22/src/lib-http/http-client.h dovecot-2.2.24/src/lib-http/http-client.h --- dovecot-2.2.22/src/lib-http/http-client.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-client.h 2016-04-26 13:01:20.000000000 +0000 @@ -194,6 +194,7 @@ void http_client_request_set_ssl(struct http_client_request *req, bool ssl); void http_client_request_set_urgent(struct http_client_request *req); +void http_client_request_set_preserve_exact_reason(struct http_client_request *req); void http_client_request_add_header(struct http_client_request *req, const char *key, const char *value); @@ -204,6 +205,8 @@ void http_client_request_set_payload(struct http_client_request *req, struct istream *input, bool sync); +void http_client_request_set_payload_data(struct http_client_request *req, + const unsigned char *data, size_t size); void http_client_request_set_timeout_msecs(struct http_client_request *req, unsigned int msecs); diff -Nru dovecot-2.2.22/src/lib-http/http-client-peer.c dovecot-2.2.24/src/lib-http/http-client-peer.c --- dovecot-2.2.22/src/lib-http/http-client-peer.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-client-peer.c 2016-04-26 13:01:20.000000000 +0000 @@ -275,17 +275,22 @@ peer->handling_requests = TRUE; t_array_init(&conns_avail, array_count(&peer->conns)); do { + bool conn_lost = FALSE; + array_clear(&conns_avail); connecting = closing = idle = 0; /* gather connection statistics */ array_foreach(&peer->conns, conn_idx) { - if (http_client_connection_is_ready(*conn_idx)) { + struct http_client_connection *conn = *conn_idx; + + http_client_connection_ref(conn); + if (http_client_connection_is_ready(conn)) { struct _conn_available *conn_avail; unsigned int insert_idx, pending_requests; /* compile sorted availability list */ - pending_requests = http_client_connection_count_pending(*conn_idx); + pending_requests = http_client_connection_count_pending(conn); if (array_count(&conns_avail) == 0) { insert_idx = 0; } else { @@ -298,18 +303,28 @@ } } conn_avail = array_insert_space(&conns_avail, insert_idx); - conn_avail->conn = *conn_idx; + conn_avail->conn = conn; conn_avail->pending_requests = pending_requests; if (pending_requests == 0) idle++; } + if (!http_client_connection_unref(&conn)) { + conn_lost = TRUE; + break; + } + conn = *conn_idx; /* count the number of connecting and closing connections */ - if ((*conn_idx)->closing) + if (conn->closing) closing++; - else if (!(*conn_idx)->connected) + else if (!conn->connected) connecting++; } + if (conn_lost) { + /* connection array changed while iterating; retry */ + continue; + } + working_conn_count = array_count(&peer->conns) - closing; statistics_dirty = FALSE; diff -Nru dovecot-2.2.22/src/lib-http/http-client-private.h dovecot-2.2.24/src/lib-http/http-client-private.h --- dovecot-2.2.22/src/lib-http/http-client-private.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-client-private.h 2016-04-26 13:01:20.000000000 +0000 @@ -122,6 +122,7 @@ unsigned int connect_tunnel:1; unsigned int connect_direct:1; unsigned int ssl_tunnel:1; + unsigned int preserve_exact_reason:1; }; struct http_client_connection { @@ -282,9 +283,9 @@ enum http_response_payload_type http_client_request_get_payload_type(struct http_client_request *req); int http_client_request_send(struct http_client_request *req, - const char **error_r); + bool pipelined, const char **error_r); int http_client_request_send_more(struct http_client_request *req, - const char **error_r); + bool pipelined, const char **error_r); bool http_client_request_callback(struct http_client_request *req, struct http_response *response); void http_client_request_connect_callback(struct http_client_request *req, diff -Nru dovecot-2.2.22/src/lib-http/http-client-request.c dovecot-2.2.24/src/lib-http/http-client-request.c --- dovecot-2.2.22/src/lib-http/http-client-request.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-client-request.c 2016-04-26 13:01:20.000000000 +0000 @@ -246,6 +246,11 @@ req->urgent = TRUE; } +void http_client_request_set_preserve_exact_reason(struct http_client_request *req) +{ + req->preserve_exact_reason = TRUE; +} + void http_client_request_add_header(struct http_client_request *req, const char *key, const char *value) { @@ -356,6 +361,23 @@ req->payload_sync = TRUE; } +void http_client_request_set_payload_data(struct http_client_request *req, + const unsigned char *data, size_t size) +{ + struct istream *input; + unsigned char *payload_data; + + if (size == 0) + return; + + payload_data = p_malloc(req->pool, size); + memcpy(payload_data, data, size); + input = i_stream_create_from_data(payload_data, size); + + http_client_request_set_payload(req, input, FALSE); + i_stream_unref(&input); +} + void http_client_request_set_timeout_msecs(struct http_client_request *req, unsigned int msecs) { @@ -748,7 +770,7 @@ } int http_client_request_send_more(struct http_client_request *req, - const char **error_r) + bool pipelined, const char **error_r) { struct http_client_connection *conn = req->conn; struct ostream *output = req->payload_output; @@ -804,6 +826,7 @@ if (req->payload_wait) { /* this chunk of input is finished (client needs to act; disable timeout) */ + i_assert(!pipelined); conn->output_locked = TRUE; http_client_connection_stop_request_timeout(conn); if (req->client->ioloop != NULL) @@ -815,13 +838,15 @@ } else if (i_stream_get_data_size(req->payload_input) > 0) { /* output is blocking (server needs to act; enable timeout) */ conn->output_locked = TRUE; - http_client_connection_start_request_timeout(conn); + if (!pipelined) + http_client_connection_start_request_timeout(conn); o_stream_set_flush_pending(output, TRUE); http_client_request_debug(req, "Partially sent payload"); } else { /* input is blocking (client needs to act; disable timeout) */ conn->output_locked = TRUE; - http_client_connection_stop_request_timeout(conn); + if (!pipelined) + http_client_connection_stop_request_timeout(conn); conn->io_req_payload = io_add_istream(req->payload_input, http_client_request_payload_input, req); } @@ -829,7 +854,7 @@ } static int http_client_request_send_real(struct http_client_request *req, - const char **error_r) + bool pipelined, const char **error_r) { const struct http_client_settings *set = &req->client->set; struct http_client_connection *conn = req->conn; @@ -946,7 +971,8 @@ if (req->payload_output != NULL) { if (!req->payload_sync) { - if (http_client_request_send_more(req, error_r) < 0) + if (http_client_request_send_more + (req, pipelined, error_r) < 0) ret = -1; } else { http_client_request_debug(req, "Waiting for 100-continue"); @@ -954,7 +980,8 @@ } } else { req->state = HTTP_REQUEST_STATE_WAITING; - http_client_connection_start_request_timeout(req->conn); + if (!pipelined) + http_client_connection_start_request_timeout(req->conn); conn->output_locked = FALSE; } if (ret >= 0 && o_stream_flush(output) < 0) { @@ -969,13 +996,13 @@ } int http_client_request_send(struct http_client_request *req, - const char **error_r) + bool pipelined, const char **error_r) { char *errstr = NULL; int ret; T_BEGIN { - ret = http_client_request_send_real(req, error_r); + ret = http_client_request_send_real(req, pipelined, error_r); if (ret < 0) errstr = i_strdup(*error_r); } T_END; @@ -994,7 +1021,18 @@ req->callback = NULL; if (callback != NULL) { - callback(response, req->context); + struct http_response response_copy = *response; + + if (req->attempts > 0 && !req->preserve_exact_reason) { + unsigned int total_msecs = + timeval_diff_msecs(&ioloop_timeval, &req->submit_time); + response_copy.reason = t_strdup_printf( + "%s (%u attempts in %u.%03u secs)", + response_copy.reason, req->attempts, + total_msecs/1000, total_msecs%1000); + } + + callback(&response_copy, req->context); if (req->attempts != orig_attempts) { /* retrying */ req->callback = callback; diff -Nru dovecot-2.2.22/src/lib-http/http-server-connection.c dovecot-2.2.24/src/lib-http/http-server-connection.c --- dovecot-2.2.22/src/lib-http/http-server-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-server-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -602,6 +602,8 @@ conn->close_indicated = TRUE; if (req->destroy_pending) http_server_request_destroy(&req); + else + http_server_request_unref(&req); if (conn->closed) { /* connection got closed in destroy callback */ diff -Nru dovecot-2.2.22/src/lib-http/http-server-request.c dovecot-2.2.24/src/lib-http/http-server-request.c --- dovecot-2.2.22/src/lib-http/http-server-request.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/http-server-request.c 2016-04-26 13:01:20.000000000 +0000 @@ -128,6 +128,9 @@ struct http_server_request *req = *_req; struct http_server_connection *conn = req->conn; + if (req->state >= HTTP_SERVER_REQUEST_STATE_FINISHED) + return; + http_server_request_debug(req, "Abort"); req->conn = NULL; diff -Nru dovecot-2.2.22/src/lib-http/Makefile.in dovecot-2.2.24/src/lib-http/Makefile.in --- dovecot-2.2.22/src/lib-http/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-http/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -329,7 +329,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-imap/Makefile.in dovecot-2.2.24/src/lib-imap/Makefile.in --- dovecot-2.2.22/src/lib-imap/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -290,7 +290,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-imap-client/imapc-client.c dovecot-2.2.24/src/lib-imap-client/imapc-client.c --- dovecot-2.2.22/src/lib-imap-client/imapc-client.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-client/imapc-client.c 2016-04-26 13:01:20.000000000 +0000 @@ -277,6 +277,9 @@ conn->box = box; box->conn = conn->conn; box->msgmap = imapc_msgmap_init(); + /* if we get disconnected before the SELECT is finished, allow + one reconnect retry. */ + box->reconnect_ok = TRUE; return box; } @@ -300,7 +303,6 @@ if (reply->state == IMAPC_COMMAND_STATE_OK) { /* reopen the mailbox */ box->reopen_callback(box->reopen_context); - imapc_connection_set_reconnected(box->conn); } else { imapc_connection_abort_commands(box->conn, NULL, FALSE); } @@ -316,21 +318,16 @@ void imapc_client_mailbox_reconnect(struct imapc_client_mailbox *box) { - bool reconnect = imapc_client_mailbox_can_reconnect(box); + i_assert(!box->reconnecting); - if (reconnect) { - i_assert(!box->reconnecting); - box->reconnecting = TRUE; - } - imapc_connection_disconnect(box->conn); - if (reconnect) { - imapc_connection_connect(box->conn, - imapc_client_reconnect_cb, box); - } + box->reconnecting = TRUE; /* if we fail again, avoid reconnecting immediately. if the server is broken we could just get into an infinitely failing reconnection loop. */ box->reconnect_ok = FALSE; + + imapc_connection_disconnect(box->conn); + imapc_connection_connect(box->conn, imapc_client_reconnect_cb, box); } void imapc_client_mailbox_close(struct imapc_client_mailbox **_box) diff -Nru dovecot-2.2.22/src/lib-imap-client/imapc-connection.c dovecot-2.2.24/src/lib-imap-client/imapc-connection.c --- dovecot-2.2.22/src/lib-imap-client/imapc-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-client/imapc-connection.c 2016-04-26 13:01:20.000000000 +0000 @@ -125,6 +125,7 @@ struct timeval throttle_end_timeval; struct timeout *to_throttle, *to_throttle_shrink; + unsigned int reconnecting:1; unsigned int idling:1; unsigned int idle_stopping:1; unsigned int idle_plus_waiting:1; @@ -329,7 +330,8 @@ i_free_and_null(conn->disconnect_reason); } reply.text_without_resp = reply.text_full; - imapc_login_callback(conn, &reply); + if (!conn->reconnecting) + imapc_login_callback(conn, &reply); conn->idling = FALSE; conn->idle_plus_waiting = FALSE; @@ -367,10 +369,13 @@ literal->fd = -1; } -void imapc_connection_disconnect(struct imapc_connection *conn) +static void imapc_connection_disconnect_full(struct imapc_connection *conn, + bool reconnecting) { - bool reconnecting = conn->selected_box != NULL && - conn->selected_box->reconnecting; + /* timeout may be set also in disconnected state */ + if (conn->to != NULL) + timeout_remove(&conn->to); + conn->reconnecting = reconnecting; if (conn->state == IMAPC_CONNECTION_STATE_DISCONNECTED) return; @@ -382,8 +387,6 @@ dns_lookup_abort(&conn->dns_lookup); imapc_connection_lfiles_free(conn); imapc_connection_literal_reset(&conn->literal); - if (conn->to != NULL) - timeout_remove(&conn->to); if (conn->to_output != NULL) timeout_remove(&conn->to_output); if (conn->to_throttle != NULL) @@ -416,6 +419,11 @@ imapc_connection_abort_commands(conn, NULL, reconnecting); } +void imapc_connection_disconnect(struct imapc_connection *conn) +{ + imapc_connection_disconnect_full(conn, FALSE); +} + static void imapc_connection_set_disconnected(struct imapc_connection *conn) { imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); @@ -427,15 +435,35 @@ if (conn->selected_box != NULL) return imapc_client_mailbox_can_reconnect(conn->selected_box); else - return FALSE; + return conn->reconnect_command_count == 0; } static void imapc_connection_reconnect(struct imapc_connection *conn) { if (conn->selected_box != NULL) imapc_client_mailbox_reconnect(conn->selected_box); - else + else { + imapc_connection_disconnect_full(conn, TRUE); + imapc_connection_connect(conn, NULL, NULL); + } +} + +static void +imapc_connection_try_reconnect(struct imapc_connection *conn, + const char *errstr, unsigned int delay_msecs) +{ + if (!imapc_connection_can_reconnect(conn)) { + i_error("imapc(%s): %s - disconnecting", conn->name, errstr); imapc_connection_disconnect(conn); + } else { + i_warning("imapc(%s): %s - reconnecting", conn->name, errstr); + if (delay_msecs == 0) + imapc_connection_reconnect(conn); + else { + imapc_connection_disconnect_full(conn, TRUE); + conn->to = timeout_add(delay_msecs, imapc_connection_reconnect, conn); + } + } } static void ATTR_FORMAT(2, 3) @@ -1333,7 +1361,8 @@ imapc_connection_unselect(conn->selected_box); } - if (conn->reconnect_command_count > 0) { + if (conn->reconnect_command_count > 0 && + (cmd->flags & IMAPC_COMMAND_FLAG_PRELOGIN) == 0) { if (--conn->reconnect_command_count == 0) { /* we've received replies for all the commands started before reconnection. if we get disconnected now, we @@ -1428,11 +1457,7 @@ str_printfa(str, "Server disconnected unexpectedly: %s", errstr); } - if (!imapc_connection_can_reconnect(conn)) - i_error("imapc(%s): %s", conn->name, str_c(str)); - else - i_warning("imapc(%s): %s - reconnecting", conn->name, str_c(str)); - imapc_connection_reconnect(conn); + imapc_connection_try_reconnect(conn, str_c(str), 0); } imapc_connection_unref(&conn); } @@ -1525,10 +1550,10 @@ err = net_geterror(conn->fd); if (err != 0) { - i_error("imapc(%s): connect(%s, %u) failed: %s", - conn->name, net_ip2addr(ip), conn->client->set.port, - strerror(err)); - imapc_connection_disconnect(conn); + imapc_connection_try_reconnect(conn, t_strdup_printf( + "connect(%s, %u) failed: %s", + net_ip2addr(ip), conn->client->set.port, + strerror(err)), IMAPC_CONNECT_RETRY_WAIT_MSECS); return; } io_remove(&conn->io); @@ -1543,21 +1568,22 @@ static void imapc_connection_timeout(struct imapc_connection *conn) { const struct ip_addr *ip = &conn->ips[conn->prev_connect_idx]; + const char *errstr; switch (conn->state) { case IMAPC_CONNECTION_STATE_CONNECTING: - i_error("imapc(%s): connect(%s, %u) timed out after %u seconds", - conn->name, net_ip2addr(ip), conn->client->set.port, + errstr = t_strdup_printf("connect(%s, %u) timed out after %u seconds", + net_ip2addr(ip), conn->client->set.port, conn->client->set.connect_timeout_msecs/1000); break; case IMAPC_CONNECTION_STATE_AUTHENTICATING: - i_error("imapc(%s): Authentication timed out after %u seconds", - conn->name, conn->client->set.connect_timeout_msecs/1000); + errstr = t_strdup_printf("Authentication timed out after %u seconds", + conn->client->set.connect_timeout_msecs/1000); break; default: i_unreached(); } - imapc_connection_disconnect(conn); + imapc_connection_try_reconnect(conn, errstr, 0); } static void @@ -1675,9 +1701,14 @@ i_assert(login_callback == NULL); return; } - i_assert(conn->login_callback == NULL); + i_assert(conn->login_callback == NULL || conn->reconnecting); conn->login_callback = login_callback; conn->login_context = login_context; + conn->reconnecting = FALSE; + /* if we get disconnected before we've finished all the pending + commands, don't reconnect */ + conn->reconnect_command_count = array_count(&conn->cmd_wait_list) + + array_count(&conn->cmd_send_queue); imapc_connection_input_reset(conn); @@ -1789,26 +1820,12 @@ { struct imapc_command *const *cmds; unsigned int count; - string_t *str = t_str_new(128); - bool reconnect = imapc_connection_can_reconnect(conn); cmds = array_get(&conn->cmd_wait_list, &count); i_assert(count > 0); - str_printfa(str, "imapc(%s): Command '%s' timed out, ", - conn->name, imapc_command_get_readable(cmds[0])); - if (reconnect) - str_append(str, "reconnecting"); - else - str_append(str, "disconnecting"); - - if (reconnect) { - i_warning("%s", str_c(str)); - imapc_connection_reconnect(conn); - } else { - i_error("%s", str_c(str)); - imapc_connection_disconnect(conn); - } + imapc_connection_try_reconnect(conn, t_strdup_printf( + "Command '%s' timed out", imapc_command_get_readable(cmds[0])), 0); } static bool @@ -2280,9 +2297,3 @@ cmd->idle = TRUE; imapc_command_send(cmd, "IDLE"); } - -void imapc_connection_set_reconnected(struct imapc_connection *conn) -{ - conn->reconnect_command_count = array_count(&conn->cmd_wait_list) + - array_count(&conn->cmd_send_queue); -} diff -Nru dovecot-2.2.22/src/lib-imap-client/imapc-connection.h dovecot-2.2.24/src/lib-imap-client/imapc-connection.h --- dovecot-2.2.22/src/lib-imap-client/imapc-connection.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-client/imapc-connection.h 2016-04-26 13:01:20.000000000 +0000 @@ -8,6 +8,9 @@ #define IMAPC_THROTTLE_DEFAULT_MAX_MSECS (16*1000) #define IMAPC_THROTTLE_DEFAULT_SHRINK_MIN_MSECS 500 +/* If connect() fails, how long should we wait before reconnection */ +#define IMAPC_CONNECT_RETRY_WAIT_MSECS 1000 + struct imapc_client; struct imapc_connection; @@ -52,6 +55,5 @@ imapc_connection_get_mailbox(struct imapc_connection *conn); void imapc_connection_idle(struct imapc_connection *conn); -void imapc_connection_set_reconnected(struct imapc_connection *conn); #endif diff -Nru dovecot-2.2.22/src/lib-imap-client/Makefile.in dovecot-2.2.24/src/lib-imap-client/Makefile.in --- dovecot-2.2.22/src/lib-imap-client/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-client/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-imap-storage/Makefile.in dovecot-2.2.24/src/lib-imap-storage/Makefile.in --- dovecot-2.2.22/src/lib-imap-storage/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-storage/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-imap-urlauth/Makefile.in dovecot-2.2.24/src/lib-imap-urlauth/Makefile.in --- dovecot-2.2.22/src/lib-imap-urlauth/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-imap-urlauth/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-index/mail-cache.c dovecot-2.2.24/src/lib-index/mail-cache.c --- dovecot-2.2.22/src/lib-index/mail-cache.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-index/mail-cache.c 2016-04-26 13:01:20.000000000 +0000 @@ -77,6 +77,7 @@ mail_cache_set_syscall_error(cache, "close()"); cache->fd = -1; } + cache->opened = FALSE; } static void mail_cache_init_file_cache(struct mail_cache *cache) @@ -101,14 +102,17 @@ { const void *data; + i_assert(!cache->opened); cache->opened = TRUE; if (MAIL_INDEX_IS_IN_MEMORY(cache->index)) return 0; + i_assert(cache->fd == -1); cache->fd = nfs_safe_open(cache->filepath, cache->index->readonly ? O_RDONLY : O_RDWR); if (cache->fd == -1) { + mail_cache_file_close(cache); if (errno == ENOENT) { cache->need_compress_file_seq = 0; return 0; @@ -120,8 +124,10 @@ mail_cache_init_file_cache(cache); - if (mail_cache_map(cache, 0, 0, &data) < 0) + if (mail_cache_map(cache, 0, 0, &data) < 0) { + mail_cache_file_close(cache); return -1; + } return 1; } @@ -487,6 +493,8 @@ { int ret; + if (cache->opened) + return 0; ret = mail_cache_try_open(cache); if (ret > 0) ret = mail_cache_header_fields_read(cache); diff -Nru dovecot-2.2.22/src/lib-index/mail-cache-compress.c dovecot-2.2.24/src/lib-index/mail-cache-compress.c --- dovecot-2.2.22/src/lib-index/mail-cache-compress.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-index/mail-cache-compress.c 2016-04-26 13:01:20.000000000 +0000 @@ -363,6 +363,7 @@ } mail_cache_file_close(cache); + cache->opened = TRUE; cache->fd = fd; cache->st_ino = st.st_ino; cache->st_dev = st.st_dev; diff -Nru dovecot-2.2.22/src/lib-index/Makefile.in dovecot-2.2.24/src/lib-index/Makefile.in --- dovecot-2.2.22/src/lib-index/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-index/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -316,7 +316,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-lda/lda-settings.c dovecot-2.2.24/src/lib-lda/lda-settings.c --- dovecot-2.2.22/src/lib-lda/lda-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-lda/lda-settings.c 2016-04-26 13:01:21.000000000 +0000 @@ -35,7 +35,7 @@ }; static const struct lda_settings lda_default_settings = { - .postmaster_address = "", + .postmaster_address = "postmaster@%d", .hostname = "", .submission_host = "", .sendmail_path = "/usr/sbin/sendmail", diff -Nru dovecot-2.2.22/src/lib-lda/Makefile.in dovecot-2.2.24/src/lib-lda/Makefile.in --- dovecot-2.2.22/src/lib-lda/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-lda/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -265,7 +265,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-client.c dovecot-2.2.24/src/lib-ldap/ldap-client.c --- dovecot-2.2.22/src/lib-ldap/ldap-client.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-client.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,55 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ldap-private.h" + +struct ldap_client { + /* for now we support just a single connection, but this could be + extended to a connection pool. */ + struct ldap_connection *conn; +}; + +int ldap_client_init(const struct ldap_client_settings *set, + struct ldap_client **client_r, const char **error_r) +{ + struct ldap_client *client; + + client = i_new(struct ldap_client, 1); + if (ldap_connection_init(client, set, &client->conn, error_r) < 0) { + i_free(client); + return -1; + } + *client_r = client; + return 0; +} + +void ldap_client_deinit(struct ldap_client **_client) +{ + struct ldap_client *client = *_client; + + *_client = NULL; + + ldap_connection_deinit(&client->conn); + i_free(client); +} + +void ldap_client_switch_ioloop(struct ldap_client *client) +{ + ldap_connection_switch_ioloop(client->conn); +} + +#undef ldap_search_start +void ldap_search_start(struct ldap_client *client, + const struct ldap_search_input *input, + ldap_result_callback_t *callback, void *context) +{ + return ldap_connection_search_start(client->conn, input, callback, context); +} + +#undef ldap_compare_start +void ldap_compare_start(struct ldap_client *client, + const struct ldap_compare_input *input, + ldap_result_callback_t *callback, void *context) +{ + return ldap_connection_compare_start(client->conn, input, callback, context); +} diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-client.h dovecot-2.2.24/src/lib-ldap/ldap-client.h --- dovecot-2.2.22/src/lib-ldap/ldap-client.h 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-client.h 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,95 @@ +#ifndef LDAP_CLIENT_H +#define LDAP_CLIENT_H + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0x0000, + LDAP_SEARCH_SCOPE_ONE = 0x0001, + LDAP_SEARCH_SCOPE_SUBTREE = 0x0002 +}; + +struct ldap_client; +struct ldap_result; +struct ldap_search_iterator; +struct ldap_entry; + +/* Called when the LDAP result has finished. The callback must verify first + if the result is valid or not by calling ldap_result_has_failed() or + ldap_result_get_error(). The result is freed automatically after this + callback finishes. */ +typedef void ldap_result_callback_t(struct ldap_result *result, void *context); + +struct ldap_client_settings { + const char *uri; + const char *bind_dn; + const char *password; + + const struct ssl_iostream_settings *ssl_set; + + unsigned int timeout_secs; + unsigned int max_idle_time_secs; + unsigned int debug; + bool require_ssl; + bool start_tls; +}; + +struct ldap_search_input { + const char *base_dn; + const char *filter; + const char *const *attributes; + enum ldap_scope scope; + + unsigned int size_limit; + + unsigned int timeout_secs; +}; + +struct ldap_compare_input { + const char *dn; + const char *attr; + const char *value; + + unsigned int timeout_secs; +}; + +/* Initialize LDAP. Returns 0 on success, or -1 and error_r if initialization + failed with the given settings. */ +int ldap_client_init(const struct ldap_client_settings *set, + struct ldap_client **client_r, const char **error_r); +void ldap_client_deinit(struct ldap_client **client); +void ldap_client_switch_ioloop(struct ldap_client *client); + +void ldap_search_start(struct ldap_client *client, + const struct ldap_search_input *input, + ldap_result_callback_t *callback, + void *context); +#define ldap_search_start(client, input, callback, context) \ + ldap_search_start(client, input + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct ldap_result *, typeof(context))), \ + (ldap_result_callback_t *)callback, context) + +/* Returns TRUE if the LDAP query failed and result must not be used further. */ +bool ldap_result_has_failed(struct ldap_result *result); +/* Returns the error string if the query had failed, or NULL if it hasn't. */ +const char *ldap_result_get_error(struct ldap_result *result); + +struct ldap_search_iterator* ldap_search_iterator_init(struct ldap_result *result); +const struct ldap_entry *ldap_search_iterator_next(struct ldap_search_iterator *iter); +void ldap_search_iterator_deinit(struct ldap_search_iterator **iter); + +void ldap_compare_start(struct ldap_client *client, + const struct ldap_compare_input *input, + ldap_result_callback_t *callback, void *context); +#define ldap_compare_start(client, input, callback, context) \ + ldap_compare_start(client, input + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct ldap_result *, typeof(context))), \ + (ldap_result_callback_t *)callback, context) +/* Returns TRUE if the comparison matched, FALSE if not. */ +bool ldap_compare_result(struct ldap_result *result); + +const char *ldap_entry_dn(const struct ldap_entry *entry); +const char *const *ldap_entry_get_attributes(const struct ldap_entry *entry); +const char *const *ldap_entry_get_attribute(const struct ldap_entry *entry, const char *attribute); + +#endif diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-compare.c dovecot-2.2.24/src/lib-ldap/ldap-compare.c --- dovecot-2.2.22/src/lib-ldap/ldap-compare.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-compare.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,121 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ldap-private.h" + +static int +ldap_compare_callback(struct ldap_connection *conn, + struct ldap_op_queue_entry *req, + LDAPMessage *message, bool *finished_r) +{ + int msgtype = ldap_msgtype(message); + struct ldap_result res; + char *result_errmsg; + int ret, result_err; + + if (msgtype != LDAP_RES_COMPARE) { + *finished_r = FALSE; + return 0; + } + *finished_r = TRUE; + + ret = ldap_parse_result(conn->conn, message, + &result_err, NULL, + &result_errmsg, NULL, NULL, 0); + memset(&res, 0, sizeof(res)); + res.openldap_ret = ret; + if (ret != LDAP_SUCCESS) { + res.error_string = t_strdup_printf( + "ldap_parse_result() failed to parse compare: %s", + ldap_err2string(ret)); + } else if (result_err == LDAP_COMPARE_TRUE) { + res.compare_true = TRUE; + } else if (result_err == LDAP_COMPARE_FALSE) { + res.compare_true = FALSE; + } else { + const struct ldap_compare_input *input = &req->input.compare; + const char *error = result_errmsg != NULL ? + result_errmsg : ldap_err2string(result_err); + res.openldap_ret = result_err; + res.error_string = t_strdup_printf( + "ldap_compare_ext(dn=%s, attr=%s) failed: %s", + input->dn, input->attr, error); + } + + req->result_callback(&res, req->result_callback_ctx); + + if (result_errmsg != NULL) + ldap_memfree(result_errmsg); + return res.openldap_ret; +} + +static int +ldap_compare_send(struct ldap_connection *conn, struct ldap_op_queue_entry *req, + const char **error_r) +{ + const struct ldap_compare_input *input = &req->input.compare; + struct berval bv = { + .bv_len = strlen(input->value), + .bv_val = (void*)input->value + }; + + LDAPControl manageDSAIT = { + LDAP_CONTROL_MANAGEDSAIT, {0, 0}, 0 + }; + + /* try to use ManageDSAIT if available */ + LDAPControl *sctrls[] = { + &manageDSAIT, + NULL + }; + + int ret = ldap_compare_ext(conn->conn, + input->dn, + input->attr, + &bv, + sctrls, + NULL, + &(req->msgid)); + + if (ret != LDAP_SUCCESS) { + *error_r = t_strdup_printf( + "ldap_compare_ext(dn=%s, attr=%s) failed: %s", + input->dn, input->attr, ldap_err2string(ret)); + } + return ret; +} + +void ldap_connection_compare_start(struct ldap_connection *conn, + const struct ldap_compare_input *input, + ldap_result_callback_t *callback, + void *context) +{ + struct ldap_op_queue_entry *req; + pool_t pool = pool_alloconly_create(MEMPOOL_GROWING "ldap compare", 128); + req = p_new(pool, struct ldap_op_queue_entry, 1); + req->pool = pool; + + req->internal_response_cb = ldap_compare_callback; + + req->input.compare = *input; + req->result_callback = callback; + req->result_callback_ctx = context; + + /* copy strings */ + req->input.compare.dn = p_strdup(req->pool, input->dn); + req->input.compare.attr = p_strdup(req->pool, input->attr); + req->input.compare.value = p_strdup(req->pool, input->value); + + req->send_request_cb = ldap_compare_send; + req->timeout_secs = input->timeout_secs; + + return ldap_connection_queue_request(conn, req); +} + +bool ldap_compare_result(struct ldap_result *result) +{ + i_assert(result->openldap_ret == LDAP_SUCCESS); + i_assert(result->error_string == NULL); + + return result->compare_true; +} diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-connection.c dovecot-2.2.24/src/lib-ldap/ldap-connection.c --- dovecot-2.2.22/src/lib-ldap/ldap-connection.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-connection.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,638 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "aqueue.h" +#include "ioloop.h" +#include "ldap-private.h" + +static +void ldap_connection_read_more(struct ldap_connection *conn); +static +int ldap_connect_next_message(struct ldap_connection *conn, struct ldap_op_queue_entry *req, bool *finished_r); +static +void ldap_connection_abort_request(struct ldap_op_queue_entry *req); +static +void ldap_connection_request_destroy(struct ldap_op_queue_entry **req); +static +int ldap_connection_connect(struct ldap_connection *conn); + +void ldap_connection_deinit(struct ldap_connection **_conn) +{ + struct ldap_connection *conn = *_conn; + + *_conn = NULL; + + ldap_connection_kill(conn); + + unsigned int n = aqueue_count(conn->request_queue); + for (unsigned int i = 0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(conn->request_array), + aqueue_idx(conn->request_queue, i)); + if ((*reqp)->to_abort != NULL) + timeout_remove(&(*reqp)->to_abort); + } + pool_unref(&conn->pool); +} + +static +int ldap_connection_setup(struct ldap_connection *conn, const char **error_r) +{ + int ret, opt; + + ret = ldap_initialize(&(conn->conn), conn->set.uri); + if (ret != LDAP_SUCCESS) { + *error_r = t_strdup_printf("ldap_initialize(uri=%s) failed: %s", + conn->set.uri, ldap_err2string(ret)); + return -1; + } + + if (conn->ssl_set.verify_remote_cert) { + opt = LDAP_OPT_X_TLS_HARD; + } else { + opt = LDAP_OPT_X_TLS_ALLOW; + } + + ldap_set_option(conn->conn, LDAP_OPT_X_TLS, &opt); + /* refuse to connect to SSLv2 as it's completely insecure */ + opt = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + ldap_set_option(conn->conn, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt); + + opt = conn->set.timeout_secs; + /* default timeout */ + ldap_set_option(conn->conn, LDAP_OPT_TIMEOUT, &opt); + ldap_set_option(conn->conn, LDAP_OPT_NETWORK_TIMEOUT, &opt); + /* timelimit */ + ldap_set_option(conn->conn, LDAP_OPT_TIMELIMIT, &opt); + + if (conn->ssl_set.ca_file != NULL) + ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CACERTFILE, conn->ssl_set.ca_file); + if (conn->ssl_set.ca_dir != NULL) + ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CACERTDIR, conn->ssl_set.ca_dir); + + if (conn->ssl_set.cert != NULL) + ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CERTFILE, conn->ssl_set.cert); + if (conn->ssl_set.key != NULL) + ldap_set_option(conn->conn, LDAP_OPT_X_TLS_KEYFILE, conn->ssl_set.key); + + opt = conn->set.debug; + ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &opt); + + opt = LDAP_VERSION3; + ldap_set_option(conn->conn, LDAP_OPT_PROTOCOL_VERSION, &opt); + + ldap_set_option(conn->conn, LDAP_OPT_REFERRALS, 0); + + return 0; +} + +int ldap_connection_init(struct ldap_client *client, + const struct ldap_client_settings *set, + struct ldap_connection **conn_r, const char **error_r) +{ + i_assert(set->uri != NULL); + + if (set->require_ssl && + !set->start_tls && + strncmp("ldaps://",set->uri,8) != 0) { + *error_r = t_strdup_printf("ldap_connection_init(uri=%s) failed: %s", set->uri, + "uri does not start with ldaps and ssl required without start TLS"); + return -1; + } + + pool_t pool = pool_alloconly_create("ldap connection", 1024); + struct ldap_connection *conn = p_new(pool, struct ldap_connection, 1); + conn->pool = pool; + + conn->client = client; + conn->set = *set; + /* deep copy relevant strings */ + conn->set.uri = p_strdup(pool, set->uri); + conn->set.bind_dn = p_strdup(pool, set->bind_dn); + if (set->password != NULL) { + conn->set.password = p_strdup(pool, set->password); + ber_str2bv(conn->set.password, strlen(conn->set.password), 0, &(conn->cred)); + } + /* cannot use these */ + conn->ssl_set.ca = NULL; + conn->ssl_set.key_password = NULL; + conn->ssl_set.cert_username_field = NULL; + conn->ssl_set.crypto_device = NULL; + + if (set->ssl_set != NULL) { + conn->ssl_set.protocols = p_strdup(pool, set->ssl_set->protocols); + conn->ssl_set.cipher_list = p_strdup(pool, set->ssl_set->cipher_list); + conn->ssl_set.ca_file = p_strdup(pool, set->ssl_set->ca_file); + conn->ssl_set.cert = p_strdup(pool, set->ssl_set->cert); + conn->ssl_set.key = p_strdup(pool, set->ssl_set->key); + } + + if (ldap_connection_setup(conn, error_r) < 0) { + ldap_connection_deinit(&conn); + return -1; + } + + p_array_init(&(conn->request_array), conn->pool, 10); + conn->request_queue = aqueue_init(&(conn->request_array.arr)); + + *conn_r = conn; + return 0; +} + +void ldap_connection_switch_ioloop(struct ldap_connection *conn) +{ + if (conn->io != NULL) + conn->io = io_loop_move_io(&conn->io); + if (conn->to_disconnect != NULL) + conn->to_disconnect = io_loop_move_timeout(&conn->to_disconnect); + if (conn->to_reconnect != NULL) + conn->to_reconnect = io_loop_move_timeout(&conn->to_reconnect); + unsigned int n = aqueue_count(conn->request_queue); + + for (unsigned int i = 0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(conn->request_array), + aqueue_idx(conn->request_queue, i)); + if ((*reqp)->to_abort != NULL) + (*reqp)->to_abort = io_loop_move_timeout(&((*reqp)->to_abort)); + } +} + +static void +ldap_connection_result_failure(struct ldap_connection *conn, + struct ldap_op_queue_entry *req, + int ret, const char *error) +{ + struct ldap_result res; + memset(&res, 0, sizeof(res)); + res.conn = conn; + res.openldap_ret = ret; + res.error_string = error; + if (req->result_callback != NULL) + req->result_callback(&res, req->result_callback_ctx); + else + i_error("%s", error); + ldap_connection_kill(conn); +} + +static +void ldap_connection_result_success(struct ldap_connection *conn, + struct ldap_op_queue_entry *req) +{ + struct ldap_result res; + memset(&res, 0, sizeof(res)); + res.conn = conn; + res.openldap_ret = LDAP_SUCCESS; + if (req->result_callback != NULL) + req->result_callback(&res, req->result_callback_ctx); +} + +static +void ldap_connection_send_next(struct ldap_connection *conn) +{ + unsigned int i = 0, n; + struct ldap_op_queue_entry *req; + + if (conn->to_reconnect != NULL) + timeout_remove(&(conn->to_reconnect)); + + if (conn->state == LDAP_STATE_DISCONNECT) { + if (ldap_connection_connect(conn) == -1) + conn->to_reconnect = timeout_add(1000, ldap_connection_send_next, conn); + return; + } + + if (conn->state != LDAP_STATE_CONNECT) { + return; + } + + if (conn->pending > 10) return; /* try again later */ + + req = NULL; + /* get next request */ + n = aqueue_count(conn->request_queue); + + for(i=0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(conn->request_array), + aqueue_idx(conn->request_queue, i)); + if ((*reqp)->msgid > -1) + break; + req = *reqp; + } + + i--; + + /* nothing to actually send */ + if (req == NULL) return; + + i_assert(req->msgid == -1); + + const char *error; + int ret; + if ((ret = req->send_request_cb(conn, req, &error)) != LDAP_SUCCESS) { + /* did not succeed */ + struct ldap_result res; + + memset(&res, 0, sizeof(res)); + res.openldap_ret = ret; + if (req->result_callback != NULL) + req->result_callback(&res, req->result_callback_ctx); + + ldap_connection_request_destroy(&req); + aqueue_delete(conn->request_queue, i); + } else conn->pending++; +} + +static +void ldap_connection_request_destroy(struct ldap_op_queue_entry **_req) +{ + struct ldap_op_queue_entry *req = *_req; + + *_req = NULL; + + if (req->to_abort != NULL) + timeout_remove(&req->to_abort); + pool_unref(&req->pool); +} + +void ldap_connection_queue_request(struct ldap_connection *conn, struct ldap_op_queue_entry *req) +{ + req->msgid = -1; + req->conn = conn; + aqueue_append(conn->request_queue, &req); + if (req->timeout_secs > 0) + req->to_abort = timeout_add(req->timeout_secs * 1000, ldap_connection_abort_request, req); + + ldap_connection_send_next(conn); +} + +static int +ldap_connection_connect_parse(struct ldap_connection *conn, + struct ldap_op_queue_entry *req, + LDAPMessage *message, bool *finished_r) +{ + int ret, result_err; + char *retoid, *result_errmsg; + int msgtype = ldap_msgtype(message); + + *finished_r = TRUE; + ret = ldap_parse_result(conn->conn, message, &result_err, NULL, + &result_errmsg, NULL, NULL, 0); + + switch(conn->state) { + case LDAP_STATE_TLS: + if (msgtype != LDAP_RES_EXTENDED) { + *finished_r = FALSE; + return LDAP_SUCCESS; + } + if (ret != 0) { + ldap_connection_result_failure(conn, req, ret, t_strdup_printf( + "ldap_start_tls(uri=%s) failed: %s", + conn->set.uri, ldap_err2string(ret))); + return ret; + } else if (result_err != 0) { + if (conn->set.require_ssl) { + ldap_connection_result_failure(conn, req, result_err, t_strdup_printf( + "ldap_start_tls(uri=%s) failed: %s", + conn->set.uri, result_errmsg)); + ldap_memfree(result_errmsg); + return LDAP_UNAVAILABLE; /* make sure it disconnects */ + } + } else { + ret = ldap_parse_extended_result(conn->conn, message, &retoid, NULL, 0); + /* retoid can be NULL even if ret == 0 */ + if (ret == 0 && retoid != NULL && strcmp(retoid, LDAP_EXOP_START_TLS) == 0) { + ret = ldap_install_tls(conn->conn); + } else if (ret == 0) ret = 2; /* make it fail on next if */ + if (ret != LDAP_SUCCESS) { + if (conn->set.require_ssl) { + ldap_connection_result_failure(conn, req, ret, t_strdup_printf( + "ldap_start_tls(uri=%s) failed: %s", + conn->set.uri, ldap_err2string(ret))); + return LDAP_UNAVAILABLE; + } + } else { + if (conn->set.debug > 0) + i_debug("Using TLS connection to remote LDAP server"); + } + ldap_memfree(retoid); + } + conn->state = LDAP_STATE_AUTH; + return ldap_connect_next_message(conn, req, finished_r); + case LDAP_STATE_AUTH: + if (ret != LDAP_SUCCESS) { + ldap_connection_result_failure(conn, req, ret, t_strdup_printf( + "ldap_parse_result() failed for connect: %s", + ldap_err2string(ret))); + return ret; + } + if (result_err != LDAP_SUCCESS) { + const char *error = result_errmsg != NULL ? + result_errmsg : ldap_err2string(result_err); + ldap_connection_result_failure(conn, req, result_err, t_strdup_printf( + "Connect failed: %s", error)); + ldap_memfree(result_errmsg); + return result_err; + } + if (msgtype != LDAP_RES_BIND) return 0; + ret = ldap_parse_sasl_bind_result(conn->conn, message, &(conn->scred), 0); + if (ret != LDAP_SUCCESS) { + const char *error = t_strdup_printf( + "Cannot bind with server: %s", ldap_err2string(ret)); + ldap_connection_result_failure(conn, req, ret, error); + return 1; + } + conn->state = LDAP_STATE_CONNECT; + return ldap_connect_next_message(conn, req, finished_r); + default: + i_unreached(); + } + return LDAP_SUCCESS; +} + +static +void ldap_connection_abort_request(struct ldap_op_queue_entry *req) +{ + struct ldap_result res; + + /* too bad */ + if (req->to_abort != NULL) + timeout_remove(&req->to_abort); + if (req->msgid > -1) + ldap_abandon_ext(req->conn->conn, req->msgid, NULL, NULL); + + memset(&res, 0, sizeof(res)); + res.openldap_ret = LDAP_TIMEOUT; + res.error_string = "Aborting LDAP request after timeout"; + if (req->result_callback != NULL) + req->result_callback(&res, req->result_callback_ctx); + + unsigned int n = aqueue_count(req->conn->request_queue); + for (unsigned int i = 0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(req->conn->request_array), + aqueue_idx(req->conn->request_queue, i)); + if (req == *reqp) { + aqueue_delete(req->conn->request_queue, i); + ldap_connection_request_destroy(&req); + return; + } + } + i_unreached(); +} + +static int +ldap_connect_next_message(struct ldap_connection *conn, + struct ldap_op_queue_entry *req, bool *finished_r) +{ + int ret; + + *finished_r = TRUE; + + switch(conn->state) { + case LDAP_STATE_DISCONNECT: + /* if we should not disable SSL, and the URI is not ldaps:// */ + if (!conn->set.start_tls || strstr(conn->set.uri, "ldaps://") == NULL) { + ret = ldap_start_tls(conn->conn, NULL, NULL, &(req->msgid)); + if (ret != LDAP_SUCCESS) { + ldap_connection_result_failure(conn, req, ret, t_strdup_printf( + "ldap_start_tls(uri=%s) failed: %s", + conn->set.uri, ldap_err2string(ret))); + return ret; + } + conn->state = LDAP_STATE_TLS; + break; + } else { + conn->state = LDAP_STATE_AUTH; + /* we let it slide intentionally to next case */ + } + case LDAP_STATE_AUTH: + ret = ldap_sasl_bind(conn->conn, + conn->set.bind_dn, + LDAP_SASL_SIMPLE, + &(conn->cred), + NULL, + NULL, + &(req->msgid)); + if (ret != LDAP_SUCCESS) { + ldap_connection_result_failure(conn, req, ret, t_strdup_printf( + "ldap_sasl_bind(uri=%s, dn=%s) failed: %s", + conn->set.uri, conn->set.bind_dn, ldap_err2string(ret))); + return ret; + } + break; + case LDAP_STATE_CONNECT: + ldap_connection_result_success(conn, req); + return LDAP_SUCCESS; /* we are done here */ + default: + i_unreached(); + }; + + req->conn = conn; + *finished_r = FALSE; + return LDAP_SUCCESS; +} + +static +int ldap_connection_connect(struct ldap_connection *conn) +{ + const char *error; + int fd; + Sockbuf *sb; + bool finished; + + if (conn->conn == NULL) { + /* try to reconnect after disconnection */ + if (ldap_connection_setup(conn, &error) < 0) + i_error("%s", error); + } + + pool_t pool = pool_alloconly_create(MEMPOOL_GROWING "ldap bind", 128); + struct ldap_op_queue_entry *req = p_new(pool, struct ldap_op_queue_entry, 1); + req->pool = pool; + + req->internal_response_cb = ldap_connection_connect_parse; + req->timeout_secs = conn->set.timeout_secs; + + if (ldap_connect_next_message(conn, req, &finished) != LDAP_SUCCESS || + conn->conn == NULL) { + pool_unref(&pool); + return -1; + } + conn->pending++; + aqueue_append(conn->request_queue, &req); + /* start timeout */ + if (req->timeout_secs > 0) + req->to_abort = timeout_add(req->timeout_secs * 1000, ldap_connection_abort_request, req); + + ldap_get_option(conn->conn, LDAP_OPT_SOCKBUF, &sb); + ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &fd); + conn->io = io_add(fd, IO_READ, ldap_connection_read_more, conn); + if (conn->set.max_idle_time_secs > 0) + conn->to_disconnect = timeout_add(conn->set.max_idle_time_secs * 1000, ldap_connection_kill, conn); + return 0; +} + +void ldap_connection_kill(struct ldap_connection *conn) +{ + if (conn->io != NULL) + io_remove(&(conn->io)); + if (conn->to_disconnect != NULL) + timeout_remove(&(conn->to_disconnect)); + if (conn->to_reconnect != NULL) + timeout_remove(&(conn->to_reconnect)); + if (conn->request_queue) { + unsigned int n = aqueue_count(conn->request_queue); + + for (unsigned int i = 0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(conn->request_array), + aqueue_idx(conn->request_queue, i)); + if ((*reqp)->msgid > -1) + ldap_abandon_ext(conn->conn, (*reqp)->msgid, NULL, NULL); + (*reqp)->msgid = -1; + } + } + if (conn->conn != NULL) { + ldap_destroy(conn->conn); + ldap_memfree(conn->scred); + } + conn->conn = NULL; + conn->state = LDAP_STATE_DISCONNECT; +} + +int ldap_connection_check(struct ldap_connection *conn) +{ + /* it's not connected */ + if (conn->state == LDAP_STATE_DISCONNECT) return -1; + return 0; +} + +static struct ldap_op_queue_entry * +ldap_connection_find_req_by_msgid(struct ldap_connection *conn, int msgid, + unsigned int *idx_r) +{ + unsigned int i, n = aqueue_count(conn->request_queue); + for (i = 0; i < n; i++) { + struct ldap_op_queue_entry *const *reqp = + array_idx(&(conn->request_array), + aqueue_idx(conn->request_queue, i)); + if ((*reqp)->msgid == msgid) { + *idx_r = i; + return *reqp; + } + } + return NULL; +} + +static int +ldap_connection_handle_message(struct ldap_connection *conn, + LDAPMessage *message) +{ + struct ldap_op_queue_entry *req; + unsigned int i = 0; + bool finished = FALSE; + int err = LDAP_SUCCESS; + + /* we need to look at who it was for */ + req = ldap_connection_find_req_by_msgid(conn, ldap_msgid(message), &i); + if (req != NULL) + err = req->internal_response_cb(conn, req, message, &finished); + ldap_msgfree(message); + + switch(err) { + case LDAP_SUCCESS: + break; + case LDAP_SERVER_DOWN: +#ifdef LDAP_CONNECT_ERROR + case LDAP_CONNECT_ERROR: +#endif + case LDAP_UNAVAILABLE: + ldap_connection_kill(conn); + /* fall through */ + case LDAP_OPERATIONS_ERROR: + case LDAP_BUSY: + /* requeue */ + ldap_connection_kill(conn); + ldap_connection_send_next(conn); + finished = FALSE; + break; + case LDAP_SIZELIMIT_EXCEEDED: + case LDAP_TIMELIMIT_EXCEEDED: + case LDAP_NO_SUCH_ATTRIBUTE: + case LDAP_UNDEFINED_TYPE: + case LDAP_INAPPROPRIATE_MATCHING: + case LDAP_CONSTRAINT_VIOLATION: + case LDAP_TYPE_OR_VALUE_EXISTS: + case LDAP_INVALID_SYNTAX: + case LDAP_NO_SUCH_OBJECT: + case LDAP_ALIAS_PROBLEM: + case LDAP_INVALID_DN_SYNTAX: + case LDAP_IS_LEAF: + case LDAP_ALIAS_DEREF_PROBLEM: + case LDAP_FILTER_ERROR: + case LDAP_LOCAL_ERROR: + case LDAP_INVALID_CREDENTIALS: + finished = TRUE; + break; + default: + /* ignore */ + break; + } + + if (finished) { + i_assert(req != NULL); + ldap_connection_request_destroy(&req); + conn->pending--; + aqueue_delete(conn->request_queue, i); + return 1; + } + return 0; +} + +static +void ldap_connection_read_more(struct ldap_connection *conn) +{ + struct timeval tv = { + .tv_sec = 0, + .tv_usec = 0 + }; + + LDAPMessage *message; + int ret; + + /* try get a message */ + ret = ldap_result(conn->conn, LDAP_RES_ANY, 0, &tv, &message); + if (ret > 0) + ret = ldap_connection_handle_message(conn, message); + + if (ret == -1) { + if (ldap_get_option(conn->conn, LDAP_OPT_RESULT_CODE, &ret) != LDAP_SUCCESS) + i_unreached(); + if (ret != LDAP_SERVER_DOWN) + i_error("ldap_result() failed: %s", ldap_err2string(ret)); + else + i_error("Connection lost to LDAP server, reconnecting"); + /* kill me */ + ldap_connection_kill(conn); + } else if (ret != 0) { + ldap_connection_send_next(conn); + } + /* reset timeout */ + if (conn->to_disconnect != NULL) + timeout_reset(conn->to_disconnect); +} + +bool ldap_result_has_failed(struct ldap_result *result) +{ + i_assert((result->openldap_ret == LDAP_SUCCESS) == (result->error_string == NULL)); + return result->openldap_ret != LDAP_SUCCESS; +} + +const char *ldap_result_get_error(struct ldap_result *result) +{ + i_assert((result->openldap_ret == LDAP_SUCCESS) == (result->error_string == NULL)); + return result->error_string; +} diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-entry.c dovecot-2.2.24/src/lib-ldap/ldap-entry.c --- dovecot-2.2.22/src/lib-ldap/ldap-entry.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-entry.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,72 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "ldap-private.h" + +int ldap_entry_init(struct ldap_entry *obj, struct ldap_result *result, + LDAPMessage *message) +{ + ARRAY_TYPE(const_string) attr_names; + struct berval **values; + int count; + BerElement *bptr; + char *tmp; + tmp = ldap_get_dn(result->conn->conn, message); + obj->dn = p_strdup(result->pool, tmp); + obj->result = result; + ldap_memfree(tmp); + + tmp = ldap_first_attribute(result->conn->conn, message, &bptr); + + p_array_init(&attr_names, result->pool, 8); + p_array_init(&(obj->attributes), result->pool, 8); + + while(tmp != NULL) { + struct ldap_attribute *attr = p_new(result->pool, struct ldap_attribute, 1); + attr->name = p_strdup(result->pool, tmp); + array_append(&attr_names, &(attr->name), 1); + values = ldap_get_values_len(result->conn->conn, message, tmp); + if (values != NULL) { + count = ldap_count_values_len(values); + p_array_init(&(attr->values), result->pool, count); + for(int i = 0; i < count; i++) { + const char *ptr = p_strndup(result->pool, values[i]->bv_val, values[i]->bv_len); + array_append(&(attr->values), &ptr, 1); + } + ldap_value_free_len(values); + } + array_append_zero(&(attr->values)); + ldap_memfree(tmp); + array_append(&(obj->attributes), attr, 1); + tmp = ldap_next_attribute(result->conn->conn, message, bptr); + } + + ber_free(bptr, 0); + + array_append_zero(&attr_names); + obj->attr_names = array_idx(&attr_names, 0); + + return 0; +} + +const char *ldap_entry_dn(const struct ldap_entry *entry) +{ + return entry->dn; +} + +const char *const *ldap_entry_get_attributes(const struct ldap_entry *entry) +{ + return entry->attr_names; +} + +const char *const *ldap_entry_get_attribute(const struct ldap_entry *entry, const char *attribute) +{ + const struct ldap_attribute *attr; + array_foreach(&(entry->attributes), attr) { + if (strcasecmp(attr->name, attribute) == 0) { + return array_idx(&(attr->values), 0); + } + } + return NULL; +} diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-iterator.c dovecot-2.2.24/src/lib-ldap/ldap-iterator.c --- dovecot-2.2.22/src/lib-ldap/ldap-iterator.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-iterator.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,29 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "ldap-private.h" + +struct ldap_search_iterator* ldap_search_iterator_init(struct ldap_result *result) +{ + struct ldap_search_iterator *iter; + + i_assert(result->openldap_ret == LDAP_SUCCESS); + i_assert(result->error_string == NULL); + + iter = p_new(result->pool, struct ldap_search_iterator, 1); + iter->result = result; + return iter; +} + +const struct ldap_entry *ldap_search_iterator_next(struct ldap_search_iterator *iter) +{ + if (iter->idx >= array_count(&(iter->result->entries))) + return NULL; + return array_idx(&(iter->result->entries), iter->idx++); +} + +void ldap_search_iterator_deinit(struct ldap_search_iterator **iter) +{ + *iter = NULL; +} diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-private.h dovecot-2.2.24/src/lib-ldap/ldap-private.h --- dovecot-2.2.22/src/lib-ldap/ldap-private.h 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-private.h 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,127 @@ +#ifndef LDAP_PRIVATE_H +#define LDAP_PRIVATE_H + +#include "iostream-ssl.h" +#include "ldap-client.h" + +#include + +#define DOVE_LDAP_CONTINUE 0 +#define DOVE_LDAP_COMPLETE 1 +#define DOVE_LDAP_REQUEUE 2 + +struct ldap_connection; +struct ldap_result; + +struct ldap_op_queue_entry; +/* Handle an LDAP response. Returns 0 on success, otherwise the OpenLDAP error + number. */ +typedef int ldap_response_callback_t(struct ldap_connection *conn, + struct ldap_op_queue_entry *entry, + LDAPMessage *msg, bool *finished_r); +/* Send the request. Returns 0 on success, otherwise the OpenLDAP error number + and sets error_r string. */ +typedef int ldap_send_request_t(struct ldap_connection *conn, + struct ldap_op_queue_entry *entry, + const char **error_r); + +struct ldap_op_queue_entry { + pool_t pool; + struct ldap_connection *conn; + ldap_response_callback_t *internal_response_cb; + void *ctx; + + int msgid; + + unsigned int timeout_secs; + struct timeout *to_abort; + + ldap_send_request_t *send_request_cb; + + ldap_result_callback_t *result_callback; + void *result_callback_ctx; + + struct { + struct ldap_search_input search; + struct ldap_compare_input compare; + } input; +}; + +struct ldap_connection { + pool_t pool; + struct ldap_client *client; + + LDAP *conn; + enum { + LDAP_STATE_DISCONNECT, + LDAP_STATE_TLS, + LDAP_STATE_AUTH, + LDAP_STATE_CONNECT + } state; + + BerValue cred; /* needed for SASL */ + BerVarray scred; + + struct ldap_client_settings set; + struct ssl_iostream_settings ssl_set; + + struct aqueue *request_queue; + ARRAY(struct ldap_op_queue_entry *) request_array; + + unsigned int sent; + unsigned int pending; + + struct io *io; + struct timeout *to_disconnect; + struct timeout *to_reconnect; +}; + +struct ldap_attribute { + const char *name; + ARRAY_TYPE(const_string) values; +}; + +struct ldap_entry { + struct ldap_result *result; + char *dn; + ARRAY(struct ldap_attribute) attributes; + const char *const *attr_names; +}; + +struct ldap_result { + pool_t pool; + struct ldap_connection *conn; + + ARRAY(struct ldap_entry) entries; + int openldap_ret; + bool compare_true; + const char *error_string; +}; + +struct ldap_search_iterator { + unsigned int idx; + struct ldap_result *result; +}; + +int ldap_connection_init(struct ldap_client *client, + const struct ldap_client_settings *set, + struct ldap_connection **conn_r, const char **error_r); +void ldap_connection_deinit(struct ldap_connection **_conn); +void ldap_connection_switch_ioloop(struct ldap_connection *conn); + +void ldap_connection_search_start(struct ldap_connection *conn, + const struct ldap_search_input *input, + ldap_result_callback_t *callback, + void *context); +void ldap_connection_compare_start(struct ldap_connection *conn, + const struct ldap_compare_input *input, + ldap_result_callback_t *callback, + void *context); + +void ldap_connection_kill(struct ldap_connection *conn); +int ldap_connection_check(struct ldap_connection *conn); +void ldap_connection_queue_request(struct ldap_connection *conn, struct ldap_op_queue_entry *req); + +int ldap_entry_init(struct ldap_entry *obj, struct ldap_result *result, LDAPMessage *message); + +#endif diff -Nru dovecot-2.2.22/src/lib-ldap/ldap-search.c dovecot-2.2.24/src/lib-ldap/ldap-search.c --- dovecot-2.2.22/src/lib-ldap/ldap-search.c 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/ldap-search.c 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,168 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "ldap-private.h" + +#include + +struct ldap_search_ctx { + const struct ldap_search_input *input; + struct ldap_result res; +}; + +static void +ldap_search_result_failure(struct ldap_op_queue_entry *req, + int ret, const char *error) +{ + struct ldap_search_ctx *sctx = req->ctx; + sctx->res.openldap_ret = ret; + sctx->res.error_string = error; + req->result_callback(&(sctx->res), req->result_callback_ctx); +} + +static void ldap_search_result_success(struct ldap_op_queue_entry *req) +{ + struct ldap_search_ctx *sctx = req->ctx; + sctx->res.openldap_ret = LDAP_SUCCESS; + req->result_callback(&(sctx->res), req->result_callback_ctx); +} + +static int +ldap_search_callback(struct ldap_connection *conn, + struct ldap_op_queue_entry *req, + LDAPMessage *message, bool *finished_r) +{ + struct ldap_search_ctx *sctx = req->ctx; + int msgtype = ldap_msgtype(message); + char *result_errmsg = NULL; + int ret, result_err; + + if (msgtype != LDAP_RES_SEARCH_ENTRY && + msgtype != LDAP_RES_SEARCH_RESULT) { + *finished_r = FALSE; + return LDAP_SUCCESS; + } + *finished_r = TRUE; + + ret = ldap_parse_result(conn->conn, message, &result_err, NULL, + &result_errmsg, NULL, NULL, 0); + if (ret == LDAP_NO_RESULTS_RETURNED) { + ret = LDAP_SUCCESS; + } else if (ret != LDAP_SUCCESS) { + ldap_search_result_failure(req, ret, t_strdup_printf( + "ldap_parse_result() failed for search: %s", ldap_err2string(ret))); + return ret; + } else if (result_err != LDAP_SUCCESS) { + const struct ldap_search_input *input = &req->input.search; + const char *error = result_errmsg != NULL ? + result_errmsg : ldap_err2string(result_err); + ldap_search_result_failure(req, result_err, t_strdup_printf( + "ldap_search_ext(base=%s, scope=%d, filter=%s) failed: %s", + input->base_dn, input->scope, input->filter, error)); + ldap_memfree(result_errmsg); + return result_err; + } + + LDAPMessage *res = ldap_first_entry(conn->conn, message); + + while(res != NULL) { + struct ldap_entry *obj = p_new(req->pool, struct ldap_entry, 1); + ldap_entry_init(obj, &(sctx->res), message); + array_append(&(sctx->res.entries), obj, 1); + res = ldap_next_entry(conn->conn, res); + } + + if (msgtype == LDAP_RES_SEARCH_RESULT) { + ldap_search_result_success(req); + return LDAP_SUCCESS; + } + + *finished_r = FALSE; + return LDAP_SUCCESS; +} + +static int +ldap_search_send(struct ldap_connection *conn, struct ldap_op_queue_entry *req, + const char **error_r) +{ + const struct ldap_search_input *input = &req->input.search; + LDAPControl manageDSAIT = { + LDAP_CONTROL_MANAGEDSAIT, {0, 0}, 0 + }; + /* try to use ManageDSAIT if available */ + LDAPControl *sctrls[] = { + &manageDSAIT, + NULL + }; + + struct timeval tv = { + .tv_sec = req->timeout_secs, + .tv_usec = 0 + }; + + int ret = ldap_search_ext(conn->conn, + input->base_dn, + input->scope, + input->filter, + (char**)input->attributes, + 0, + sctrls, + NULL, + &tv, + input->size_limit, + &(req->msgid)); + + if (ret != LDAP_SUCCESS) { + *error_r = t_strdup_printf( + "ldap_search_ext(base=%s, scope=%d, filter=%s) failed: %s", + input->base_dn, input->scope, input->filter, + ldap_err2string(ret)); + } + return ret; +} + +void ldap_connection_search_start(struct ldap_connection *conn, + const struct ldap_search_input *input, + ldap_result_callback_t *callback, + void *context) +{ + struct ldap_op_queue_entry *req; + pool_t pool = pool_alloconly_create(MEMPOOL_GROWING "ldap search", 128); + req = p_new(pool, struct ldap_op_queue_entry, 1); + req->pool = pool; + + struct ldap_search_ctx *sctx = p_new(pool, struct ldap_search_ctx, 1); + sctx->res.conn = conn; + sctx->res.pool = pool; + + p_array_init(&(sctx->res.entries), req->pool, 8); + + req->internal_response_cb = ldap_search_callback; + + req->result_callback = callback; + req->result_callback_ctx = context; + req->input.search = *input; + + /* copy strings */ + req->input.search.base_dn = p_strdup(req->pool, input->base_dn); + req->input.search.filter = p_strdup(req->pool, input->filter); + + if (input->attributes != NULL) { + ARRAY_TYPE(const_string) arr; + p_array_init(&arr, req->pool, 8); + for(const char **ptr = (const char**)input->attributes; *ptr != NULL; ptr++) { + const char *tmp = p_strdup(req->pool, *ptr); + array_append(&arr, &tmp, 1); + } + array_append_zero(&arr); + req->input.search.attributes = array_idx_modifiable(&arr, 0); + } + + req->send_request_cb = ldap_search_send; + sctx->input = &req->input.search; + req->ctx = sctx; + req->timeout_secs = input->timeout_secs; + + ldap_connection_queue_request(conn, req); +} diff -Nru dovecot-2.2.22/src/lib-ldap/Makefile.am dovecot-2.2.24/src/lib-ldap/Makefile.am --- dovecot-2.2.22/src/lib-ldap/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/Makefile.am 2016-04-26 13:01:21.000000000 +0000 @@ -0,0 +1,41 @@ +pkglib_LTLIBRARIES = libdovecot-ldap.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-master \ + -I$(top_srcdir)/src/lib-ssl-iostream \ + $(LDAP_CFLAGS) + +libdovecot_ldap_la_SOURCES = \ + ldap-client.c \ + ldap-connection.c \ + ldap-iterator.c \ + ldap-search.c \ + ldap-compare.c \ + ldap-entry.c + +libdovecot_ldap_la_DEPENDENCIES = +libdovecot_ldap_la_LDFLAGS = -export-dynamic +libdovecot_ldap_la_LIBADD = $(LDAP_LIBS) + +headers = \ + ldap-client.h + +noinst_HEADERS = \ + ldap-private.h + +pkginc_libdir=$(pkgincludedir) +pkginc_lib_HEADERS = $(headers) + +test_libs = \ + ../lib-test/libtest.la \ + ../lib-ssl-iostream/libssl_iostream.la \ + ../lib/liblib.la + +check: check-am check-test +check-test: all-am + for bin in $(test_programs); do \ + if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ + done diff -Nru dovecot-2.2.22/src/lib-ldap/Makefile.in dovecot-2.2.24/src/lib-ldap/Makefile.in --- dovecot-2.2.22/src/lib-ldap/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.24/src/lib-ldap/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -0,0 +1,786 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/lib-ldap +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/dovecot.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(pkginc_lib_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" \ + "$(DESTDIR)$(pkginc_libdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +am_libdovecot_ldap_la_OBJECTS = ldap-client.lo ldap-connection.lo \ + ldap-iterator.lo ldap-search.lo ldap-compare.lo ldap-entry.lo +libdovecot_ldap_la_OBJECTS = $(am_libdovecot_ldap_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libdovecot_ldap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libdovecot_ldap_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdovecot_ldap_la_SOURCES) +DIST_SOURCES = $(libdovecot_ldap_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) $(pkginc_lib_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTH_CFLAGS = @AUTH_CFLAGS@ +AUTH_LIBS = @AUTH_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CASSANDRA_CFLAGS = @CASSANDRA_CFLAGS@ +CASSANDRA_LIBS = @CASSANDRA_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CDB_LIBS = @CDB_LIBS@ +CFLAGS = @CFLAGS@ +CLUCENE_CFLAGS = @CLUCENE_CFLAGS@ +CLUCENE_LIBS = @CLUCENE_LIBS@ +COMPRESS_LIBS = @COMPRESS_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPT_LIBS = @CRYPT_LIBS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DICT_LIBS = @DICT_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KRB5CONFIG = @KRB5CONFIG@ +KRB5_CFLAGS = @KRB5_CFLAGS@ +KRB5_LIBS = @KRB5_LIBS@ +LD = @LD@ +LDAP_LIBS = @LDAP_LIBS@ +LDFLAGS = @LDFLAGS@ +LIBCAP = @LIBCAP@ +LIBDOVECOT = @LIBDOVECOT@ +LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ +LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ +LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ +LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ +LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ +LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ +LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ +LIBDOVECOT_SQL = @LIBDOVECOT_SQL@ +LIBDOVECOT_STORAGE = @LIBDOVECOT_STORAGE@ +LIBDOVECOT_STORAGE_DEPS = @LIBDOVECOT_STORAGE_DEPS@ +LIBEXTTEXTCAT_CFLAGS = @LIBEXTTEXTCAT_CFLAGS@ +LIBEXTTEXTCAT_LIBS = @LIBEXTTEXTCAT_LIBS@ +LIBICONV = @LIBICONV@ +LIBICU_CFLAGS = @LIBICU_CFLAGS@ +LIBICU_LIBS = @LIBICU_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LINKED_STORAGE_LDADD = @LINKED_STORAGE_LDADD@ +LINKED_STORAGE_LIBS = @LINKED_STORAGE_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MODULE_LIBS = @MODULE_LIBS@ +MODULE_SUFFIX = @MODULE_SUFFIX@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NOPLUGIN_LDFLAGS = @NOPLUGIN_LDFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +QUOTA_LIBS = @QUOTA_LIBS@ +RANLIB = @RANLIB@ +RPCGEN = @RPCGEN@ +RUN_TEST = @RUN_TEST@ +SED = @SED@ +SETTING_FILES = @SETTING_FILES@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CFLAGS = @SQLITE_CFLAGS@ +SQLITE_LIBS = @SQLITE_LIBS@ +SQL_CFLAGS = @SQL_CFLAGS@ +SQL_LIBS = @SQL_LIBS@ +SSL_CFLAGS = @SSL_CFLAGS@ +SSL_LIBS = @SSL_LIBS@ +STRIP = @STRIP@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dict_drivers = @dict_drivers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mail_storages = @mail_storages@ +mailbox_list_drivers = @mailbox_list_drivers@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +rundir = @rundir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sql_drivers = @sql_drivers@ +srcdir = @srcdir@ +ssldir = @ssldir@ +statedir = @statedir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = libdovecot-ldap.la +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-master \ + -I$(top_srcdir)/src/lib-ssl-iostream \ + $(LDAP_CFLAGS) + +libdovecot_ldap_la_SOURCES = \ + ldap-client.c \ + ldap-connection.c \ + ldap-iterator.c \ + ldap-search.c \ + ldap-compare.c \ + ldap-entry.c + +libdovecot_ldap_la_DEPENDENCIES = +libdovecot_ldap_la_LDFLAGS = -export-dynamic +libdovecot_ldap_la_LIBADD = $(LDAP_LIBS) +headers = \ + ldap-client.h + +noinst_HEADERS = \ + ldap-private.h + +pkginc_libdir = $(pkgincludedir) +pkginc_lib_HEADERS = $(headers) +test_libs = \ + ../lib-test/libtest.la \ + ../lib-ssl-iostream/libssl_iostream.la \ + ../lib/liblib.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib-ldap/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib-ldap/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdovecot-ldap.la: $(libdovecot_ldap_la_OBJECTS) $(libdovecot_ldap_la_DEPENDENCIES) $(EXTRA_libdovecot_ldap_la_DEPENDENCIES) + $(AM_V_CCLD)$(libdovecot_ldap_la_LINK) -rpath $(pkglibdir) $(libdovecot_ldap_la_OBJECTS) $(libdovecot_ldap_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-compare.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-entry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-iterator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap-search.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkginc_libHEADERS: $(pkginc_lib_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkginc_libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkginc_libdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginc_libdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginc_libdir)" || exit $$?; \ + done + +uninstall-pkginc_libHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginc_lib_HEADERS)'; test -n "$(pkginc_libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkginc_libdir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(pkginc_libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkginc_libHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkginc_libHEADERS uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pkglibLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkginc_libHEADERS install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkginc_libHEADERS \ + uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +check: check-am check-test +check-test: all-am + for bin in $(test_programs); do \ + if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ + done + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru dovecot-2.2.22/src/lib-mail/istream-header-filter.c dovecot-2.2.24/src/lib-mail/istream-header-filter.c --- dovecot-2.2.22/src/lib-mail/istream-header-filter.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-mail/istream-header-filter.c 2016-04-26 13:01:21.000000000 +0000 @@ -39,6 +39,7 @@ unsigned int end_body_with_lf:1; unsigned int last_lf_added:1; unsigned int eoh_not_matched:1; + unsigned int prev_matched:1; }; header_filter_callback *null_header_filter_callback = NULL; @@ -144,6 +145,9 @@ ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip); i_assert(ret >= 0); mstream->istream.pos = pos; + + if (pos >= mstream->istream.max_buffer_size) + return -2; return ret; } @@ -152,7 +156,6 @@ struct message_header_line *hdr; uoff_t highwater_offset; ssize_t ret, ret2; - bool matched; int hdr_ret; if (mstream->hdr_ctx == NULL) { @@ -181,10 +184,15 @@ } } + if (mstream->hdr_buf->used >= mstream->istream.max_buffer_size) + return -2; + while ((hdr_ret = message_parse_header_next(mstream->hdr_ctx, &hdr)) > 0) { - mstream->cur_line++; + bool matched; + if (!hdr->continued) + mstream->cur_line++; if (hdr->eoh) { mstream->seen_eoh = TRUE; matched = TRUE; @@ -206,15 +214,25 @@ continue; } - matched = mstream->headers_count == 0 ? FALSE : - i_bsearch(hdr->name, mstream->headers, - mstream->headers_count, - sizeof(*mstream->headers), - bsearch_strcasecmp) != NULL; + if (hdr->continued) { + /* Header line continued - use only the first line's + matched-result. Otherwise multiline headers might + end up being only partially picked, which wouldn't + be very good. However, allow callbacks to modify + the headers in any way they want. */ + matched = mstream->prev_matched; + } else if (mstream->headers_count == 0) { + /* no include/exclude headers - default matching */ + matched = FALSE; + } else { + matched = i_bsearch(hdr->name, mstream->headers, + mstream->headers_count, + sizeof(*mstream->headers), + bsearch_strcasecmp) != NULL; + } if (mstream->callback == NULL) { /* nothing gets excluded */ - } else if (mstream->cur_line > mstream->parsed_lines || - mstream->headers_edited) { + } else if (!mstream->header_parsed || mstream->headers_edited) { /* first time in this line or we have actually modified the header so we always want to call the callbacks */ bool orig_matched = matched; @@ -223,18 +241,19 @@ mstream->callback(mstream, hdr, &matched, mstream->context); if (matched != orig_matched && - !mstream->headers_edited) { + !hdr->continued && !mstream->headers_edited) { if (!array_is_created(&mstream->match_change_lines)) i_array_init(&mstream->match_change_lines, 8); array_append(&mstream->match_change_lines, &mstream->cur_line, 1); } - } else { + } else if (!hdr->continued) { /* second time in this line. was it excluded by the callback the first time? */ if (match_line_changed(mstream)) matched = !matched; } + mstream->prev_matched = matched; if (matched == mstream->exclude) { /* ignore */ @@ -263,6 +282,8 @@ break; } } + if (mstream->hdr_buf->used >= mstream->istream.max_buffer_size) + break; } if (hdr_ret < 0) { @@ -295,6 +316,7 @@ mstream->hdr_ctx = NULL; if (!mstream->header_parsed && mstream->callback != NULL) { + bool matched = FALSE; mstream->callback(mstream, NULL, &matched, mstream->context); /* check if the callback added more headers. @@ -419,6 +441,7 @@ message_parse_header_deinit(&mstream->hdr_ctx); mstream->skip_count = v_offset; mstream->cur_line = 0; + mstream->prev_matched = FALSE; mstream->header_read = FALSE; mstream->seen_eoh = FALSE; } diff -Nru dovecot-2.2.22/src/lib-mail/Makefile.in dovecot-2.2.24/src/lib-mail/Makefile.in --- dovecot-2.2.22/src/lib-mail/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-mail/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -384,7 +384,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-mail/message-parser.c dovecot-2.2.24/src/lib-mail/message-parser.c --- dovecot-2.2.22/src/lib-mail/message-parser.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-mail/message-parser.c 2016-04-26 13:01:21.000000000 +0000 @@ -45,6 +45,7 @@ struct message_block *block_r); unsigned int part_seen_content_type:1; + unsigned int multipart:1; unsigned int eof:1; }; @@ -65,19 +66,23 @@ boundary_find(struct message_boundary *boundaries, const unsigned char *data, size_t len) { + struct message_boundary *best = NULL; + /* As MIME spec says: search from latest one to oldest one so that we don't break if the same boundary is used in nested parts. Also the full message line doesn't have to match the boundary, only the - beginning. */ + beginning. However, if there are multiple prefixes whose beginning + matches, use the longest matching one. */ while (boundaries != NULL) { if (boundaries->len <= len && - memcmp(boundaries->boundary, data, boundaries->len) == 0) - return boundaries; + memcmp(boundaries->boundary, data, boundaries->len) == 0 && + (best == NULL || best->len < boundaries->len)) + best = boundaries; boundaries = boundaries->next; } - return NULL; + return best; } static void parse_body_add_block(struct message_parser_ctx *ctx, @@ -504,6 +509,21 @@ } } +static bool block_is_at_eoh(const struct message_block *block) +{ + if (block->size < 1) + return FALSE; + if (block->data[0] == '\n') + return TRUE; + if (block->data[0] == '\r') { + if (block->size < 2) + return FALSE; + if (block->data[1] == '\n') + return TRUE; + } + return FALSE; +} + #define MUTEX_FLAGS \ (MESSAGE_PART_FLAG_MESSAGE_RFC822 | MESSAGE_PART_FLAG_MULTIPART) @@ -519,12 +539,30 @@ if ((ret = message_parser_read_more(ctx, block_r, &full)) == 0) return ret; + if (ret > 0 && block_is_at_eoh(block_r) && + ctx->last_boundary != NULL && + (part->flags & MESSAGE_PART_FLAG_IS_MIME) != 0) { + /* we are at the end of headers and we've determined that we're + going to start a multipart. add the boundary already here + at this point so we can reliably determine whether the + "\n--boundary" belongs to us or to a previous boundary. + this is a problem if the boundary prefixes are identical, + because MIME requires only the prefix to match. */ + parse_next_body_multipart_init(ctx); + ctx->multipart = TRUE; + } + /* before parsing the header see if we can find a --boundary from here. we're guaranteed to be at the beginning of the line here. */ if (ret > 0) { ret = ctx->boundaries == NULL ? -1 : boundary_line_find(ctx, block_r->data, block_r->size, full, &boundary); + if (ret > 0 && boundary->part == ctx->part) { + /* our own body begins with our own --boundary. + we don't want to handle that yet. */ + ret = -1; + } } if (ret < 0) { /* no boundary */ @@ -581,14 +619,10 @@ } /* end of headers */ - if ((part->flags & MESSAGE_PART_FLAG_MULTIPART) != 0 && - ctx->last_boundary == NULL) { - /* multipart type but no message boundary */ - part->flags = 0; - } if ((part->flags & MESSAGE_PART_FLAG_IS_MIME) == 0) { /* It's not MIME. Reset everything we found from Content-Type. */ + i_assert(!ctx->multipart); part->flags = 0; ctx->last_boundary = NULL; } @@ -615,8 +649,9 @@ i_assert((part->flags & MUTEX_FLAGS) != MUTEX_FLAGS); ctx->last_chr = '\n'; - if (ctx->last_boundary != NULL) { - parse_next_body_multipart_init(ctx); + if (ctx->multipart) { + i_assert(ctx->last_boundary == NULL); + ctx->multipart = FALSE; ctx->parse_next_block = parse_next_body_to_boundary; } else if (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) ctx->parse_next_block = parse_next_body_message_rfc822_init; diff -Nru dovecot-2.2.22/src/lib-mail/test-istream-header-filter.c dovecot-2.2.24/src/lib-mail/test-istream-header-filter.c --- dovecot-2.2.22/src/lib-mail/test-istream-header-filter.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-mail/test-istream-header-filter.c 2016-04-26 13:01:21.000000000 +0000 @@ -48,7 +48,7 @@ static void test_istream_filter(void) { - static const char *exclude_headers[] = { "Subject", "To", "X-Drop", NULL }; + static const char *exclude_headers[] = { "Subject", "To" }; const char *input = "From: foo\nFrom: abc\nTo: bar\nSubject: plop\nX-Drop: 1\n\nhello world\n"; const char *output = "From: abc\n\nhello world\n"; struct istream *istream, *filter, *filter2; @@ -62,12 +62,14 @@ filter = i_stream_create_header_filter(istream, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, - exclude_headers, 2, + exclude_headers, + N_ELEMENTS(exclude_headers), filter_callback, (void *)NULL); filter2 = i_stream_create_header_filter(filter, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, - exclude_headers, 2, + exclude_headers, + N_ELEMENTS(exclude_headers), *null_header_filter_callback, (void *)NULL); i_stream_unref(&filter); @@ -96,6 +98,147 @@ test_end(); } +static void add_random_text(string_t *dest, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + str_append_c(dest, rand() % ('z'-'a'+1) + 'a'); +} + +static void ATTR_NULL(3) +filter2_callback(struct header_filter_istream *input ATTR_UNUSED, + struct message_header_line *hdr, + bool *matched, void *context ATTR_UNUSED) +{ + if (hdr != NULL && strcmp(hdr->name, "To") == 0) + *matched = TRUE; +} + +static void test_istream_filter_large_buffer(void) +{ + string_t *input, *output; + struct istream *istream, *filter; + const unsigned char *data; + size_t size, prefix_len; + const char *p; + unsigned int i; + + test_begin("i_stream_create_header_filter(large buffer)"); + + input = str_new(default_pool, 1024*128); + output = str_new(default_pool, 1024*128); + str_append(input, "From: "); + add_random_text(input, 1024*31); + str_append(input, "\nTo: "); + add_random_text(input, 1024*32); + str_append(input, "\nSubject: "); + add_random_text(input, 1024*34); + str_append(input, "\n\nbody\n"); + + istream = test_istream_create_data(str_data(input), str_len(input)); + test_istream_set_max_buffer_size(istream, 8192); + + filter = i_stream_create_header_filter(istream, + HEADER_FILTER_EXCLUDE | + HEADER_FILTER_NO_CR, + NULL, 0, + filter2_callback, + (void *)NULL); + + for (i = 0; i < 2; i++) { + for (;;) { + ssize_t ret = i_stream_read(filter); + i_assert(ret != 0); + if (ret == -1) + break; + if (ret == -2) { + data = i_stream_get_data(filter, &size); + str_append_n(output, data, size); + i_stream_skip(filter, size); + } + } + + data = i_stream_get_data(filter, &size); + test_assert(size <= 8192); + str_append_n(output, data, size); + + p = strstr(str_c(input), "To: "); + i_assert(p != NULL); + prefix_len = p - str_c(input); + test_assert(strncmp(str_c(input), str_c(output), prefix_len) == 0); + + p = strchr(p, '\n'); + i_assert(p != NULL); + test_assert(strcmp(p+1, str_c(output) + prefix_len) == 0); + + /* seek back and retry once with caching and different + buffer size */ + i_stream_seek(filter, 0); + str_truncate(output, 0); + test_istream_set_max_buffer_size(istream, 4096); + } + + str_free(&input); + str_free(&output); + i_stream_unref(&filter); + i_stream_unref(&istream); + + test_end(); +} + +static void +filter3_callback(struct header_filter_istream *input ATTR_UNUSED, + struct message_header_line *hdr, + bool *matched ATTR_UNUSED, string_t *dest) +{ + if (hdr != NULL) + message_header_line_write(dest, hdr); +} + +static void test_istream_callbacks(void) +{ + string_t *input, *output; + struct istream *istream, *filter; + unsigned int i; + + test_begin("i_stream_create_header_filter(callbacks)"); + + input = str_new(default_pool, 1024*128); + output = str_new(default_pool, 1024*128); + str_append(input, "From: first line\n "); + add_random_text(input, 1024*31); + str_append(input, "\nTo: first line\n\tsecond line\n\t"); + add_random_text(input, 1024*32); + str_append(input, "\n last line\nSubject: "); + add_random_text(input, 1024*34); + str_append(input, "\n"); + + istream = test_istream_create_data(str_data(input), str_len(input)); + test_istream_set_max_buffer_size(istream, 8192); + + filter = i_stream_create_header_filter(istream, + HEADER_FILTER_EXCLUDE | + HEADER_FILTER_NO_CR, + NULL, 0, + filter3_callback, + output); + + /* callback should be called exactly once for all the header input */ + for (i = 0; i < 2; i++) { + while (i_stream_read(filter) != -1) + i_stream_skip(filter, i_stream_get_data_size(filter)); + } + + test_assert(strcmp(str_c(output), str_c(input)) == 0); + str_free(&input); + str_free(&output); + i_stream_unref(&filter); + i_stream_unref(&istream); + + test_end(); +} + static void ATTR_NULL(3) edit_callback(struct header_filter_istream *input, struct message_header_line *hdr, @@ -131,7 +274,6 @@ static void test_istream_end_body_with_lf(void) { - static const char *empty_strarray[] = { NULL }; const char *input = "From: foo\n\nhello world"; const char *output = "From: foo\n\nhello world\n"; struct istream *istream, *filter; @@ -147,7 +289,7 @@ HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_END_BODY_WITH_LF, - empty_strarray, 0, + NULL, 0, *null_header_filter_callback, (void *)NULL); @@ -219,6 +361,8 @@ { static void (*test_functions[])(void) = { test_istream_filter, + test_istream_filter_large_buffer, + test_istream_callbacks, test_istream_edit, test_istream_end_body_with_lf, test_istream_strip_eoh, diff -Nru dovecot-2.2.22/src/lib-mail/test-message-parser.c dovecot-2.2.24/src/lib-mail/test-message-parser.c --- dovecot-2.2.22/src/lib-mail/test-message-parser.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-mail/test-message-parser.c 2016-04-26 13:01:21.000000000 +0000 @@ -196,6 +196,308 @@ test_end(); } +static void test_message_parser_truncated_mime_headers2(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"ab\"\n" +"\n" +"--ab\n" +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--ab\n" +"Content-Type: text/plain\n" +"\n" +"--a\n\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser truncated mime headers 2"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 2); + test_assert(parts->header_size.physical_size == 46); + test_assert(parts->header_size.virtual_size == 46+2); + test_assert(parts->body_size.lines == 8); + test_assert(parts->body_size.physical_size == 86); + test_assert(parts->body_size.virtual_size == 86+8); + + test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->physical_pos == 51); + test_assert(parts->children->header_size.lines == 1); + test_assert(parts->children->header_size.physical_size == 44); + test_assert(parts->children->header_size.virtual_size == 44+1); + test_assert(parts->children->body_size.lines == 0); + test_assert(parts->children->body_size.physical_size == 0); + test_assert(parts->children->children == NULL); + + test_assert(parts->children->next->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->next->physical_pos == 101); + test_assert(parts->children->next->header_size.lines == 2); + test_assert(parts->children->next->header_size.physical_size == 26); + test_assert(parts->children->next->header_size.virtual_size == 26+2); + test_assert(parts->children->next->body_size.lines == 2); + test_assert(parts->children->next->body_size.physical_size == 5); + test_assert(parts->children->next->body_size.virtual_size == 5+2); + test_assert(parts->children->next->children == NULL); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + +static void test_message_parser_truncated_mime_headers3(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"ab\"\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser truncated mime headers 3"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 1); + test_assert(parts->header_size.physical_size == 45); + test_assert(parts->header_size.virtual_size == 45+1); + test_assert(parts->body_size.lines == 0); + test_assert(parts->body_size.physical_size == 0); + + test_assert(parts->children == NULL); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + +static void test_message_parser_empty_multipart(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"ab\"\n" +"\n" +"body\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser truncated mime headers 3"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 2); + test_assert(parts->header_size.physical_size == 46); + test_assert(parts->header_size.virtual_size == 46+2); + test_assert(parts->body_size.lines == 1); + test_assert(parts->body_size.physical_size == 5); + test_assert(parts->body_size.virtual_size == 5+1); + + test_assert(parts->children == NULL); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + +static void test_message_parser_duplicate_mime_boundary(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--a\n" +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--a\n" +"Content-Type: text/plain\n" +"\n" +"body\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser duplicate mime boundary"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 2); + test_assert(parts->header_size.physical_size == 45); + test_assert(parts->header_size.virtual_size == 45+2); + test_assert(parts->body_size.lines == 7); + test_assert(parts->body_size.physical_size == 84); + test_assert(parts->body_size.virtual_size == 84+7); + test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->physical_pos == 49); + test_assert(parts->children->header_size.lines == 2); + test_assert(parts->children->header_size.physical_size == 45); + test_assert(parts->children->header_size.virtual_size == 45+2); + test_assert(parts->children->body_size.lines == 4); + test_assert(parts->children->body_size.physical_size == 35); + test_assert(parts->children->body_size.virtual_size == 35+4); + test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->children->physical_pos == 98); + test_assert(parts->children->children->header_size.lines == 2); + test_assert(parts->children->children->header_size.physical_size == 26); + test_assert(parts->children->children->header_size.virtual_size == 26+2); + test_assert(parts->children->children->body_size.lines == 1); + test_assert(parts->children->children->body_size.physical_size == 5); + test_assert(parts->children->children->body_size.virtual_size == 5+1); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + +static void test_message_parser_garbage_suffix_mime_boundary(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--ab\n" +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--ac\n" +"Content-Type: text/plain\n" +"\n" +"body\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser garbage suffix mime boundary"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 2); + test_assert(parts->header_size.physical_size == 45); + test_assert(parts->header_size.virtual_size == 45+2); + test_assert(parts->body_size.lines == 7); + test_assert(parts->body_size.physical_size == 86); + test_assert(parts->body_size.virtual_size == 86+7); + test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->physical_pos == 50); + test_assert(parts->children->header_size.lines == 2); + test_assert(parts->children->header_size.physical_size == 45); + test_assert(parts->children->header_size.virtual_size == 45+2); + test_assert(parts->children->body_size.lines == 4); + test_assert(parts->children->body_size.physical_size == 36); + test_assert(parts->children->body_size.virtual_size == 36+4); + test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->children->physical_pos == 100); + test_assert(parts->children->children->header_size.lines == 2); + test_assert(parts->children->children->header_size.physical_size == 26); + test_assert(parts->children->children->header_size.virtual_size == 26+2); + test_assert(parts->children->children->body_size.lines == 1); + test_assert(parts->children->children->body_size.physical_size == 5); + test_assert(parts->children->children->body_size.virtual_size == 5+1); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + +static void test_message_parser_continuing_mime_boundary(void) +{ +static const char input_msg[] = +"Content-Type: multipart/mixed; boundary=\"a\"\n" +"\n" +"--a\n" +"Content-Type: multipart/mixed; boundary=\"ab\"\n" +"\n" +"--ab\n" +"Content-Type: text/plain\n" +"\n" +"body\n"; + struct message_parser_ctx *parser; + struct istream *input; + struct message_part *parts; + struct message_block block; + pool_t pool; + int ret; + + test_begin("message parser continuing mime boundary"); + pool = pool_alloconly_create("message parser", 10240); + input = test_istream_create(input_msg); + + parser = message_parser_init(pool, input, 0, 0); + while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ; + test_assert(ret < 0); + test_assert(message_parser_deinit(&parser, &parts) == 0); + + test_assert(parts->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->header_size.lines == 2); + test_assert(parts->header_size.physical_size == 45); + test_assert(parts->header_size.virtual_size == 45+2); + test_assert(parts->body_size.lines == 7); + test_assert(parts->body_size.physical_size == 86); + test_assert(parts->body_size.virtual_size == 86+7); + test_assert(parts->children->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->physical_pos == 49); + test_assert(parts->children->header_size.lines == 2); + test_assert(parts->children->header_size.physical_size == 46); + test_assert(parts->children->header_size.virtual_size == 46+2); + test_assert(parts->children->body_size.lines == 4); + test_assert(parts->children->body_size.physical_size == 36); + test_assert(parts->children->body_size.virtual_size == 36+4); + test_assert(parts->children->children->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(parts->children->children->physical_pos == 100); + test_assert(parts->children->children->header_size.lines == 2); + test_assert(parts->children->children->header_size.physical_size == 26); + test_assert(parts->children->children->header_size.virtual_size == 26+2); + test_assert(parts->children->children->body_size.lines == 1); + test_assert(parts->children->children->body_size.physical_size == 5); + test_assert(parts->children->children->body_size.virtual_size == 5+1); + + i_stream_unref(&input); + pool_unref(&pool); + test_end(); +} + static void test_message_parser_no_eoh(void) { static const char input_msg[] = "a:b\n"; @@ -228,6 +530,12 @@ static void (*test_functions[])(void) = { test_message_parser_small_blocks, test_message_parser_truncated_mime_headers, + test_message_parser_truncated_mime_headers2, + test_message_parser_truncated_mime_headers3, + test_message_parser_empty_multipart, + test_message_parser_duplicate_mime_boundary, + test_message_parser_garbage_suffix_mime_boundary, + test_message_parser_continuing_mime_boundary, test_message_parser_no_eoh, NULL }; diff -Nru dovecot-2.2.22/src/lib-master/Makefile.in dovecot-2.2.24/src/lib-master/Makefile.in --- dovecot-2.2.22/src/lib-master/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-master/Makefile.in 2016-04-26 15:10:50.000000000 +0000 @@ -273,7 +273,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-master/master-service-haproxy.c dovecot-2.2.24/src/lib-master/master-service-haproxy.c --- dovecot-2.2.22/src/lib-master/master-service-haproxy.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-master/master-service-haproxy.c 2016-04-26 13:01:21.000000000 +0000 @@ -466,9 +466,8 @@ while (service->haproxy_conns != NULL) { int fd = service->haproxy_conns->conn.fd; - if (close(fd) < 0) - i_error("haproxy: close(service connection) failed: %m"); master_service_haproxy_conn_free(service->haproxy_conns); + i_close_fd(&fd); } } diff -Nru dovecot-2.2.22/src/lib-master/master-service-settings.c dovecot-2.2.24/src/lib-master/master-service-settings.c --- dovecot-2.2.22/src/lib-master/master-service-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-master/master-service-settings.c 2016-04-26 13:01:21.000000000 +0000 @@ -107,7 +107,7 @@ const struct master_service_settings_input *input) { const char **conf_argv, *binary_path = service->argv[0]; - const char *home = NULL, *user = NULL; + const char *home = NULL, *user = NULL, *timestamp = NULL; unsigned int i, argv_max_count; (void)t_binary_abspath(&binary_path); @@ -117,11 +117,15 @@ home = getenv("HOME"); if (input->preserve_user) user = getenv("USER"); + if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0) + timestamp = getenv("LOG_STDERR_TIMESTAMP"); master_service_env_clean(); if (home != NULL) env_put(t_strconcat("HOME=", home, NULL)); if (user != NULL) env_put(t_strconcat("USER=", user, NULL)); + if (timestamp != NULL) + env_put(t_strconcat("LOG_STDERR_TIMESTAMP=", timestamp, NULL)); } if (input->use_sysexits) env_put("USE_SYSEXITS=1"); @@ -479,6 +483,7 @@ } i_close_fd(&fd); config_exec_fallback(service, input); + settings_parser_deinit(&parser); return -1; } @@ -494,19 +499,23 @@ if (use_environment || service->keep_environment) { if (settings_parse_environ(parser) < 0) { - *error_r = settings_parser_get_error(parser); + *error_r = t_strdup(settings_parser_get_error(parser)); + settings_parser_deinit(&parser); return -1; } } if (array_is_created(&service->config_overrides)) { if (master_service_apply_config_overrides(service, parser, - error_r) < 0) + error_r) < 0) { + settings_parser_deinit(&parser); return -1; + } } if (!settings_parser_check(parser, service->set_pool, &error)) { *error_r = t_strdup_printf("Invalid settings: %s", error); + settings_parser_deinit(&parser); return -1; } diff -Nru dovecot-2.2.22/src/lib-ntlm/Makefile.in dovecot-2.2.24/src/lib-ntlm/Makefile.in --- dovecot-2.2.22/src/lib-ntlm/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-ntlm/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-otp/Makefile.in dovecot-2.2.24/src/lib-otp/Makefile.in --- dovecot-2.2.22/src/lib-otp/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-otp/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-sasl/Makefile.in dovecot-2.2.24/src/lib-sasl/Makefile.in --- dovecot-2.2.22/src/lib-sasl/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-sasl/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-settings/Makefile.in dovecot-2.2.24/src/lib-settings/Makefile.in --- dovecot-2.2.22/src/lib-settings/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-settings/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-sql/driver-cassandra.c dovecot-2.2.24/src/lib-sql/driver-cassandra.c --- dovecot-2.2.22/src/lib-sql/driver-cassandra.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-sql/driver-cassandra.c 2016-04-26 13:01:21.000000000 +0000 @@ -8,6 +8,7 @@ #include "net.h" #include "write-full.h" #include "time-util.h" +#include "settings-parser.h" #include "sql-api-private.h" #ifdef BUILD_CASSANDRA @@ -46,11 +47,13 @@ struct cassandra_db { struct sql_db api; - char *hosts, *keyspace; + char *hosts, *keyspace, *user, *password; CassConsistency read_consistency, write_consistency, delete_consistency; CassConsistency read_fallback_consistency, write_fallback_consistency, delete_fallback_consistency; CassLogLevel log_level; unsigned int protocol_version; + unsigned int num_threads; + unsigned int connect_timeout_secs, request_timeout_secs; in_port_t port; CassCluster *cluster; @@ -366,7 +369,7 @@ static void driver_cassandra_parse_connect_string(struct cassandra_db *db, const char *connect_string) { - const char *const *args, *key, *value; + const char *const *args, *key, *value, *error; string_t *hosts = t_str_new(64); bool read_fallback_set = FALSE, write_fallback_set = FALSE, delete_fallback_set = FALSE; @@ -374,6 +377,8 @@ db->read_consistency = CASS_CONSISTENCY_LOCAL_QUORUM; db->write_consistency = CASS_CONSISTENCY_LOCAL_QUORUM; db->delete_consistency = CASS_CONSISTENCY_LOCAL_QUORUM; + db->connect_timeout_secs = SQL_CONNECT_TIMEOUT_SECS; + db->request_timeout_secs = SQL_QUERY_TIMEOUT_SECS; args = t_strsplit_spaces(connect_string, " "); for (; *args != NULL; args++) { @@ -395,6 +400,12 @@ strcmp(key, "keyspace") == 0) { i_free(db->keyspace); db->keyspace = i_strdup(value); + } else if (strcmp(key, "user") == 0) { + i_free(db->user); + db->user = i_strdup(value); + } else if (strcmp(key, "password") == 0) { + i_free(db->password); + db->password = i_strdup(value); } else if (strcmp(key, "read_consistency") == 0) { if (consistency_parse(value, &db->read_consistency) < 0) i_fatal("cassandra: Unknown read_consistency: %s", value); @@ -422,6 +433,15 @@ } else if (strcmp(key, "version") == 0) { if (str_to_uint(value, &db->protocol_version) < 0) i_fatal("cassandra: Invalid version: %s", value); + } else if (strcmp(key, "num_threads") == 0) { + if (str_to_uint(value, &db->num_threads) < 0) + i_fatal("cassandra: Invalid num_threads: %s", value); + } else if (strcmp(key, "connect_timeout") == 0) { + if (settings_get_time(value, &db->connect_timeout_secs, &error) < 0) + i_fatal("cassandra: Invalid connect_timeout '%s': %s", value, error); + } else if (strcmp(key, "request_timeout") == 0) { + if (settings_get_time(value, &db->request_timeout_secs, &error) < 0) + i_fatal("cassandra: Invalid request_timeout '%s': %s", value, error); } else { i_fatal("cassandra: Unknown connect string: %s", key); } @@ -457,13 +477,17 @@ db->timestamp_gen = cass_timestamp_gen_monotonic_new(); db->cluster = cass_cluster_new(); cass_cluster_set_timestamp_gen(db->cluster, db->timestamp_gen); - cass_cluster_set_connect_timeout(db->cluster, SQL_CONNECT_TIMEOUT_SECS * 1000); - cass_cluster_set_request_timeout(db->cluster, SQL_QUERY_TIMEOUT_SECS * 1000); + cass_cluster_set_connect_timeout(db->cluster, db->connect_timeout_secs * 1000); + cass_cluster_set_request_timeout(db->cluster, db->request_timeout_secs * 1000); cass_cluster_set_contact_points(db->cluster, db->hosts); + if (db->user != NULL && db->password != NULL) + cass_cluster_set_credentials(db->cluster, db->user, db->password); if (db->port != 0) cass_cluster_set_port(db->cluster, db->port); if (db->protocol_version != 0) cass_cluster_set_protocol_version(db->cluster, db->protocol_version); + if (db->num_threads != 0) + cass_cluster_set_num_threads_io(db->cluster, db->num_threads); db->session = cass_session_new(); i_array_init(&db->results, 16); i_array_init(&db->callbacks, 16); @@ -487,6 +511,8 @@ i_free(db->hosts); i_free(db->error); i_free(db->keyspace); + i_free(db->user); + i_free(db->password); array_free(&_db->module_contexts); i_free(db); } diff -Nru dovecot-2.2.22/src/lib-sql/Makefile.am dovecot-2.2.24/src/lib-sql/Makefile.am --- dovecot-2.2.22/src/lib-sql/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-sql/Makefile.am 2016-04-26 13:01:21.000000000 +0000 @@ -36,6 +36,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-settings \ $(SQL_CFLAGS) dist_sources = \ @@ -62,22 +63,22 @@ if SQL_PLUGINS libdriver_mysql_la_LDFLAGS = -module -avoid-version libdriver_mysql_la_LIBADD = $(MYSQL_LIBS) -libdriver_mysql_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(MYSQL_CFLAGS) +libdriver_mysql_la_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQL_CFLAGS) libdriver_mysql_la_SOURCES = driver-mysql.c libdriver_pgsql_la_LDFLAGS = -module -avoid-version libdriver_pgsql_la_LIBADD = $(PGSQL_LIBS) -libdriver_pgsql_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(PGSQL_CFLAGS) +libdriver_pgsql_la_CPPFLAGS = $(AM_CPPFLAGS) $(PGSQL_CFLAGS) libdriver_pgsql_la_SOURCES = driver-pgsql.c libdriver_sqlite_la_LDFLAGS = -module -avoid-version libdriver_sqlite_la_LIBADD = $(SQLITE_LIBS) -libdriver_sqlite_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(SQLITE_CFLAGS) +libdriver_sqlite_la_CPPFLAGS = $(AM_CPPFLAGS) $(SQLITE_CFLAGS) libdriver_sqlite_la_SOURCES = driver-sqlite.c libdriver_cassandra_la_LDFLAGS = -module -avoid-version libdriver_cassandra_la_LIBADD = $(CASSANDRA_LIBS) -libdriver_cassandra_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(CASSANDRA_CFLAGS) +libdriver_cassandra_la_CPPFLAGS = $(AM_CPPFLAGS) $(CASSANDRA_CFLAGS) libdriver_cassandra_la_SOURCES = driver-cassandra.c sql_libs = diff -Nru dovecot-2.2.22/src/lib-sql/Makefile.in dovecot-2.2.24/src/lib-sql/Makefile.in --- dovecot-2.2.22/src/lib-sql/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-sql/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -340,7 +340,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -491,6 +493,7 @@ @SQL_PLUGINS_TRUE@sql_moduledir = $(moduledir) AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-settings \ $(SQL_CFLAGS) dist_sources = \ @@ -514,19 +517,19 @@ @SQL_PLUGINS_TRUE@libdriver_mysql_la_LDFLAGS = -module -avoid-version @SQL_PLUGINS_TRUE@libdriver_mysql_la_LIBADD = $(MYSQL_LIBS) -@SQL_PLUGINS_TRUE@libdriver_mysql_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(MYSQL_CFLAGS) +@SQL_PLUGINS_TRUE@libdriver_mysql_la_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQL_CFLAGS) @SQL_PLUGINS_TRUE@libdriver_mysql_la_SOURCES = driver-mysql.c @SQL_PLUGINS_TRUE@libdriver_pgsql_la_LDFLAGS = -module -avoid-version @SQL_PLUGINS_TRUE@libdriver_pgsql_la_LIBADD = $(PGSQL_LIBS) -@SQL_PLUGINS_TRUE@libdriver_pgsql_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(PGSQL_CFLAGS) +@SQL_PLUGINS_TRUE@libdriver_pgsql_la_CPPFLAGS = $(AM_CPPFLAGS) $(PGSQL_CFLAGS) @SQL_PLUGINS_TRUE@libdriver_pgsql_la_SOURCES = driver-pgsql.c @SQL_PLUGINS_TRUE@libdriver_sqlite_la_LDFLAGS = -module -avoid-version @SQL_PLUGINS_TRUE@libdriver_sqlite_la_LIBADD = $(SQLITE_LIBS) -@SQL_PLUGINS_TRUE@libdriver_sqlite_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(SQLITE_CFLAGS) +@SQL_PLUGINS_TRUE@libdriver_sqlite_la_CPPFLAGS = $(AM_CPPFLAGS) $(SQLITE_CFLAGS) @SQL_PLUGINS_TRUE@libdriver_sqlite_la_SOURCES = driver-sqlite.c @SQL_PLUGINS_TRUE@libdriver_cassandra_la_LDFLAGS = -module -avoid-version @SQL_PLUGINS_TRUE@libdriver_cassandra_la_LIBADD = $(CASSANDRA_LIBS) -@SQL_PLUGINS_TRUE@libdriver_cassandra_la_CPPFLAGS = -I$(top_srcdir)/src/lib $(CASSANDRA_CFLAGS) +@SQL_PLUGINS_TRUE@libdriver_cassandra_la_CPPFLAGS = $(AM_CPPFLAGS) $(CASSANDRA_CFLAGS) @SQL_PLUGINS_TRUE@libdriver_cassandra_la_SOURCES = driver-cassandra.c @SQL_PLUGINS_FALSE@sql_libs = \ @SQL_PLUGINS_FALSE@ $(MYSQL_LIBS) \ diff -Nru dovecot-2.2.22/src/lib-ssl-iostream/iostream-openssl-common.c dovecot-2.2.24/src/lib-ssl-iostream/iostream-openssl-common.c --- dovecot-2.2.22/src/lib-ssl-iostream/iostream-openssl-common.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-ssl-iostream/iostream-openssl-common.c 2016-04-26 13:01:21.000000000 +0000 @@ -1,6 +1,7 @@ /* Copyright (c) 2009-2016 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "str.h" #include "iostream-openssl.h" #include @@ -185,24 +186,36 @@ const char *openssl_iostream_error(void) { + string_t *errstr = NULL; unsigned long err; - const char *data; + const char *data, *final_error; int flags; while ((err = ERR_get_error_line_data(NULL, NULL, &data, &flags)) != 0) { if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE) i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed"); - if (ERR_peek_error() != 0) + if (ERR_peek_error() == 0) break; - i_error("SSL: Stacked error: %s", - ssl_err2str(err, data, flags)); + if (errstr == NULL) + errstr = t_str_new(128); + else + str_append(errstr, ", "); + str_append(errstr, ssl_err2str(err, data, flags)); } if (err == 0) { if (errno != 0) - return strerror(errno); - return "Unknown error"; + final_error = strerror(errno); + else + final_error = "Unknown error"; + } else { + final_error = ssl_err2str(err, data, flags); + } + if (errstr == NULL) + return final_error; + else { + str_printfa(errstr, ", %s", final_error); + return str_c(errstr); } - return ssl_err2str(err, data, flags); } const char *openssl_iostream_key_load_error(void) diff -Nru dovecot-2.2.22/src/lib-ssl-iostream/Makefile.in dovecot-2.2.24/src/lib-ssl-iostream/Makefile.in --- dovecot-2.2.22/src/lib-ssl-iostream/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-ssl-iostream/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -280,7 +280,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-stats/Makefile.in dovecot-2.2.24/src/lib-stats/Makefile.in --- dovecot-2.2.22/src/lib-stats/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-stats/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-stats/stats-connection.c dovecot-2.2.24/src/lib-stats/stats-connection.c --- dovecot-2.2.22/src/lib-stats/stats-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-stats/stats-connection.c 2016-04-26 13:01:21.000000000 +0000 @@ -1,6 +1,7 @@ /* Copyright (c) 2011-2016 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "ioloop.h" #include "str.h" #include "master-service.h" #include "stats-connection.h" @@ -8,6 +9,8 @@ #include #include +#define STATS_EAGAIN_WARN_INTERVAL_SECS 30 + struct stats_connection { int refcount; @@ -15,6 +18,7 @@ char *path; bool open_failed; + time_t next_warning_timestamp; }; static bool stats_connection_open(struct stats_connection *conn) @@ -89,7 +93,17 @@ } ret = write(conn->fd, str_data(str), str_len(str)); - if (ret != (ssize_t)str_len(str)) { + if (ret == (ssize_t)str_len(str)) { + /* success */ + } else if (ret < 0 && errno == EAGAIN) { + /* stats process is busy */ + if (ioloop_time > conn->next_warning_timestamp) { + i_warning("write(%s) failed: %m (stats process is busy)", conn->path); + conn->next_warning_timestamp = ioloop_time + + STATS_EAGAIN_WARN_INTERVAL_SECS; + } + } else { + /* error - reconnect */ if (ret < 0) { /* don't log EPIPE errors. they can happen when Dovecot is stopped. */ diff -Nru dovecot-2.2.22/src/lib-storage/index/cydir/Makefile.in dovecot-2.2.24/src/lib-storage/index/cydir/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/cydir/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/cydir/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/dbox-common/Makefile.in dovecot-2.2.24/src/lib-storage/index/dbox-common/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/dbox-common/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/dbox-common/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -259,7 +259,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/dbox-multi/Makefile.in dovecot-2.2.24/src/lib-storage/index/dbox-multi/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/dbox-multi/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/dbox-multi/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -261,7 +261,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/dbox-single/Makefile.in dovecot-2.2.24/src/lib-storage/index/dbox-single/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/dbox-single/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/dbox-single/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -260,7 +260,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-list.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-list.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-list.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-list.c 2016-04-26 13:01:21.000000000 +0000 @@ -301,6 +301,7 @@ cmd = imapc_client_cmd(list->client->client, imapc_storage_sep_callback, list); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_send(cmd, "LIST \"\" \"\""); } @@ -324,9 +325,11 @@ struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list; char sep; - if (imapc_list_try_get_root_sep(list, &sep) < 0) { - /* we can't really fail here. just return a common separator - and keep failing all list commands until it succeeds. */ + if (list->root_sep_lookup_failed || + imapc_list_try_get_root_sep(list, &sep) < 0) { + /* we can't really return a failure here. just return a common + separator and fail all the future list operations. */ + list->root_sep_lookup_failed = TRUE; return '/'; } return sep; @@ -546,6 +549,10 @@ struct mailbox_node *node; const char *pattern; + if (list->root_sep_lookup_failed) { + mailbox_list_set_internal_error(&list->list); + return -1; + } if (list->refreshed_mailboxes) return 0; @@ -559,6 +566,7 @@ } cmd = imapc_list_simple_context_init(&ctx, list); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_sendf(cmd, "LIST \"\" %s", pattern); mailbox_tree_deinit(&list->mailboxes); list->mailboxes = mailbox_tree_init(mail_namespace_get_sep(list->list.ns)); @@ -774,6 +782,11 @@ i_assert(src_list->tmp_subscriptions == NULL); + if (src_list->root_sep_lookup_failed) { + mailbox_list_set_internal_error(_src_list); + return -1; + } + if (src_list->refreshed_subscriptions) { if (dest_list->subscriptions == NULL) dest_list->subscriptions = mailbox_tree_init(dest_sep); @@ -788,9 +801,13 @@ pattern = "*"; else pattern = t_strdup_printf("%s*", src_list->set->imapc_list_prefix); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_sendf(cmd, "LSUB \"\" %s", pattern); imapc_simple_run(&ctx); + if (ctx.ret < 0) + return -1; + /* replace subscriptions tree in destination */ if (dest_list->subscriptions != NULL) mailbox_tree_deinit(&dest_list->subscriptions); @@ -810,6 +827,7 @@ struct imapc_simple_context ctx; cmd = imapc_list_simple_context_init(&ctx, list); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_sendf(cmd, set ? "SUBSCRIBE %s" : "UNSUBSCRIBE %s", imapc_list_to_remote(list, name)); imapc_simple_run(&ctx); @@ -828,6 +846,7 @@ capa = imapc_client_get_capabilities(list->client->client); cmd = imapc_list_simple_context_init(&ctx, list); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); if (!imapc_command_connection_is_selected(cmd)) imapc_command_abort(&cmd); else { @@ -840,6 +859,7 @@ } cmd = imapc_list_simple_context_init(&ctx, list); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_sendf(cmd, "DELETE %s", imapc_list_to_remote(list, name)); imapc_simple_run(&ctx); diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-list.h dovecot-2.2.24/src/lib-storage/index/imapc/imapc-list.h --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-list.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-list.h 2016-04-26 13:01:21.000000000 +0000 @@ -30,6 +30,7 @@ unsigned int refreshed_mailboxes_recently:1; unsigned int index_list_failed:1; unsigned int root_sep_pending:1; + unsigned int root_sep_lookup_failed:1; }; int imapc_list_get_mailbox_flags(struct mailbox_list *list, const char *name, diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mailbox.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mailbox.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mailbox.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mailbox.c 2016-04-26 13:01:21.000000000 +0000 @@ -2,6 +2,7 @@ #include "lib.h" #include "ioloop.h" +#include "mail-index-modseq.h" #include "imap-arg.h" #include "imap-seqset.h" #include "imap-util.h" @@ -282,11 +283,12 @@ uint32_t lseq, rseq = reply->num; struct imapc_fetch_request *const *fetch_requestp; struct imapc_mail *const *mailp; - const struct imap_arg *list, *flags_list; + const struct imap_arg *list, *flags_list, *modseq_list; const char *atom, *guid = NULL; const struct mail_index_record *rec = NULL; enum mail_flags flags; uint32_t fetch_uid, uid; + uint64_t modseq = 0; unsigned int i, j; ARRAY_TYPE(const_string) keywords = ARRAY_INIT; bool seen_flags = FALSE, have_labels = FALSE; @@ -319,6 +321,15 @@ array_append(&keywords, &atom, 1); } } + } else if (strcasecmp(atom, "MODSEQ") == 0 && + imapc_storage_has_modseqs(mbox->storage)) { + /* (modseq-number) */ + if (!imap_arg_get_list(&list[i+1], &modseq_list)) + return; + if (!imap_arg_get_atom(&modseq_list[0], &atom) || + str_to_uint64(atom, &modseq) < 0 || + modseq_list[1].type != IMAP_ARG_EOL) + return; } else if (strcasecmp(atom, "X-GM-MSGID") == 0 && !mbox->initial_sync_done) { if (imap_arg_get_atom(&list[i+1], &atom)) @@ -414,6 +425,11 @@ } mail_index_keywords_unref(&kw); } + if (modseq != 0) { + if (mail_index_modseq_lookup(mbox->delayed_sync_view, lseq) < modseq) + mail_index_update_modseq(mbox->delayed_sync_trans, lseq, modseq); + array_idx_set(&mbox->rseq_modseqs, rseq-1, &modseq); + } if (guid != NULL) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(&mbox->box); const enum index_cache_field guid_cache_idx = @@ -454,6 +470,7 @@ } uid = imapc_msgmap_rseq_to_uid(msgmap, rseq); imapc_msgmap_expunge(msgmap, rseq); + array_delete(&mbox->rseq_modseqs, rseq-1, 1); imapc_mailbox_init_delayed_trans(mbox); if (mail_index_lookup_seq(mbox->sync_view, uid, &lseq)) @@ -579,6 +596,19 @@ } static void +imapc_resp_text_highestmodseq(const struct imapc_untagged_reply *reply, + struct imapc_mailbox *mbox) +{ + uint64_t highestmodseq; + + if (mbox == NULL || + str_to_uint64(reply->resp_text_value, &highestmodseq) < 0) + return; + + mbox->sync_highestmodseq = highestmodseq; +} + +static void imapc_resp_text_permanentflags(const struct imapc_untagged_reply *reply, struct imapc_mailbox *mbox) { @@ -646,6 +676,8 @@ imapc_resp_text_uidvalidity); imapc_mailbox_register_resp_text(mbox, "UIDNEXT", imapc_resp_text_uidnext); + imapc_mailbox_register_resp_text(mbox, "HIGHESTMODSEQ", + imapc_resp_text_highestmodseq); imapc_mailbox_register_resp_text(mbox, "PERMANENTFLAGS", imapc_resp_text_permanentflags); } diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mail.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mail.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mail.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mail.c 2016-04-26 13:01:21.000000000 +0000 @@ -96,6 +96,26 @@ return fix_broken_mail ? 0 : -1; } +static uint64_t imapc_mail_get_modseq(struct mail *_mail) +{ + struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; + struct imapc_msgmap *msgmap; + const uint64_t *modseqs; + unsigned int count; + uint32_t rseq; + + if (!imapc_storage_has_modseqs(mbox->storage)) + return index_mail_get_modseq(_mail); + + msgmap = imapc_client_mailbox_get_msgmap(mbox->client_box); + if (imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq)) { + modseqs = array_get(&mbox->rseq_modseqs, &count); + if (rseq <= count) + return modseqs[rseq-1]; + } + return 1; /* unknown modseq */ +} + static int imapc_mail_get_received_date(struct mail *_mail, time_t *date_r) { struct index_mail *mail = (struct index_mail *)_mail; @@ -561,7 +581,7 @@ index_mail_get_flags, index_mail_get_keywords, index_mail_get_keyword_indexes, - index_mail_get_modseq, + imapc_mail_get_modseq, index_mail_get_pvt_modseq, index_mail_get_parts, index_mail_get_date, diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mail-fetch.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mail-fetch.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-mail-fetch.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-mail-fetch.c 2016-04-26 13:01:21.000000000 +0000 @@ -419,6 +419,12 @@ "Message GUID not available in this server"); return -1; } + if (_mail->saving) { + mail_storage_set_error(_mail->box->storage, + MAIL_ERROR_NOTPOSSIBLE, + "Attempting to issue FETCH for a mail not yet committed"); + return -1; + } fields |= imapc_mail_get_wanted_fetch_fields(imail); T_BEGIN { diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-save.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-save.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-save.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-save.c 2016-04-26 13:01:21.000000000 +0000 @@ -261,6 +261,7 @@ sctx.ret = -2; cmd = imapc_client_cmd(ctx->mbox->storage->client->client, imapc_save_noop_callback, &sctx); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_send(cmd, "NOOP"); while (sctx.ret == -2) imapc_mailbox_run(ctx->mbox); diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-settings.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-settings.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-settings.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-settings.c 2016-04-26 13:01:21.000000000 +0000 @@ -93,6 +93,7 @@ { "proxyauth", IMAPC_FEATURE_PROXYAUTH }, { "fetch-msn-workarounds", IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS }, { "fetch-fix-broken-mails", IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS }, + { "modseq", IMAPC_FEATURE_MODSEQ }, { NULL, 0 } }; diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-settings.h dovecot-2.2.24/src/lib-storage/index/imapc/imapc-settings.h --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-settings.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-settings.h 2016-04-26 13:01:21.000000000 +0000 @@ -14,7 +14,8 @@ IMAPC_FEATURE_NO_EXAMINE = 0x40, IMAPC_FEATURE_PROXYAUTH = 0x80, IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS = 0x100, - IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS = 0x200 + IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS = 0x200, + IMAPC_FEATURE_MODSEQ = 0x400 }; /* */ diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-storage.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-storage.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-storage.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-storage.c 2016-04-26 13:01:21.000000000 +0000 @@ -55,6 +55,9 @@ struct imapc_storage_client *client); static void imapc_untagged_namespace(const struct imapc_untagged_reply *reply, struct imapc_storage_client *client); +static int imapc_mailbox_run_status(struct mailbox *box, + enum mailbox_status_items items, + struct mailbox_status *status_r); bool imap_resp_text_code_parse(const char *str, enum mail_error *error_r) { @@ -72,6 +75,16 @@ return FALSE; } +bool imapc_storage_has_modseqs(struct imapc_storage *storage) +{ + enum imapc_capability capa = + imapc_client_get_capabilities(storage->client->client); + + return (capa & (IMAPC_CAPABILITY_CONDSTORE | + IMAPC_CAPABILITY_QRESYNC)) != 0 && + IMAPC_HAS_FEATURE(storage, IMAPC_FEATURE_MODSEQ); +} + static struct mail_storage *imapc_storage_alloc(void) { struct imapc_storage *storage; @@ -430,8 +443,10 @@ { enum mailbox_info_flags flags; - if (imapc_list_get_mailbox_flags(box->list, box->name, &flags) < 0) + if (imapc_list_get_mailbox_flags(box->list, box->name, &flags) < 0) { + mail_storage_copy_list_error(box->storage, box->list); return -1; + } if ((flags & MAILBOX_NONEXISTENT) != 0) *existence_r = MAILBOX_EXISTENCE_NONE; else if ((flags & MAILBOX_NOSELECT) != 0) @@ -564,7 +579,8 @@ ctx.ret = -2; cmd = imapc_client_mailbox_cmd(mbox->client_box, imapc_mailbox_open_callback, &ctx); - imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_SELECT | + IMAPC_COMMAND_FLAG_RETRIABLE); if (imapc_mailbox_want_examine(mbox)) { imapc_command_sendf(cmd, "EXAMINE %s", imapc_mailbox_get_remote_name(mbox)); @@ -600,6 +616,13 @@ return -1; } + if (imapc_storage_has_modseqs(mbox->storage)) { + if (!array_is_created(&mbox->rseq_modseqs)) + i_array_init(&mbox->rseq_modseqs, 32); + else + array_clear(&mbox->rseq_modseqs); + } + if (imapc_mailbox_select(mbox) < 0) { mailbox_close(box); return -1; @@ -632,6 +655,8 @@ if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0) mailbox_set_index_error(&mbox->box); } + if (array_is_created(&mbox->rseq_modseqs)) + array_free(&mbox->rseq_modseqs); if (mbox->sync_view != NULL) mail_index_view_close(&mbox->sync_view); if (mbox->to_idle_delay != NULL) @@ -724,6 +749,9 @@ status->uidvalidity = num; else if (strcasecmp(key, "UNSEEN") == 0) status->unseen = num; + else if (strcasecmp(key, "HIGHESTMODSEQ") == 0 && + imapc_storage_has_modseqs(storage)) + status->highest_modseq = num; } } @@ -762,15 +790,32 @@ } } -static void imapc_mailbox_get_selected_status(struct imapc_mailbox *mbox, - enum mailbox_status_items items, - struct mailbox_status *status_r) +static int imapc_mailbox_get_selected_status(struct imapc_mailbox *mbox, + enum mailbox_status_items items, + struct mailbox_status *status_r) { + int ret = 0; + index_storage_get_open_status(&mbox->box, items, status_r); if ((items & STATUS_PERMANENT_FLAGS) != 0) status_r->permanent_flags = mbox->permanent_flags; if ((items & STATUS_FIRST_RECENT_UID) != 0) status_r->first_recent_uid = mbox->highest_nonrecent_uid + 1; + if ((items & STATUS_HIGHESTMODSEQ) != 0) { + /* FIXME: this doesn't work perfectly. we're now just returning + the HIGHESTMODSEQ from the current index, which may or may + not be correct. with QRESYNC enabled we could be returning + sync_highestmodseq, but that would require implementing + VANISHED replies. and without QRESYNC we'd have to issue + STATUS (HIGHESTMODSEQ), which isn't efficient since we get + here constantly (after every IMAP command). */ + } + if (imapc_storage_has_modseqs(mbox->storage)) { + /* even if local indexes are only in memory, we still + have modseqs on the IMAP server itself. */ + status_r->nonpermanent_modseqs = FALSE; + } + return ret; } static int imapc_mailbox_delete(struct mailbox *box) @@ -799,6 +844,9 @@ str_append(str, " UIDVALIDITY"); if ((items & STATUS_UNSEEN) != 0) str_append(str, " UNSEEN"); + if ((items & STATUS_HIGHESTMODSEQ) != 0 && + imapc_storage_has_modseqs(mbox->storage)) + str_append(str, " HIGHESTMODSEQ"); if (str_len(str) == 0) { /* nothing requested */ @@ -810,6 +858,7 @@ mbox->storage->cur_status = status_r; cmd = imapc_client_cmd(mbox->storage->client->client, imapc_simple_callback, &sctx); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_sendf(cmd, "STATUS %s (%1s)", imapc_mailbox_get_remote_name(mbox), str_c(str)+1); imapc_simple_run(&sctx); @@ -829,14 +878,17 @@ status_r->have_guids = TRUE; if (box->opened) { - imapc_mailbox_get_selected_status(mbox, items, status_r); + if (imapc_mailbox_get_selected_status(mbox, items, status_r) < 0) { + /* can't do anything about this */ + } } else if ((items & (STATUS_FIRST_UNSEEN_SEQ | STATUS_KEYWORDS | STATUS_PERMANENT_FLAGS | STATUS_FIRST_RECENT_UID)) != 0) { /* getting these requires opening the mailbox */ if (mailbox_open(box) < 0) return -1; - imapc_mailbox_get_selected_status(mbox, items, status_r); + if (imapc_mailbox_get_selected_status(mbox, items, status_r) < 0) + return -1; } else { if (imapc_mailbox_run_status(box, items, status_r) < 0) return -1; @@ -869,6 +921,7 @@ imapc_simple_context_init(&sctx, storage->client); cmd = imapc_client_cmd(storage->client->client, imapc_simple_callback, &sctx); + imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE); imapc_command_send(cmd, "NAMESPACE"); imapc_simple_run(&sctx); diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-storage.h dovecot-2.2.24/src/lib-storage/index/imapc/imapc-storage.h --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-storage.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-storage.h 2016-04-26 13:01:21.000000000 +0000 @@ -108,9 +108,11 @@ enum mail_flags permanent_flags; uint32_t highest_nonrecent_uid; + ARRAY(uint64_t) rseq_modseqs; ARRAY_TYPE(uint32_t) delayed_expunged_uids; uint32_t sync_uid_validity; uint32_t sync_uid_next; + uint64_t sync_highestmodseq; uint32_t sync_fetch_first_uid; uint32_t sync_next_lseq; uint32_t sync_next_rseq; @@ -165,6 +167,7 @@ void imapc_mail_cache_free(struct imapc_mail_cache *cache); int imapc_mailbox_select(struct imapc_mailbox *mbox); +bool imapc_storage_has_modseqs(struct imapc_storage *storage); bool imap_resp_text_code_parse(const char *str, enum mail_error *error_r); void imapc_copy_error_from_reply(struct imapc_storage *storage, enum mail_error default_error, diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/imapc-sync.c dovecot-2.2.24/src/lib-storage/index/imapc/imapc-sync.c --- dovecot-2.2.22/src/lib-storage/index/imapc/imapc-sync.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/imapc-sync.c 2016-04-26 13:01:21.000000000 +0000 @@ -5,6 +5,7 @@ #include "str.h" #include "imap-util.h" #include "mail-cache.h" +#include "mail-index-modseq.h" #include "index-sync-private.h" #include "imapc-client.h" #include "imapc-msgmap.h" @@ -245,6 +246,13 @@ } } +static void imapc_sync_highestmodseq(struct imapc_sync_context *ctx) +{ + if (imapc_storage_has_modseqs(ctx->mbox->storage) && + mail_index_modseq_get_highest(ctx->sync_view) < ctx->mbox->sync_highestmodseq) + mail_index_update_highest_modseq(ctx->trans, ctx->mbox->sync_highestmodseq); +} + static void imapc_initial_sync_check(struct imapc_sync_context *ctx, bool nooped) { @@ -311,6 +319,10 @@ string_t *cmd = t_str_new(64); str_printfa(cmd, "UID FETCH %u:* (FLAGS", first_uid); + if (imapc_storage_has_modseqs(ctx->mbox->storage)) { + str_append(cmd, " MODSEQ"); + mail_index_modseq_enable(ctx->mbox->box.index); + } if (IMAPC_BOX_HAS_FEATURE(ctx->mbox, IMAPC_FEATURE_GMAIL_MIGRATION)) { enum mailbox_info_flags flags; @@ -393,8 +405,9 @@ imapc_mailbox_run(mbox); array_free(&ctx->expunged_uids); - /* add uidnext after all appends */ + /* add uidnext & highestmodseq after all appends */ imapc_sync_uid_next(ctx); + imapc_sync_highestmodseq(ctx); if (!ctx->failed) imapc_sync_expunge_eom(ctx); diff -Nru dovecot-2.2.22/src/lib-storage/index/imapc/Makefile.in dovecot-2.2.24/src/lib-storage/index/imapc/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/imapc/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/imapc/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -260,7 +260,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/index-search.c dovecot-2.2.24/src/lib-storage/index/index-search.c --- dovecot-2.2.22/src/lib-storage/index/index-search.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/index-search.c 2016-04-26 13:01:21.000000000 +0000 @@ -985,9 +985,6 @@ /* UNSEEN with all seen? */ if (args->match_not) return FALSE; - - /* SEEN with all seen */ - args->match_always = TRUE; } else if (args->match_not) { /* UNSEEN with lowwater limiting */ search_limit_lowwater(ctx, @@ -1005,9 +1002,6 @@ /* UNDELETED with all deleted? */ if (args->match_not) return FALSE; - - /* DELETED with all deleted */ - args->match_always = TRUE; } else if (!args->match_not) { /* DELETED with lowwater limiting */ search_limit_lowwater(ctx, diff -Nru dovecot-2.2.22/src/lib-storage/index/maildir/Makefile.in dovecot-2.2.24/src/lib-storage/index/maildir/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/maildir/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/maildir/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -261,7 +261,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/Makefile.in dovecot-2.2.24/src/lib-storage/index/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -306,7 +306,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/mbox/Makefile.in dovecot-2.2.24/src/lib-storage/index/mbox/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/mbox/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/mbox/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -261,7 +261,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/pop3c/Makefile.in dovecot-2.2.24/src/lib-storage/index/pop3c/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/pop3c/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/pop3c/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -258,7 +258,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/raw/Makefile.in dovecot-2.2.24/src/lib-storage/index/raw/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/raw/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/raw/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/index/shared/Makefile.in dovecot-2.2.24/src/lib-storage/index/shared/Makefile.in --- dovecot-2.2.22/src/lib-storage/index/shared/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/index/shared/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/list/mailbox-list-fs-iter.c dovecot-2.2.24/src/lib-storage/list/mailbox-list-fs-iter.c --- dovecot-2.2.22/src/lib-storage/list/mailbox-list-fs-iter.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/list/mailbox-list-fs-iter.c 2016-04-26 13:01:21.000000000 +0000 @@ -350,6 +350,10 @@ validation. */ if (strncmp(test_pattern, _list->ns->prefix, prefix_len) == 0) test_pattern += prefix_len; + if (!uni_utf8_str_is_valid(test_pattern)) { + /* ignore invalid UTF8 patterns */ + continue; + } /* check pattern also when it's converted to use real separators. */ real_pattern = diff -Nru dovecot-2.2.22/src/lib-storage/list/mailbox-list-index-backend.c dovecot-2.2.24/src/lib-storage/list/mailbox-list-index-backend.c --- dovecot-2.2.22/src/lib-storage/list/mailbox-list-index-backend.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/list/mailbox-list-index-backend.c 2016-04-26 13:01:21.000000000 +0000 @@ -526,7 +526,8 @@ if (ret <= 0) return ret; - if ((_list->flags & MAILBOX_LIST_FLAG_NO_MAIL_FILES) != 0) { + if ((_list->flags & (MAILBOX_LIST_FLAG_NO_MAIL_FILES | + MAILBOX_LIST_FLAG_NO_DELETES)) != 0) { ret = 0; } else if ((_list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) { ret = mailbox_list_delete_mailbox_file(_list, name, path); @@ -535,7 +536,8 @@ path, TRUE); } - if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0) + if ((ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0) && + (_list->flags & MAILBOX_LIST_FLAG_NO_DELETES) == 0) index_list_delete_finish(_list, name); if (ret == 0) { if (index_list_delete_entry(list, name, TRUE) < 0) diff -Nru dovecot-2.2.22/src/lib-storage/list/mailbox-list-iter.c dovecot-2.2.24/src/lib-storage/list/mailbox-list-iter.c --- dovecot-2.2.22/src/lib-storage/list/mailbox-list-iter.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/list/mailbox-list-iter.c 2016-04-26 13:01:21.000000000 +0000 @@ -545,6 +545,18 @@ ctx->inbox_info.flags |= MAILBOX_NOCHILDREN; } +static void mailbox_list_ns_iter_failed(struct ns_list_iterate_context *ctx) +{ + enum mail_error error; + const char *errstr; + + if (ctx->cur_ns->list != ctx->error_list) { + errstr = mailbox_list_get_last_error(ctx->cur_ns->list, &error); + mailbox_list_set_error(ctx->error_list, error, errstr); + } + ctx->ctx.failed = TRUE; +} + static bool mailbox_list_ns_iter_try_next(struct mailbox_list_iterate_context *_ctx, const struct mailbox_info **info_r) @@ -553,8 +565,6 @@ (struct ns_list_iterate_context *)_ctx; struct mail_namespace *ns; const struct mailbox_info *info; - enum mail_error error; - const char *errstr; bool has_children; if (ctx->cur_ns == NULL) { @@ -640,12 +650,8 @@ } /* finished with this namespace */ - if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) { - errstr = mailbox_list_get_last_error(ctx->cur_ns->list, - &error); - mailbox_list_set_error(ctx->error_list, error, errstr); - _ctx->failed = TRUE; - } + if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) + mailbox_list_ns_iter_failed(ctx); ctx->cur_ns = ctx->cur_ns->next; return FALSE; } @@ -664,17 +670,11 @@ { struct ns_list_iterate_context *ctx = (struct ns_list_iterate_context *)_ctx; - enum mail_error error; - const char *errstr; int ret; if (ctx->backend_ctx != NULL) { - if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) { - errstr = mailbox_list_get_last_error(ctx->cur_ns->list, - &error); - mailbox_list_set_error(ctx->error_list, error, errstr); - _ctx->failed = TRUE; - } + if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0) + mailbox_list_ns_iter_failed(ctx); } ret = _ctx->failed ? -1 : 0; pool_unref(&ctx->pool); diff -Nru dovecot-2.2.22/src/lib-storage/list/Makefile.in dovecot-2.2.24/src/lib-storage/list/Makefile.in --- dovecot-2.2.22/src/lib-storage/list/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/list/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -265,7 +265,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/mail-autoexpunge.c dovecot-2.2.24/src/lib-storage/mail-autoexpunge.c --- dovecot-2.2.22/src/lib-storage/mail-autoexpunge.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-autoexpunge.c 2016-04-26 13:01:21.000000000 +0000 @@ -2,6 +2,7 @@ #include "lib.h" #include "ioloop.h" +#include "mailbox-list-iter.h" #include "mail-storage-private.h" #include "mail-namespace.h" #include "mail-user.h" @@ -58,11 +59,51 @@ return ret; } -static void mail_namespace_autoexpunge(struct mail_namespace *ns) +static void +mailbox_autoexpunge_set(struct mail_namespace *ns, const char *vname, + unsigned int autoexpunge) { - struct mailbox_settings *const *box_set; struct mailbox *box; time_t expire_time; + + expire_time = ioloop_time - autoexpunge; + + /* autoexpunge is configured by admin, so we can safely ignore + any ACLs the user might normally have against expunging in + the mailbox. */ + box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_IGNORE_ACLS); + if (mailbox_autoexpunge(box, expire_time) < 0) { + i_error("Failed to autoexpunge mailbox '%s': %s", + mailbox_get_vname(box), + mailbox_get_last_error(box, NULL)); + } + mailbox_free(&box); +} + +static void +mailbox_autoexpunge_wildcards(struct mail_namespace *ns, + const struct mailbox_settings *set) +{ + struct mailbox_list_iterate_context *iter; + const struct mailbox_info *info; + + iter = mailbox_list_iter_init(ns->list, set->name, + MAILBOX_LIST_ITER_NO_AUTO_BOXES | + MAILBOX_LIST_ITER_SKIP_ALIASES | + MAILBOX_LIST_ITER_RETURN_NO_FLAGS); + while ((info = mailbox_list_iter_next(iter)) != NULL) T_BEGIN { + mailbox_autoexpunge_set(ns, info->vname, set->autoexpunge); + } T_END; + if (mailbox_list_iter_deinit(&iter) < 0) { + i_error("Failed to iterate autoexpunge mailboxes '%s%s': %s", + ns->prefix, set->name, + mailbox_list_get_last_error(ns->list, NULL)); + } +} + +static void mail_namespace_autoexpunge(struct mail_namespace *ns) +{ + struct mailbox_settings *const *box_set; const char *vname; if (!array_is_created(&ns->set->mailboxes)) @@ -73,22 +114,16 @@ (unsigned int)ioloop_time < (*box_set)->autoexpunge) continue; - if ((*box_set)->name[0] == '\0' && ns->prefix_len > 0 && - ns->prefix[ns->prefix_len-1] == mail_namespace_get_sep(ns)) - vname = t_strndup(ns->prefix, ns->prefix_len - 1); - else - vname = t_strconcat(ns->prefix, (*box_set)->name, NULL); - expire_time = ioloop_time - (*box_set)->autoexpunge; - /* autoexpunge is configured by admin, so we can safely ignore - any ACLs the user might normally have against expunging in - the mailbox. */ - box = mailbox_alloc(ns->list, vname, MAILBOX_FLAG_IGNORE_ACLS); - if (mailbox_autoexpunge(box, expire_time) < 0) { - i_error("Failed to autoexpunge mailbox '%s': %s", - mailbox_get_vname(box), - mailbox_get_last_error(box, NULL)); + if (strpbrk((*box_set)->name, "*?") != NULL) + mailbox_autoexpunge_wildcards(ns, *box_set); + else { + if ((*box_set)->name[0] == '\0' && ns->prefix_len > 0 && + ns->prefix[ns->prefix_len-1] == mail_namespace_get_sep(ns)) + vname = t_strndup(ns->prefix, ns->prefix_len - 1); + else + vname = t_strconcat(ns->prefix, (*box_set)->name, NULL); + mailbox_autoexpunge_set(ns, vname, (*box_set)->autoexpunge); } - mailbox_free(&box); } } diff -Nru dovecot-2.2.22/src/lib-storage/mailbox-attribute.c dovecot-2.2.24/src/lib-storage/mailbox-attribute.c --- dovecot-2.2.22/src/lib-storage/mailbox-attribute.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mailbox-attribute.c 2016-04-26 13:01:21.000000000 +0000 @@ -447,6 +447,7 @@ /* wrapped */ intiter = (struct mailbox_attribute_internal_iter *)iter; ret = intiter->real_iter->box->v.attribute_iter_deinit(intiter->real_iter); + array_free(&intiter->extra_attrs); i_free(intiter); return ret; } diff -Nru dovecot-2.2.22/src/lib-storage/mailbox-list.h dovecot-2.2.24/src/lib-storage/mailbox-list.h --- dovecot-2.2.22/src/lib-storage/mailbox-list.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mailbox-list.h 2016-04-26 13:01:21.000000000 +0000 @@ -34,7 +34,9 @@ mailbox list to it. */ MAILBOX_LIST_FLAG_SECONDARY = 0x02, /* There are no mail files, only index and/or control files. */ - MAILBOX_LIST_FLAG_NO_MAIL_FILES = 0x04 + MAILBOX_LIST_FLAG_NO_MAIL_FILES = 0x04, + /* LAYOUT=index: Don't delete any files in delete_mailbox(). */ + MAILBOX_LIST_FLAG_NO_DELETES = 0x08 }; enum mailbox_info_flags { diff -Nru dovecot-2.2.22/src/lib-storage/mail-search.c dovecot-2.2.24/src/lib-storage/mail-search.c --- dovecot-2.2.22/src/lib-storage/mail-search.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-search.c 2016-04-26 13:01:21.000000000 +0000 @@ -649,8 +649,8 @@ case SEARCH_INTHREAD: if (arg1->value.thread_type != arg2->value.thread_type) return FALSE; - return mail_search_args_equal(arg1->initialized.search_args, - arg2->initialized.search_args); + return mail_search_arg_equals(arg1->value.subargs, + arg2->value.subargs); } i_unreached(); return FALSE; diff -Nru dovecot-2.2.22/src/lib-storage/mail-storage.c dovecot-2.2.24/src/lib-storage/mail-storage.c --- dovecot-2.2.22/src/lib-storage/mail-storage.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-storage.c 2016-04-26 13:01:21.000000000 +0000 @@ -360,6 +360,8 @@ list_flags |= MAILBOX_LIST_FLAG_MAILBOX_FILES; if ((storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0) list_flags |= MAILBOX_LIST_FLAG_NO_MAIL_FILES; + if ((storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_LIST_DELETES) != 0) + list_flags |= MAILBOX_LIST_FLAG_NO_DELETES; if (mailbox_list_create(list_set.layout, ns, &list_set, list_flags, &list, error_r) < 0) { *error_r = t_strdup_printf("Mailbox list driver %s: %s", diff -Nru dovecot-2.2.22/src/lib-storage/mail-storage-private.h dovecot-2.2.24/src/lib-storage/mail-storage-private.h --- dovecot-2.2.22/src/lib-storage/mail-storage-private.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-storage-private.h 2016-04-26 13:01:21.000000000 +0000 @@ -78,7 +78,10 @@ MAIL_STORAGE_CLASS_FLAG_BINARY_DATA = 0x100, /* Message GUIDs can only be 128bit (always set mailbox_status.have_only_guid128) */ - MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUID128 = 0x200 + MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUID128 = 0x200, + /* Storage deletes all files internally - mailbox list's + delete_mailbox() shouldn't delete anything itself. */ + MAIL_STORAGE_CLASS_FLAG_NO_LIST_DELETES = 0x400 }; struct mail_binary_cache { diff -Nru dovecot-2.2.22/src/lib-storage/mail-storage-service.c dovecot-2.2.24/src/lib-storage/mail-storage-service.c --- dovecot-2.2.22/src/lib-storage/mail-storage-service.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-storage-service.c 2016-04-26 13:01:21.000000000 +0000 @@ -82,6 +82,8 @@ const struct setting_parser_info *user_info; struct setting_parser_context *set_parser; + unsigned int session_id_counter; + unsigned int anonymous:1; unsigned int admin:1; }; @@ -324,6 +326,7 @@ info.remote_ip = input->remote_ip; info.local_port = input->local_port; info.remote_port = input->remote_port; + info.debug = input->debug; ret = auth_master_user_lookup(ctx->conn, *user, &info, pool, &new_username, fields_r); @@ -657,8 +660,15 @@ mail_user->admin = user->admin; mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token); mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user); - mail_user->session_id = - p_strdup(mail_user->pool, user->input.session_id); + if (user->session_id_counter++ == 0) { + mail_user->session_id = + p_strdup(mail_user->pool, user->input.session_id); + } else { + mail_user->session_id = + p_strdup_printf(mail_user->pool, "%s:%u", + user->input.session_id, + user->session_id_counter); + } mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL : p_strarray_dup(mail_user->pool, user->input.userdb_fields); mail_user->autoexpunge_enabled = @@ -1101,7 +1111,7 @@ string_t *str = str_new(pool, MAX_BASE64_ENCODED_SIZE(prefix_len + 1 + sizeof(guid))); if (prefix != NULL) - str_printfa(str, "%s-", prefix); + str_printfa(str, "%s:", prefix); guid_128_generate(guid); base64_encode(guid, sizeof(guid), str); @@ -1520,6 +1530,12 @@ void mail_storage_service_all_init(struct mail_storage_service_ctx *ctx) { + mail_storage_service_all_init_mask(ctx, ""); +} + +void mail_storage_service_all_init_mask(struct mail_storage_service_ctx *ctx, + const char *user_mask_hint) +{ enum auth_master_flags flags = 0; (void)mail_storage_service_all_iter_deinit(ctx); @@ -1532,7 +1548,8 @@ flags |= AUTH_MASTER_FLAG_DEBUG; ctx->iter_conn = auth_master_init(auth_master_get_socket_path(ctx->conn), flags); - ctx->auth_list = auth_master_user_list_init(ctx->iter_conn, "", NULL); + ctx->auth_list = auth_master_user_list_init(ctx->iter_conn, + user_mask_hint, NULL); } int mail_storage_service_all_next(struct mail_storage_service_ctx *ctx, diff -Nru dovecot-2.2.22/src/lib-storage/mail-storage-service.h dovecot-2.2.24/src/lib-storage/mail-storage-service.h --- dovecot-2.2.22/src/lib-storage/mail-storage-service.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/mail-storage-service.h 2016-04-26 13:01:21.000000000 +0000 @@ -58,6 +58,8 @@ /* override MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP for this lookup */ unsigned int no_userdb_lookup:1; + /* Enable auth_debug=yes for this lookup */ + unsigned int debug:1; }; extern struct module *mail_storage_service_modules; @@ -109,6 +111,11 @@ void mail_storage_service_user_free(struct mail_storage_service_user **user); /* Initialize iterating through all users. */ void mail_storage_service_all_init(struct mail_storage_service_ctx *ctx); +/* Same as mail_storage_service_all_init(), but give a user mask hint to the + userdb iteration lookup. This itself isn't yet guaranteed to filter out any + usernames. */ +void mail_storage_service_all_init_mask(struct mail_storage_service_ctx *ctx, + const char *user_mask_hint); /* Iterate through all usernames. Returns 1 if username was returned, 0 if there are no more users, -1 if error. */ int mail_storage_service_all_next(struct mail_storage_service_ctx *ctx, diff -Nru dovecot-2.2.22/src/lib-storage/Makefile.in dovecot-2.2.24/src/lib-storage/Makefile.in --- dovecot-2.2.22/src/lib-storage/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -346,7 +346,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-storage/register/Makefile.in dovecot-2.2.24/src/lib-storage/register/Makefile.in --- dovecot-2.2.22/src/lib-storage/register/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-storage/register/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -228,7 +228,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lib-test/Makefile.in dovecot-2.2.24/src/lib-test/Makefile.in --- dovecot-2.2.22/src/lib-test/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lib-test/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/lmtp/client.h dovecot-2.2.24/src/lmtp/client.h --- dovecot-2.2.22/src/lmtp/client.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lmtp/client.h 2016-04-26 13:01:21.000000000 +0000 @@ -8,6 +8,7 @@ struct mail_recipient { struct client *client; + const char *session_id; const char *address; const char *detail; /* +detail part is also in address */ diff -Nru dovecot-2.2.22/src/lmtp/commands.c dovecot-2.2.24/src/lmtp/commands.c --- dovecot-2.2.22/src/lmtp/commands.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lmtp/commands.c 2016-04-26 13:01:21.000000000 +0000 @@ -39,7 +39,7 @@ #define ERRSTR_TEMP_USERDB_FAIL \ ERRSTR_TEMP_USERDB_FAIL_PREFIX "Temporary user lookup failure" -#define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30) +#define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*125) static void client_input_data_write(struct client *client); @@ -655,6 +655,17 @@ return 0; } + /* Use a unique session_id for each mail delivery. This is especially + important for stats process to not see duplicate sessions. */ + if (array_count(&client->state.rcpt_to) == 0) + rcpt->session_id = client->state.session_id; + else { + rcpt->session_id = + p_strdup_printf(client->state_pool, "%s:%u", + client->state.session_id, + array_count(&client->state.rcpt_to)+1); + } + memset(&input, 0, sizeof(input)); input.module = input.service = "lmtp"; input.username = username; @@ -662,7 +673,7 @@ input.remote_ip = client->remote_ip; input.local_port = client->local_port; input.remote_port = client->remote_port; - input.session_id = client->state.session_id; + input.session_id = rcpt->session_id; ret = mail_storage_service_lookup(storage_service, &input, &rcpt->service_user, &error); @@ -829,7 +840,7 @@ dctx.pool = session->pool; dctx.set = lda_set; dctx.timeout_secs = LDA_SUBMISSION_TIMEOUT_SECS; - dctx.session_id = client->state.session_id; + dctx.session_id = rcpt->session_id; dctx.src_mail = src_mail; dctx.src_envelope_sender = client->state.mail_from; dctx.dest_user = client->state.dest_user; @@ -870,7 +881,7 @@ client->state.first_saved_mail = dctx.dest_mail; } client_send_line(client, "250 2.0.0 <%s> %s Saved", - rcpt->address, client->state.session_id); + rcpt->address, rcpt->session_id); ret = 0; } else if (dctx.tempfail_error != NULL) { client_send_line(client, "451 4.2.0 <%s> %s", diff -Nru dovecot-2.2.22/src/lmtp/Makefile.in dovecot-2.2.24/src/lmtp/Makefile.in --- dovecot-2.2.22/src/lmtp/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/lmtp/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -235,7 +235,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/log/Makefile.in dovecot-2.2.24/src/log/Makefile.in --- dovecot-2.2.22/src/log/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/log/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -233,7 +233,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/login-common/client-common-auth.c dovecot-2.2.24/src/login-common/client-common-auth.c --- dovecot-2.2.22/src/login-common/client-common-auth.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/login-common/client-common-auth.c 2016-04-26 13:01:21.000000000 +0000 @@ -206,7 +206,7 @@ str_printfa(str, " (master %s)", client->proxy_master_user); str_append(str, ": "); str_append(str, line); - i_info("%s", str_c(str)); + client_log(client, str_c(str)); } void client_proxy_failed(struct client *client, bool send_line) diff -Nru dovecot-2.2.22/src/login-common/login-proxy.c dovecot-2.2.24/src/login-common/login-proxy.c --- dovecot-2.2.22/src/login-common/login-proxy.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/login-common/login-proxy.c 2016-04-26 13:01:21.000000000 +0000 @@ -295,7 +295,7 @@ } str_append_c(str, ')'); - i_error("%s", str_c(str)); + client_log_err(proxy->client, str_c(str)); } static void proxy_reconnect_timeout(struct login_proxy *proxy) @@ -376,8 +376,9 @@ rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS && rec->num_waiting_connections != 0) { /* the server is down. fail immediately */ - i_error("proxy(%s): Host %s:%u is down", - proxy->client->virtual_user, proxy->host, proxy->port); + client_log_err(proxy->client, t_strdup_printf( + "proxy(%s): Host %s:%u is down", + proxy->client->virtual_user, proxy->host, proxy->port)); login_proxy_free(&proxy); return -1; } @@ -412,13 +413,15 @@ i_assert(client->login_proxy == NULL); if (set->host == NULL || *set->host == '\0') { - i_error("proxy(%s): host not given", client->virtual_user); + client_log_err(client, t_strdup_printf( + "proxy(%s): host not given", client->virtual_user)); return -1; } if (client->proxy_ttl <= 1) { - i_error("proxy(%s): TTL reached zero - " - "proxies appear to be looping?", client->virtual_user); + client_log_err(client, t_strdup_printf( + "proxy(%s): TTL reached zero - " + "proxies appear to be looping?", client->virtual_user)); return -1; } @@ -440,9 +443,10 @@ if (set->ip.family == 0 && net_addr2ip(set->host, &proxy->ip) < 0) { - i_error("proxy(%s): BUG: host %s is not an IP " + client_log_err(client, t_strdup_printf( + "proxy(%s): BUG: host %s is not an IP " "(auth should have changed it)", - client->virtual_user, set->host); + client->virtual_user, set->host)); } else { if (login_proxy_connect(proxy) < 0) return -1; diff -Nru dovecot-2.2.22/src/login-common/Makefile.in dovecot-2.2.24/src/login-common/Makefile.in --- dovecot-2.2.22/src/login-common/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/login-common/Makefile.in 2016-04-26 15:10:51.000000000 +0000 @@ -268,7 +268,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/login-common/ssl-proxy-openssl.c dovecot-2.2.24/src/login-common/ssl-proxy-openssl.c --- dovecot-2.2.22/src/login-common/ssl-proxy-openssl.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/login-common/ssl-proxy-openssl.c 2016-04-26 13:01:21.000000000 +0000 @@ -904,11 +904,13 @@ if (proxy->ssl_set->verbose_ssl || (proxy->login_set->auth_verbose && !preverify_ok)) { - if (preverify_ok) - i_info("Valid certificate: %s", buf); - else { - i_info("Invalid certificate: %s: %s", - X509_verify_cert_error_string(ctx->error), buf); + if (preverify_ok) { + client_log(proxy->client, t_strdup_printf( + "Valid certificate: %s", buf)); + } else { + client_log(proxy->client, t_strdup_printf( + "Invalid certificate: %s: %s", + X509_verify_cert_error_string(ctx->error), buf)); } } diff -Nru dovecot-2.2.22/src/Makefile.am dovecot-2.2.24/src/Makefile.am --- dovecot-2.2.22/src/Makefile.am 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/Makefile.am 2016-04-26 13:01:20.000000000 +0000 @@ -1,3 +1,7 @@ +if HAVE_LDAP +LIB_LDAP=lib-ldap +endif + LIBDOVECOT_SUBDIRS = \ lib-test \ lib \ @@ -18,6 +22,8 @@ SUBDIRS = \ $(LIBDOVECOT_SUBDIRS) \ + $(LIB_LDAP) \ + lib-dict-extra \ lib-dovecot \ lib-fts \ lib-imap-client \ diff -Nru dovecot-2.2.22/src/Makefile.in dovecot-2.2.24/src/Makefile.in --- dovecot-2.2.22/src/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/Makefile.in 2016-04-26 14:29:24.000000000 +0000 @@ -152,7 +152,15 @@ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) +DIST_SUBDIRS = lib-test lib lib-settings lib-auth lib-master \ + lib-charset lib-dns lib-dict lib-sasl lib-ssl-iostream \ + lib-stats lib-http lib-fs lib-mail lib-imap lib-imap-storage \ + lib-ldap lib-dict-extra lib-dovecot lib-fts lib-imap-client \ + lib-imap-urlauth lib-compression lib-index lib-storage lib-sql \ + lib-ntlm lib-otp lib-lda anvil auth dict dns indexer ipc \ + master login-common imap-hibernate imap-login imap \ + imap-urlauth pop3-login pop3 lda lmtp log config director \ + replication util doveadm ssl-params stats plugins am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ @@ -237,7 +245,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ @@ -370,6 +380,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +@HAVE_LDAP_TRUE@LIB_LDAP = lib-ldap LIBDOVECOT_SUBDIRS = \ lib-test \ lib \ @@ -390,6 +401,8 @@ SUBDIRS = \ $(LIBDOVECOT_SUBDIRS) \ + $(LIB_LDAP) \ + lib-dict-extra \ lib-dovecot \ lib-fts \ lib-imap-client \ diff -Nru dovecot-2.2.22/src/master/Makefile.in dovecot-2.2.24/src/master/Makefile.in --- dovecot-2.2.22/src/master/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/master/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -241,7 +241,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/acl/Makefile.in dovecot-2.2.24/src/plugins/acl/Makefile.in --- dovecot-2.2.22/src/plugins/acl/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/acl/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -277,7 +277,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/autocreate/Makefile.in dovecot-2.2.24/src/plugins/autocreate/Makefile.in --- dovecot-2.2.22/src/plugins/autocreate/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/autocreate/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/expire/Makefile.in dovecot-2.2.24/src/plugins/expire/Makefile.in --- dovecot-2.2.22/src/plugins/expire/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/expire/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -272,7 +272,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/fs-compress/Makefile.in dovecot-2.2.24/src/plugins/fs-compress/Makefile.in --- dovecot-2.2.22/src/plugins/fs-compress/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fs-compress/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -257,7 +257,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/fts/fts-parser-tika.c dovecot-2.2.24/src/plugins/fts/fts-parser-tika.c --- dovecot-2.2.22/src/plugins/fts/fts-parser-tika.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts/fts-parser-tika.c 2016-04-26 13:01:21.000000000 +0000 @@ -107,11 +107,13 @@ /* Server Error - the problem could be anything (in Tika or HTTP server or proxy) and might be retriable, but Tika has trouble processing some documents and throws up this error - every time for those documents. So we try retrying this a - couple of times, but if that doesn't work we'll just ignore - it. */ - if (http_client_request_try_retry(parser->http_req)) - return; + every time for those documents. + + Unfortunately we can't easily re-send the request here, + because we would have to re-send the entire payload, which + isn't available anymore here. So we'd need to indicate + in fts_parser_deinit() that we want to retry. + FIXME: do this in v2.3. For now we'll just ignore it. */ i_info("fts_tika: PUT %s failed: %u %s - ignoring", mail_user_plugin_getenv(parser->user, "fts_tika"), response->status, response->reason); diff -Nru dovecot-2.2.22/src/plugins/fts/Makefile.in dovecot-2.2.24/src/plugins/fts/Makefile.in --- dovecot-2.2.22/src/plugins/fts/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -286,7 +286,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/fts-lucene/lucene-wrapper.cc dovecot-2.2.24/src/plugins/fts-lucene/lucene-wrapper.cc --- dovecot-2.2.22/src/plugins/fts-lucene/lucene-wrapper.cc 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts-lucene/lucene-wrapper.cc 2016-04-26 13:01:21.000000000 +0000 @@ -819,6 +819,29 @@ } } +static void +rescan_clear_unseen_mailbox(struct rescan_context *rescan_ctx, + const char *vname, + const struct fts_index_header *hdr) +{ + struct mailbox *box; + struct mailbox_metadata metadata; + + box = mailbox_alloc(rescan_ctx->index->list, vname, + (enum mailbox_flags)0); + if (mailbox_open(box) == 0 && + mailbox_get_metadata(box, MAILBOX_METADATA_GUID, + &metadata) == 0 && + (rescan_ctx == NULL || + hash_table_lookup(rescan_ctx->seen_mailbox_guids, + metadata.guid) == NULL)) { + /* this mailbox had no records in lucene index. + make sure its last indexed uid is 0 */ + (void)fts_index_set_header(box, hdr); + } + mailbox_free(&box); +} + static void rescan_clear_unseen_mailboxes(struct lucene_index *index, struct rescan_context *rescan_ctx) { @@ -828,30 +851,25 @@ MAILBOX_LIST_ITER_RETURN_NO_FLAGS); struct mailbox_list_iterate_context *iter; const struct mailbox_info *info; - struct mailbox *box; - struct mailbox_metadata metadata; struct fts_index_header hdr; + struct mail_namespace *ns = index->list->ns; + const char *vname; memset(&hdr, 0, sizeof(hdr)); hdr.settings_checksum = fts_lucene_settings_checksum(&index->set); iter = mailbox_list_iter_init(index->list, "*", iter_flags); - while ((info = mailbox_list_iter_next(iter)) != NULL) { - box = mailbox_alloc(index->list, info->vname, - (enum mailbox_flags)0); - if (mailbox_open(box) == 0 && - mailbox_get_metadata(box, MAILBOX_METADATA_GUID, - &metadata) == 0 && - (rescan_ctx == NULL || - hash_table_lookup(rescan_ctx->seen_mailbox_guids, - metadata.guid) == NULL)) { - /* this mailbox had no records in lucene index. - make sure its last indexed uid is 0 */ - (void)fts_index_set_header(box, &hdr); - } - mailbox_free(&box); - } + while ((info = mailbox_list_iter_next(iter)) != NULL) + rescan_clear_unseen_mailbox(rescan_ctx, info->vname, &hdr); (void)mailbox_list_iter_deinit(&iter); + + if (ns->prefix_len > 0 && + ns->prefix[ns->prefix_len-1] == mail_namespace_get_sep(ns)) { + /* namespace prefix itself isn't returned by the listing */ + vname = t_strndup(index->list->ns->prefix, + index->list->ns->prefix_len-1); + rescan_clear_unseen_mailbox(rescan_ctx, vname, &hdr); + } } int lucene_index_rescan(struct lucene_index *index) diff -Nru dovecot-2.2.22/src/plugins/fts-lucene/Makefile.in dovecot-2.2.24/src/plugins/fts-lucene/Makefile.in --- dovecot-2.2.22/src/plugins/fts-lucene/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts-lucene/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -300,7 +300,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/fts-solr/Makefile.in dovecot-2.2.24/src/plugins/fts-solr/Makefile.in --- dovecot-2.2.22/src/plugins/fts-solr/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts-solr/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/fts-squat/Makefile.in dovecot-2.2.24/src/plugins/fts-squat/Makefile.in --- dovecot-2.2.22/src/plugins/fts-squat/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/fts-squat/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -271,7 +271,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/imap-acl/Makefile.in dovecot-2.2.24/src/plugins/imap-acl/Makefile.in --- dovecot-2.2.22/src/plugins/imap-acl/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/imap-acl/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/imap-quota/Makefile.in dovecot-2.2.24/src/plugins/imap-quota/Makefile.in --- dovecot-2.2.22/src/plugins/imap-quota/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/imap-quota/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/imap-stats/Makefile.in dovecot-2.2.24/src/plugins/imap-stats/Makefile.in --- dovecot-2.2.22/src/plugins/imap-stats/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/imap-stats/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/imap-zlib/Makefile.in dovecot-2.2.24/src/plugins/imap-zlib/Makefile.in --- dovecot-2.2.22/src/plugins/imap-zlib/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/imap-zlib/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/last-login/Makefile.in dovecot-2.2.24/src/plugins/last-login/Makefile.in --- dovecot-2.2.22/src/plugins/last-login/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/last-login/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/lazy-expunge/lazy-expunge-plugin.c dovecot-2.2.24/src/plugins/lazy-expunge/lazy-expunge-plugin.c --- dovecot-2.2.22/src/plugins/lazy-expunge/lazy-expunge-plugin.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/lazy-expunge/lazy-expunge-plugin.c 2016-04-26 13:01:21.000000000 +0000 @@ -31,6 +31,7 @@ union mail_user_module_context module_ctx; struct mail_namespace *lazy_ns; + const char *lazy_mailbox_vname; const char *env; bool copy_only_last_instance; }; @@ -66,15 +67,17 @@ static MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mail_user_module, &mail_user_module_register); -static struct mailbox * -mailbox_open_or_create(struct mailbox_list *list, struct mailbox *src_box, - const char **error_r) +static const char * +get_dest_vname(struct mailbox_list *list, struct mailbox *src_box) { - struct mailbox *box; - enum mail_error error; + struct lazy_expunge_mail_user *luser = + LAZY_EXPUNGE_USER_CONTEXT(list->ns->user); const char *name; char src_sep, dest_sep; + if (luser->lazy_mailbox_vname != NULL) + return luser->lazy_mailbox_vname; + /* use the (canonical / unaliased) storage name */ name = src_box->name; /* replace hierarchy separators with destination virtual separator */ @@ -93,7 +96,18 @@ name = str_c(str); } /* add expunge namespace prefix. the name is now a proper vname */ - name = t_strconcat(list->ns->prefix, name, NULL); + return t_strconcat(list->ns->prefix, name, NULL); +} + +static struct mailbox * +mailbox_open_or_create(struct mailbox_list *list, struct mailbox *src_box, + const char **error_r) +{ + struct mailbox *box; + enum mail_error error; + const char *name; + + name = get_dest_vname(list, src_box); box = mailbox_alloc(list, name, MAILBOX_FLAG_NO_INDEX_FILES); if (mailbox_open(box) == 0) { @@ -195,6 +209,30 @@ return refcount <= 1 ? 1 : 0; } +static bool lazy_expunge_is_internal_mailbox(struct mailbox *box) +{ + struct mail_namespace *ns = box->list->ns; + struct lazy_expunge_mail_user *luser = + LAZY_EXPUNGE_USER_CONTEXT(ns->user); + struct lazy_expunge_mailbox_list *llist = + LAZY_EXPUNGE_LIST_CONTEXT(box->list); + + if (llist == NULL) { + /* lazy_expunge not enabled at all */ + return FALSE; + } + if (llist->internal_namespace) { + /* lazy-expunge namespace */ + return TRUE; + } + if (luser->lazy_mailbox_vname != NULL && + strcmp(luser->lazy_mailbox_vname, box->vname) == 0) { + /* lazy-expunge mailbox */ + return TRUE; + } + return FALSE; +} + static void lazy_expunge_mail_expunge(struct mail *_mail) { struct mail_namespace *ns = _mail->box->list->ns; @@ -204,8 +242,6 @@ union mail_module_context *mmail = LAZY_EXPUNGE_MAIL_CONTEXT(mail); struct lazy_expunge_transaction *lt = LAZY_EXPUNGE_CONTEXT(_mail->transaction); - struct lazy_expunge_mailbox_list *llist; - struct mailbox *real_box; struct mail *real_mail; struct mail_save_context *save_ctx; const char *error; @@ -217,9 +253,7 @@ lt->failed = TRUE; return; } - real_box = real_mail->box; - llist = LAZY_EXPUNGE_LIST_CONTEXT(real_box->list); - if (llist != NULL && llist->internal_namespace) { + if (lazy_expunge_is_internal_mailbox(real_mail->box)) { mmail->super.expunge(_mail); return; } @@ -385,13 +419,17 @@ box->vlast = &mbox->super; MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module, mbox); - if (!llist->internal_namespace) { + if (!lazy_expunge_is_internal_mailbox(box)) { v->transaction_begin = lazy_expunge_transaction_begin; v->transaction_commit = lazy_expunge_transaction_commit; v->transaction_rollback = lazy_expunge_transaction_rollback; v->rename_box = lazy_expunge_mailbox_rename; - } else { + } else if (llist->internal_namespace) { v->rename_box = lazy_expunge_mailbox_rename; + } else { + /* internal mailbox in a non-internal namespace - + don't add any unnecessary restrictions to it. if it's not + wanted, just use the ACL plugin. */ } } @@ -427,13 +465,16 @@ return; luser->lazy_ns = mail_namespace_find_prefix(namespaces, luser->env); - if (luser->lazy_ns == NULL) - i_fatal("lazy_expunge: Unknown namespace: '%s'", luser->env); + if (luser->lazy_ns != NULL) { + /* we don't want to override this namespace's expunge operation. */ + llist = LAZY_EXPUNGE_LIST_CONTEXT(luser->lazy_ns->list); + llist->internal_namespace = TRUE; + } else { + /* store the the expunged mails to the specified mailbox. */ + luser->lazy_ns = mail_namespace_find(namespaces, luser->env); + luser->lazy_mailbox_vname = luser->env; + } mail_namespace_ref(luser->lazy_ns); - - /* we don't want to override this namespace's expunge operation. */ - llist = LAZY_EXPUNGE_LIST_CONTEXT(luser->lazy_ns->list); - llist->internal_namespace = TRUE; } static void lazy_expunge_user_deinit(struct mail_user *user) diff -Nru dovecot-2.2.22/src/plugins/lazy-expunge/Makefile.in dovecot-2.2.24/src/plugins/lazy-expunge/Makefile.in --- dovecot-2.2.22/src/plugins/lazy-expunge/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/lazy-expunge/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/listescape/Makefile.in dovecot-2.2.24/src/plugins/listescape/Makefile.in --- dovecot-2.2.22/src/plugins/listescape/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/listescape/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/mailbox-alias/Makefile.in dovecot-2.2.24/src/plugins/mailbox-alias/Makefile.in --- dovecot-2.2.22/src/plugins/mailbox-alias/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/mailbox-alias/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/mail-filter/Makefile.in dovecot-2.2.24/src/plugins/mail-filter/Makefile.in --- dovecot-2.2.22/src/plugins/mail-filter/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/mail-filter/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/mail-log/Makefile.in dovecot-2.2.24/src/plugins/mail-log/Makefile.in --- dovecot-2.2.22/src/plugins/mail-log/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/mail-log/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/Makefile.in dovecot-2.2.24/src/plugins/Makefile.in --- dovecot-2.2.22/src/plugins/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/Makefile.in 2016-04-26 14:29:26.000000000 +0000 @@ -241,7 +241,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/notify/Makefile.in dovecot-2.2.24/src/plugins/notify/Makefile.in --- dovecot-2.2.22/src/plugins/notify/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/notify/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/pop3-migration/Makefile.in dovecot-2.2.24/src/plugins/pop3-migration/Makefile.in --- dovecot-2.2.22/src/plugins/pop3-migration/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/pop3-migration/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -274,7 +274,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/push-notification/Makefile.in dovecot-2.2.24/src/plugins/push-notification/Makefile.in --- dovecot-2.2.22/src/plugins/push-notification/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/push-notification/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -282,7 +282,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/push-notification/push-notification-txn-msg.c dovecot-2.2.24/src/plugins/push-notification/push-notification-txn-msg.c --- dovecot-2.2.22/src/plugins/push-notification/push-notification-txn-msg.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/push-notification/push-notification-txn-msg.c 2016-04-26 13:01:21.000000000 +0000 @@ -45,7 +45,7 @@ struct push_notification_driver_txn **dtxn; struct seq_range_iter siter; struct mailbox_status status; - uint32_t uid; + uint32_t uid, uid_validity; struct push_notification_txn_msg *value; if (!hash_table_is_created(ptxn->messages)) { @@ -55,20 +55,21 @@ hiter = hash_table_iterate_init(ptxn->messages); seq_range_array_iter_init(&siter, &changes->saved_uids); + /* uid_validity is only set in changes if message is new. */ + if (changes->uid_validity == 0) { + mailbox_get_open_status(ptxn->mbox, STATUS_UIDVALIDITY, &status); + uid_validity = status.uidvalidity; + } else { + uid_validity = changes->uid_validity; + } + while (hash_table_iterate(hiter, ptxn->messages, &key, &value)) { if (value->uid == 0) { if (seq_range_array_iter_nth(&siter, value->seq, &uid)) { value->uid = uid; } } - - /* uid_validity is only set in changes if message is new. */ - if (changes->uid_validity == 0) { - mailbox_get_open_status(ptxn->mbox, STATUS_UIDVALIDITY, &status); - value->uid_validity = status.uidvalidity; - } else { - value->uid_validity = changes->uid_validity; - } + value->uid_validity = uid_validity; array_foreach_modifiable(&ptxn->drivers, dtxn) { if ((*dtxn)->duser->driver->v.process_msg != NULL) { diff -Nru dovecot-2.2.22/src/plugins/quota/Makefile.in dovecot-2.2.24/src/plugins/quota/Makefile.in --- dovecot-2.2.22/src/plugins/quota/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/quota/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -292,7 +292,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/quota/quota-fs.c dovecot-2.2.24/src/plugins/quota/quota-fs.c --- dovecot-2.2.22/src/plugins/quota/quota-fs.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/quota/quota-fs.c 2016-04-26 13:01:21.000000000 +0000 @@ -692,7 +692,7 @@ qk.qk_idtype = group ? QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER; qk.qk_id = group ? root->gid : root->uid; - for (i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) { qk.qk_objtype = i == 0 ? QUOTA_OBJTYPE_BLOCKS : QUOTA_OBJTYPE_FILES; if (quota_get(qh, &qk, &qv) != 0) { diff -Nru dovecot-2.2.22/src/plugins/quota-clone/Makefile.in dovecot-2.2.24/src/plugins/quota-clone/Makefile.in --- dovecot-2.2.22/src/plugins/quota-clone/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/quota-clone/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/replication/Makefile.in dovecot-2.2.24/src/plugins/replication/Makefile.in --- dovecot-2.2.22/src/plugins/replication/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/replication/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/snarf/Makefile.in dovecot-2.2.24/src/plugins/snarf/Makefile.in --- dovecot-2.2.22/src/plugins/snarf/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/snarf/Makefile.in 2016-04-26 15:10:52.000000000 +0000 @@ -261,7 +261,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/stats/Makefile.in dovecot-2.2.24/src/plugins/stats/Makefile.in --- dovecot-2.2.22/src/plugins/stats/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/stats/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -271,7 +271,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/stats/stats-plugin.c dovecot-2.2.24/src/plugins/stats/stats-plugin.c --- dovecot-2.2.22/src/plugins/stats/stats-plugin.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/stats/stats-plugin.c 2016-04-26 13:01:21.000000000 +0000 @@ -18,7 +18,7 @@ Must be smaller than MAIL_SESSION_IDLE_TIMEOUT_MSECS in stats server */ #define SESSION_STATS_FORCE_REFRESH_SECS (5*60) #define REFRESH_CHECK_INTERVAL 100 -#define MAIL_STATS_SOCKET_NAME "stats-mail" +#define MAIL_STATS_FIFO_NAME "stats-mail" struct stats_storage { union mail_storage_module_context module_ctx; @@ -379,8 +379,11 @@ } if (global_stats_conn == NULL) { - path = t_strconcat(user->set->base_dir, - "/"MAIL_STATS_SOCKET_NAME, NULL); + path = mail_user_plugin_getenv(user, "stats_notify_path"); + if (path == NULL) + path = MAIL_STATS_FIFO_NAME; + if (path[0] != '/') + path = t_strconcat(user->set->base_dir, "/", path, NULL); global_stats_conn = stats_connection_create(path); } stats_connection_ref(global_stats_conn); diff -Nru dovecot-2.2.22/src/plugins/trash/Makefile.in dovecot-2.2.24/src/plugins/trash/Makefile.in --- dovecot-2.2.22/src/plugins/trash/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/trash/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/virtual/Makefile.in dovecot-2.2.24/src/plugins/virtual/Makefile.in --- dovecot-2.2.22/src/plugins/virtual/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/virtual/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -264,7 +264,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/virtual/virtual-mail.c dovecot-2.2.24/src/plugins/virtual/virtual-mail.c --- dovecot-2.2.22/src/plugins/virtual/virtual-mail.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/virtual/virtual-mail.c 2016-04-26 13:01:21.000000000 +0000 @@ -55,6 +55,21 @@ return &vmail->imail.mail.mail; } +static void virtual_mail_close(struct mail *mail) +{ + struct virtual_mail *vmail = (struct virtual_mail *)mail; + struct mail **mails; + unsigned int i, count; + + mails = array_get_modifiable(&vmail->backend_mails, &count); + for (i = 0; i < count; i++) { + struct mail_private *p = (struct mail_private *)mails[i]; + + p->v.close(mails[i]); + } + index_mail_close(mail); +} + static void virtual_mail_free(struct mail *mail) { struct virtual_mail *vmail = (struct virtual_mail *)mail; @@ -487,7 +502,7 @@ } struct mail_vfuncs virtual_mail_vfuncs = { - NULL, + virtual_mail_close, virtual_mail_free, virtual_mail_set_seq, virtual_mail_set_uid, diff -Nru dovecot-2.2.22/src/plugins/zlib/Makefile.in dovecot-2.2.24/src/plugins/zlib/Makefile.in --- dovecot-2.2.22/src/plugins/zlib/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/zlib/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -262,7 +262,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/plugins/zlib/zlib-plugin.c dovecot-2.2.24/src/plugins/zlib/zlib-plugin.c --- dovecot-2.2.22/src/plugins/zlib/zlib-plugin.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/plugins/zlib/zlib-plugin.c 2016-04-26 13:01:21.000000000 +0000 @@ -154,6 +154,25 @@ return zmail->module_ctx.super.istream_opened(_mail, stream); } +static void zlib_mail_close(struct mail *_mail) +{ + struct mail_private *mail = (struct mail_private *)_mail; + struct zlib_mail *zmail = ZLIB_MAIL_CONTEXT(mail); + struct zlib_user *zuser = ZLIB_USER_CONTEXT(_mail->box->storage->user); + struct zlib_mail_cache *cache = &zuser->cache; + uoff_t size; + + if (cache->uid == _mail->uid && cache->box == _mail->box) { + /* make sure we have read the entire email into the seekable + stream (which causes the original input stream to be + unrefed). we can't safely keep the original input stream + open after the mail is closed. */ + if (i_stream_get_size(cache->input, TRUE, &size) < 0) + zlib_mail_cache_close(zuser); + } + zmail->module_ctx.super.close(_mail); +} + static void zlib_mail_allocated(struct mail *_mail) { struct zlib_transaction_context *zt = ZLIB_CONTEXT(_mail->transaction); @@ -169,6 +188,7 @@ mail->vlast = &zmail->module_ctx.super; v->istream_opened = zlib_istream_opened; + v->close = zlib_mail_close; MODULE_CONTEXT_SET(mail, zlib_mail_module, zmail); } diff -Nru dovecot-2.2.22/src/pop3/Makefile.in dovecot-2.2.24/src/pop3/Makefile.in --- dovecot-2.2.22/src/pop3/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/pop3/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -263,7 +263,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/pop3-login/client.c dovecot-2.2.24/src/pop3-login/client.c --- dovecot-2.2.22/src/pop3-login/client.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/pop3-login/client.c 2016-04-26 13:01:21.000000000 +0000 @@ -42,8 +42,8 @@ bool args_ok = TRUE; if (!client->common.trusted) { - client_send_reply(&client->common, POP3_CMD_REPLY_ERROR, - "You are not from trusted IP"); + client_send_reply(&client->common, POP3_CMD_REPLY_OK, + "You are not from trusted IP - ignoring"); return TRUE; } for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) { diff -Nru dovecot-2.2.22/src/pop3-login/Makefile.in dovecot-2.2.24/src/pop3-login/Makefile.in --- dovecot-2.2.22/src/pop3-login/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/pop3-login/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -232,7 +232,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/replication/aggregator/Makefile.in dovecot-2.2.24/src/replication/aggregator/Makefile.in --- dovecot-2.2.22/src/replication/aggregator/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/replication/aggregator/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/replication/Makefile.in dovecot-2.2.24/src/replication/Makefile.in --- dovecot-2.2.22/src/replication/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/replication/Makefile.in 2016-04-26 14:29:28.000000000 +0000 @@ -240,7 +240,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/replication/replicator/Makefile.in dovecot-2.2.24/src/replication/replicator/Makefile.in --- dovecot-2.2.22/src/replication/replicator/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/replication/replicator/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -238,7 +238,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/ssl-params/Makefile.in dovecot-2.2.24/src/ssl-params/Makefile.in --- dovecot-2.2.22/src/ssl-params/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/ssl-params/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -232,7 +232,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/stats/fifo-input-connection.c dovecot-2.2.24/src/stats/fifo-input-connection.c --- dovecot-2.2.22/src/stats/fifo-input-connection.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/stats/fifo-input-connection.c 2016-04-26 14:27:44.000000000 +0000 @@ -1,6 +1,7 @@ /* Copyright (c) 2011-2016 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "llist.h" #include "strescape.h" #include "istream.h" #include "ostream.h" @@ -15,11 +16,15 @@ #define MAX_INBUF_SIZE (PIPE_BUF*2) struct fifo_input_connection { + struct fifo_input_connection *prev, *next; + int fd; struct istream *input; struct io *io; }; +static struct fifo_input_connection *fifo_conns = NULL; + static int fifo_input_connection_request(const char *const *args, const char **error_r) { @@ -75,6 +80,7 @@ conn->fd = fd; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->io = io_add(fd, IO_READ, fifo_input_connection_input, conn); + DLLIST_PREPEND(&fifo_conns, conn); return conn; } @@ -84,9 +90,19 @@ *_conn = NULL; + DLLIST_REMOVE(&fifo_conns, conn); io_remove(&conn->io); i_stream_destroy(&conn->input); if (close(conn->fd) < 0) i_error("close(conn) failed: %m"); i_free(conn); } + +void fifo_input_connections_destroy_all(void) +{ + while (fifo_conns != NULL) { + struct fifo_input_connection *conn = fifo_conns; + + fifo_input_connection_destroy(&conn); + } +} diff -Nru dovecot-2.2.22/src/stats/fifo-input-connection.h dovecot-2.2.24/src/stats/fifo-input-connection.h --- dovecot-2.2.22/src/stats/fifo-input-connection.h 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/stats/fifo-input-connection.h 2016-04-26 14:27:44.000000000 +0000 @@ -4,4 +4,6 @@ struct fifo_input_connection *fifo_input_connection_create(int fd); void fifo_input_connection_destroy(struct fifo_input_connection **conn); +void fifo_input_connections_destroy_all(void); + #endif diff -Nru dovecot-2.2.22/src/stats/main.c dovecot-2.2.24/src/stats/main.c --- dovecot-2.2.22/src/stats/main.c 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/stats/main.c 2016-04-26 14:27:44.000000000 +0000 @@ -16,20 +16,14 @@ #include "mail-stats.h" #include "client.h" -static struct fifo_input_connection *fifo_input_conn = NULL; static struct module *modules = NULL; static void client_connected(struct master_service_connection *conn) { - if (conn->fifo) { - if (fifo_input_conn != NULL) { - i_error("Received another mail-server connection"); - return; - } - fifo_input_conn = fifo_input_connection_create(conn->fd); - } else { + if (conn->fifo) + (void)fifo_input_connection_create(conn->fd); + else (void)client_create(conn->fd); - } master_service_client_connection_accept(conn); } @@ -85,6 +79,7 @@ master_service_run(master_service, client_connected); clients_destroy_all(); + fifo_input_connections_destroy_all(); mail_commands_deinit(); mail_sessions_deinit(); mail_users_deinit(); @@ -92,9 +87,6 @@ mail_ips_deinit(); mail_global_deinit(); - if (fifo_input_conn != NULL) - fifo_input_connection_destroy(&fifo_input_conn); - module_dir_unload(&modules); i_assert(global_used_memory == 0); master_service_deinit(&master_service); diff -Nru dovecot-2.2.22/src/stats/Makefile.in dovecot-2.2.24/src/stats/Makefile.in --- dovecot-2.2.22/src/stats/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/stats/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -236,7 +236,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@ diff -Nru dovecot-2.2.22/src/util/Makefile.in dovecot-2.2.24/src/util/Makefile.in --- dovecot-2.2.22/src/util/Makefile.in 2016-03-16 10:13:55.000000000 +0000 +++ dovecot-2.2.24/src/util/Makefile.in 2016-04-26 15:10:53.000000000 +0000 @@ -247,7 +247,9 @@ LIBDOVECOT_COMPRESS = @LIBDOVECOT_COMPRESS@ LIBDOVECOT_DEPS = @LIBDOVECOT_DEPS@ LIBDOVECOT_DSYNC = @LIBDOVECOT_DSYNC@ +LIBDOVECOT_LA_LIBS = @LIBDOVECOT_LA_LIBS@ LIBDOVECOT_LDA = @LIBDOVECOT_LDA@ +LIBDOVECOT_LDAP = @LIBDOVECOT_LDAP@ LIBDOVECOT_LIBFTS = @LIBDOVECOT_LIBFTS@ LIBDOVECOT_LIBFTS_DEPS = @LIBDOVECOT_LIBFTS_DEPS@ LIBDOVECOT_LOGIN = @LIBDOVECOT_LOGIN@