From: Marcin Krol Date: Wed, 16 Apr 2025 18:11:43 +0000 (+0200) Subject: - merged changes from PLD X-Git-Url: https://git.tld-linux.org/?a=commitdiff_plain;ds=inline;p=packages%2Fdovecot.git - merged changes from PLD --- diff --git a/dovecot-config.patch b/dovecot-config.patch index a1d90ef..c5c40a3 100644 --- a/dovecot-config.patch +++ b/dovecot-config.patch @@ -1,6 +1,6 @@ -diff -urNpa dovecot-ce-2.3.0.orig/doc/example-config/conf.d/10-ssl.conf dovecot-ce-2.3.0/doc/example-config/conf.d/10-ssl.conf ---- dovecot-ce-2.3.0.orig/doc/example-config/conf.d/10-ssl.conf 2017-12-22 13:53:36.000000000 +0000 -+++ dovecot-ce-2.3.0/doc/example-config/conf.d/10-ssl.conf 2018-01-19 10:16:36.961648643 +0000 +diff -urN dovecot-2.0.3.org/doc/example-config/conf.d/10-ssl.conf dovecot-2.0.3/doc/example-config/conf.d/10-ssl.conf +--- dovecot-2.0.3.org/doc/example-config/conf.d/10-ssl.conf 2010-05-24 16:35:40.000000000 +0200 ++++ dovecot-2.0.3/doc/example-config/conf.d/10-ssl.conf 2010-09-18 22:05:37.079775811 +0200 @@ -3,14 +3,14 @@ ## diff --git a/dovecot-lua-export-on-auth-fail.patch b/dovecot-lua-export-on-auth-fail.patch new file mode 100644 index 0000000..70c7000 --- /dev/null +++ b/dovecot-lua-export-on-auth-fail.patch @@ -0,0 +1,49 @@ +; export fields from lua back to dovecot also on userdb/passdb failures +; Patch by Przemysław Plewa +diff -urNp dovecot-2.3.21.1.org/src/auth/db-lua.c dovecot-2.3.21.1/src/auth/db-lua.c +--- dovecot-2.3.21.1.org/src/auth/db-lua.c 2024-08-13 12:37:50.000000000 +0200 ++++ dovecot-2.3.21.1/src/auth/db-lua.c 2025-02-19 10:28:54.277679024 +0100 +@@ -537,14 +537,13 @@ auth_lua_export_userdb_table(lua_State * + { + enum userdb_result ret = lua_tointeger(L, -2); + ++ auth_lua_export_table(L, req, NULL, NULL); ++ + if (ret != USERDB_RESULT_OK) { +- lua_pop(L, 2); +- lua_gc(L, LUA_GCCOLLECT, 0); + *error_r = "userdb failed"; + return ret; + } + +- auth_lua_export_table(L, req, NULL, NULL); + return USERDB_RESULT_OK; + } + +@@ -555,14 +554,13 @@ auth_lua_export_passdb_table(lua_State * + { + enum passdb_result ret = lua_tointeger(L, -2); + ++ auth_lua_export_table(L, req, scheme_r, password_r); ++ + if (ret != PASSDB_RESULT_OK) { +- lua_pop(L, 2); +- lua_gc(L, LUA_GCCOLLECT, 0); + *error_r = "passb failed"; + return ret; + } + +- auth_lua_export_table(L, req, scheme_r, password_r); + return PASSDB_RESULT_OK; + } + +@@ -585,7 +583,8 @@ auth_lua_call_lookup_finish(lua_State *L + + if (ret != PASSDB_RESULT_OK && ret != PASSDB_RESULT_NEXT) { + *error_r = str; +- } else { ++ } ++ if (str != NULL) { + auth_lua_export_fields(req, str, scheme_r, password_r); + } + diff --git a/dovecot-rpath.patch b/dovecot-rpath.patch index 07395fb..89f885f 100644 --- a/dovecot-rpath.patch +++ b/dovecot-rpath.patch @@ -1,7 +1,6 @@ -diff -urNpa dovecot-ce-2.3.0.orig/Makefile.am dovecot-ce-2.3.0/Makefile.am ---- dovecot-ce-2.3.0.orig/Makefile.am 2017-12-22 13:53:36.000000000 +0000 -+++ dovecot-ce-2.3.0/Makefile.am 2018-01-19 10:17:38.305644987 +0000 -@@ -73,7 +73,7 @@ install-exec-hook: +--- dovecot-2.2.18/Makefile.am~ 2015-02-19 12:44:40.000000000 +0100 ++++ dovecot-2.2.18/Makefile.am 2015-05-17 08:43:25.681245560 +0200 +@@ -64,7 +64,7 @@ install-exec-hook: grep -v '^LIBDOVECOT_.*_INCLUDE' dovecot-config | \ grep -v '^LIBDOVECOT.*_DEPS' | sed \ -e "s|^\(DOVECOT_INSTALLED\)=.*$$|\1=yes|" \ diff --git a/dovecot.init b/dovecot.init index 6a76990..4b1c3be 100644 --- a/dovecot.init +++ b/dovecot.init @@ -23,11 +23,20 @@ else exit 0 fi +if [ -n "${DOVECOT_CONF}" ]; then + if [ -f "${DOVECOT_CONF}" ]; then + DOVECOT_CFG="-c ${DOVECOT_CONF}" + else + echo "error: DOVECOT_CONF='$DOVECOT_CONF': not a file" + exit 1 + fi +fi + start() { # Check if the service is already running? if [ ! -f /var/lock/subsys/dovecot ]; then msg_starting "Dovecot" - daemon /usr/sbin/dovecot + daemon /usr/sbin/dovecot $DOVECOT_CFG RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/dovecot else diff --git a/dovecot.spec b/dovecot.spec index dcd06f2..cddb563 100644 --- a/dovecot.spec +++ b/dovecot.spec @@ -2,6 +2,7 @@ # Conditional build: %bcond_without gssapi # without GSSAPI support %bcond_without ldap # without LDAP auth +%bcond_without lua # without Lua auth %bcond_without mysql # without MySQL auth %bcond_without pgsql # without PostgreSQL auth %bcond_without sqlite # without SQLite3 auth @@ -12,7 +13,7 @@ Summary: IMAP and POP3 server written with security primarily in mind Summary(pl.UTF-8): Serwer IMAP i POP3 pisany głównie z myślą o bezpieczeństwie Name: dovecot Version: 2.3.21.1 -Release: 1 +Release: 2 Epoch: 1 License: MIT (libraries), LGPL v2.1 (the rest) Group: Networking/Daemons @@ -24,6 +25,10 @@ Source3: %{name}.sysconfig Patch0: %{name}-config.patch Patch1: %{name}-rpath.patch Patch2: %{name}-shebang.patch +Patch3: proc-status.patch +Patch4: openssl3.patch +Patch5: icu76.patch +Patch6: dovecot-lua-export-on-auth-fail.patch URL: http://dovecot.org/ BuildRequires: autoconf BuildRequires: automake @@ -40,18 +45,21 @@ BuildRequires: libicu-devel BuildRequires: libstemmer-devel BuildRequires: libexttextcat-devel BuildRequires: libtool +%{?with_lua:BuildRequires: lua53-devel} BuildRequires: lz4-devel %{?with_mysql:BuildRequires: mysql-devel} %{?with_ldap:BuildRequires: openldap-devel >= 2.3.3} BuildRequires: openssl-devel >= 0.9.7d BuildRequires: pam-devel BuildRequires: pkgconfig +BuildRequires: pkgconfig(lua) >= 5.1 %{?with_pgsql:BuildRequires: postgresql-devel} BuildRequires: rpmbuild(macros) >= 1.647 BuildRequires: sed >= 4.0 %{?with_sqlite:BuildRequires: sqlite3-devel} BuildRequires: xz-devel BuildRequires: zlib-devel +BuildRequires: zstd-devel Requires(post,preun): /sbin/chkconfig Requires(postun): /usr/sbin/groupdel Requires(postun): /usr/sbin/userdel @@ -62,6 +70,7 @@ Requires(pre): /usr/sbin/useradd Requires: %{name}-libs = %{epoch}:%{version}-%{release} Requires: pam >= 0.79.0 Provides: group(dovecot) +Provides: group(dovenull) Provides: imapdaemon Provides: pop3daemon Provides: user(dovecot) @@ -157,12 +166,18 @@ Pakiet programistyczny do tworzenia wtyczek dla Dovecota. %prep %setup -q -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 +%patch -P0 -p1 +%patch -P1 -p1 +%patch -P2 -p1 +%patch -P3 -p1 +%patch -P4 -p1 +%patch -P5 -p1 +%patch -P6 -p1 %{__sed} -i 's,/usr/lib/dovecot,%{_libdir}/dovecot,g' doc/example-config/*.conf doc/example-config/conf.d/*.conf +%{__sed} -i 's,#!/usr/bin/env bash,#!/bin/bash,' src/util/health-check.sh + %build touch config.rpath %{__libtoolize} @@ -171,15 +186,17 @@ touch config.rpath %{__autoheader} %{__automake} %configure \ - ac_cv_prog_VALGRIND=no \ + ac_cv_path_VALGRIND=reject \ CPPFLAGS="%{rpmcppflags} -I/usr/include/libstemmer -D_LINUX_QUOTA_VERSION=2" \ --disable-static \ + --enable-hardening \ %{?debug:--enable-debug} \ %{?with_ldap:--with-ldap=yes} \ %{?with_mysql:--with-mysql} \ %{?with_pgsql:--with-pgsql} \ %{?with_sqlite:--with-sqlite} \ %{?with_gssapi:--with-gssapi=plugin} \ + %{?with_lua:--with-lua=plugin} \ --with-lucene \ --with-stemmer \ --with-solr \ @@ -189,6 +206,10 @@ touch config.rpath --with-bzlib \ --with-libcap \ --with-ssl=openssl \ + --with-zstd \ +%ifarch x32 + --without-libunwind \ +%endif --with-moduledir=%{_libdir}/%{name}/plugins \ --with-ssldir=/var/lib/openssl \ --sysconfdir=%{_sysconfdir} @@ -373,8 +394,10 @@ fi %attr(755,root,root) %{_libdir}/%{name}/libdovecot-lda.so.0.0.0 %{?with_ldap:%attr(755,root,root) %{_libdir}/%{name}/libdovecot-ldap.so.0.0.0} %attr(755,root,root) %{_libdir}/%{name}/libdovecot-login.so.0.0.0 +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-lua.so.0.0.0 %attr(755,root,root) %{_libdir}/%{name}/libdovecot-sql.so.0.0.0 %attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage.so.0.0.0 +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage-lua.so.0.0.0 # Note: we are in %{_libdir}/dovecot, ldconfig does not look into this # directory. This is why the following files are not %ghost %attr(755,root,root) %{_libdir}/%{name}/libdovecot.so.0 @@ -384,8 +407,10 @@ fi %attr(755,root,root) %{_libdir}/%{name}/libdovecot-lda.so.0 %{?with_ldap:%attr(755,root,root) %{_libdir}/%{name}/libdovecot-ldap.so.0} %attr(755,root,root) %{_libdir}/%{name}/libdovecot-login.so.0 +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-lua.so.0 %attr(755,root,root) %{_libdir}/%{name}/libdovecot-sql.so.0 %attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage.so.0 +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage-lua.so.0 %files devel %defattr(644,root,root,755) @@ -396,8 +421,10 @@ fi %attr(755,root,root) %{_libdir}/%{name}/libdovecot-lda.so %{?with_ldap:%attr(755,root,root) %{_libdir}/%{name}/libdovecot-ldap.so} %attr(755,root,root) %{_libdir}/%{name}/libdovecot-login.so +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-lua.so %attr(755,root,root) %{_libdir}/%{name}/libdovecot-sql.so %attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage.so +%attr(755,root,root) %{_libdir}/%{name}/libdovecot-storage-lua.so %{_libdir}/%{name}/%{name}-config %{_includedir}/%{name} %{_aclocaldir}/dovecot.m4 diff --git a/icu76.patch b/icu76.patch new file mode 100644 index 0000000..b078b17 --- /dev/null +++ b/icu76.patch @@ -0,0 +1,11 @@ +--- dovecot-2.3.21.1/m4/want_icu.m4.orig 2024-08-13 12:37:50.000000000 +0200 ++++ dovecot-2.3.21.1/m4/want_icu.m4 2025-01-21 17:49:01.402262183 +0100 +@@ -1,7 +1,7 @@ + AC_DEFUN([DOVECOT_WANT_ICU], [ + if test "$want_icu" != "no"; then + if test "$PKG_CONFIG" != "" && $PKG_CONFIG --exists icu-i18n 2>/dev/null; then +- PKG_CHECK_MODULES(LIBICU, icu-i18n) ++ PKG_CHECK_MODULES(LIBICU, [icu-i18n icu-uc]) + have_icu=yes + AC_DEFINE(HAVE_LIBICU,, [Define if you want ICU normalization support for FTS]) + elif test "$want_icu" = "yes"; then diff --git a/openssl3.patch b/openssl3.patch new file mode 100644 index 0000000..fa6c44f --- /dev/null +++ b/openssl3.patch @@ -0,0 +1,34 @@ +diff -up dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c.opensslv3 dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c +--- dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c.opensslv3 2021-06-03 18:56:52.573174433 +0200 ++++ dovecot-2.3.14/src/lib-dcrypt/dcrypt-openssl.c 2021-06-03 18:56:52.585174274 +0200 +@@ -73,10 +73,30 @@ + 2key algo oid1symmetric algo namesalthash algoroundsE(RSA = i2d_PrivateKey, EC=Private Point)key id + **/ + ++#if OPENSSL_VERSION_MAJOR == 3 ++static EC_KEY *EVP_PKEY_get0_EC_KEYv3(EVP_PKEY *key) ++{ ++ EC_KEY *eck = EVP_PKEY_get1_EC_KEY(key); ++ EVP_PKEY_set1_EC_KEY(key, eck); ++ EC_KEY_free(eck); ++ return eck; ++} ++ ++static EC_KEY *EVP_PKEY_get1_EC_KEYv3(EVP_PKEY *key) ++{ ++ EC_KEY *eck = EVP_PKEY_get1_EC_KEY(key); ++ EVP_PKEY_set1_EC_KEY(key, eck); ++ return eck; ++} ++ ++#define EVP_PKEY_get0_EC_KEY EVP_PKEY_get0_EC_KEYv3 ++#define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEYv3 ++#else + #ifndef HAVE_EVP_PKEY_get0 + #define EVP_PKEY_get0_EC_KEY(x) x->pkey.ec + #define EVP_PKEY_get0_RSA(x) x->pkey.rsa + #endif ++#endif + + #ifndef HAVE_OBJ_LENGTH + #define OBJ_length(o) ((o)->length) diff --git a/proc-status.patch b/proc-status.patch new file mode 100644 index 0000000..1b7d021 --- /dev/null +++ b/proc-status.patch @@ -0,0 +1,236 @@ +From f359c6ee179aad5e077711c188fc8422106cbead Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Tue, 21 Mar 2023 08:55:55 +0200 +Subject: [PATCH 1/3] lib: process-stat - Use buffer_append_full_istream() to + read files + +--- + src/lib/process-stat.c | 84 ++++++++++++++++++++++-------------------- + 1 file changed, 44 insertions(+), 40 deletions(-) + +diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c +index 782503e60b..60eddbc3ec 100644 +--- a/src/lib/process-stat.c ++++ b/src/lib/process-stat.c +@@ -1,6 +1,9 @@ + /* Copyright (c) 2008-2021 Dovecot authors, see the included COPYING file */ + + #include "lib.h" ++#include "buffer.h" ++#include "str.h" ++#include "istream.h" + #include "process-stat.h" + #include "time-util.h" + #include +@@ -12,8 +15,12 @@ + #include + + #define PROC_STAT_PATH "/proc/self/stat" ++#define PROC_STAT_MAX_SIZE 1024 + #define PROC_STATUS_PATH "/proc/self/status" ++#define PROC_STATUS_MAX_SIZE 2048 + #define PROC_IO_PATH "/proc/self/io" ++#define PROC_IO_MAX_SIZE 1024 ++#define PROC_BUFFER_INITIAL_SIZE 512 + + static const uint64_t stat_undefined = 0xFFFFFFFFFFFFFFFF; + +@@ -71,39 +78,38 @@ static int open_fd(const char *path, struct event *event) + } + + static int +-read_file(int fd, const char *path, char *buf_r, size_t buf_size, struct event *event) ++read_file_buffer(const char *path, string_t *buf, size_t max_size, struct event *event) + { +- ssize_t ret; +- ret = read(fd, buf_r, buf_size); +- if (ret <= 0) { +- if (ret == -1) +- e_error(event, "read(%s) failed: %m", path); +- else +- e_error(event, "read(%s) returned EOF", path); +- } else if (ret == (ssize_t)buf_size) { +- e_error(event, "%s is larger than expected", path); +- buf_r[buf_size - 1] = '\0'; +- } else { +- buf_r[ret] = '\0'; ++ const char *error; ++ int fd = open_fd(path, event); ++ if (fd < 0) ++ return -1; ++ struct istream *is = i_stream_create_fd_autoclose(&fd, max_size); ++ i_stream_set_name(is, path); ++ enum buffer_append_result res = ++ buffer_append_full_istream(buf, is, max_size, &error); ++ i_stream_unref(&is); ++ if (res == BUFFER_APPEND_READ_MAX_SIZE) ++ e_error(event, "%s is larger than expected (%zu)", path, max_size); ++ else if (res != BUFFER_APPEND_OK) { ++ e_error(event, "read(%s) failed: %s", path, error); ++ return -1; + } +- i_close_fd(&fd); +- return ret <= 0 ? -1 : 0; ++ return 0; + } + + static int parse_key_val_file(const char *path, ++ size_t max_size, + struct key_val *fields, + struct event *event) + { +- char buf[2048]; +- int fd; +- +- fd = open_fd(path, event); +- if (fd == -1 || read_file(fd, path, buf, sizeof(buf), event) < 0) { ++ string_t *buf = t_str_new(PROC_BUFFER_INITIAL_SIZE); ++ if (read_file_buffer(path, buf, max_size, event) < 0) { + for (; fields->key != NULL; fields++) + *fields->value = stat_undefined; + return -1; + } +- buffer_parse(buf, fields); ++ buffer_parse(str_c(buf), fields); + return 0; + } + +@@ -117,7 +123,8 @@ static int parse_proc_io(struct process_stat *stat_r, struct event *event) + { NULL, NULL, 0 }, + }; + if (stat_r->proc_io_failed || +- parse_key_val_file(PROC_IO_PATH, fields, event) < 0) { ++ parse_key_val_file(PROC_IO_PATH, PROC_IO_MAX_SIZE, fields, ++ event) < 0) { + stat_r->proc_io_failed = TRUE; + return -1; + } +@@ -132,7 +139,8 @@ static int parse_proc_status(struct process_stat *stat_r, struct event *event) + { NULL, NULL, 0 }, + }; + if (stat_r->proc_status_failed || +- parse_key_val_file(PROC_STATUS_PATH, fields, event) < 0) { ++ parse_key_val_file(PROC_STATUS_PATH, PROC_STATUS_MAX_SIZE, ++ fields, event) < 0) { + stat_r->proc_status_failed = TRUE; + return -1; + } +@@ -156,8 +164,7 @@ static int stat_get_rusage(struct process_stat *stat_r) + + static int parse_stat_file(struct process_stat *stat_r, struct event *event) + { +- int fd = -1; +- char buf[1024]; ++ string_t *buf = t_str_new(PROC_BUFFER_INITIAL_SIZE); + unsigned int i; + const char *const *tmp; + struct { +@@ -171,9 +178,8 @@ static int parse_stat_file(struct process_stat *stat_r, struct event *event) + { &stat_r->vsz, 22 }, + { &stat_r->rss, 23 }, + }; +- if (!stat_r->proc_stat_failed) +- fd = open_fd(PROC_STAT_PATH, event); +- if (fd == -1) { ++ if (stat_r->proc_stat_failed || ++ read_file_buffer(PROC_STAT_PATH, buf, PROC_STAT_MAX_SIZE, event) < 0) { + stat_r->proc_stat_failed = TRUE; + /* vsz and rss are not provided by getrusage(), setting to undefined */ + stat_r->vsz = stat_undefined; +@@ -187,11 +193,7 @@ static int parse_stat_file(struct process_stat *stat_r, struct event *event) + } + return 0; + } +- if (read_file(fd, PROC_STAT_PATH, buf, sizeof(buf), event) < 0) { +- stat_r->proc_stat_failed = TRUE; +- return -1; +- } +- tmp = t_strsplit(buf, " "); ++ tmp = t_strsplit(str_c(buf), " "); + unsigned int tmp_count = str_array_length(tmp); + + for (i = 0; i < N_ELEMENTS(fields); i++) { +@@ -208,13 +210,15 @@ static int parse_all_stats(struct process_stat *stat_r, struct event *event) + { + bool has_fields = FALSE; + +- if (parse_stat_file(stat_r, event) == 0) +- has_fields = TRUE; +- if (parse_proc_io(stat_r, event) == 0) +- has_fields = TRUE; +- if ((!stat_r->proc_stat_failed || stat_r->rusage_failed) && +- parse_proc_status(stat_r, event) == 0) +- has_fields = TRUE; ++ T_BEGIN { ++ if (parse_stat_file(stat_r, event) == 0) ++ has_fields = TRUE; ++ if (parse_proc_io(stat_r, event) == 0) ++ has_fields = TRUE; ++ if ((!stat_r->proc_stat_failed || stat_r->rusage_failed) && ++ parse_proc_status(stat_r, event) == 0) ++ has_fields = TRUE; ++ } T_END; + + if (has_fields) + return 0; + +From 218a79a48bb0e5d2be44bb46c51836fd406b0c50 Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Tue, 21 Mar 2023 09:05:12 +0200 +Subject: [PATCH 2/3] lib: process-stat - Increase maximum /proc/self/status + size + +Kernel 6.x has larger status file. +--- + src/lib/process-stat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c +index 60eddbc3ec..1d23c89964 100644 +--- a/src/lib/process-stat.c ++++ b/src/lib/process-stat.c +@@ -17,7 +17,7 @@ + #define PROC_STAT_PATH "/proc/self/stat" + #define PROC_STAT_MAX_SIZE 1024 + #define PROC_STATUS_PATH "/proc/self/status" +-#define PROC_STATUS_MAX_SIZE 2048 ++#define PROC_STATUS_MAX_SIZE 4096 + #define PROC_IO_PATH "/proc/self/io" + #define PROC_IO_MAX_SIZE 1024 + #define PROC_BUFFER_INITIAL_SIZE 512 + +From d93c31d51b05d43eaa6eeef9cdc0f7a4157f7d0e Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Tue, 21 Mar 2023 09:13:35 +0200 +Subject: [PATCH 3/3] lib: process-stat - Use eacces_error_get() for EACCES + errno + +This tells better why the open failed. +--- + src/lib/process-stat.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c +index 1d23c89964..454d9335d2 100644 +--- a/src/lib/process-stat.c ++++ b/src/lib/process-stat.c +@@ -4,6 +4,7 @@ + #include "buffer.h" + #include "str.h" + #include "istream.h" ++#include "eacces-error.h" + #include "process-stat.h" + #include "time-util.h" + #include +@@ -69,8 +70,10 @@ static int open_fd(const char *path, struct event *event) + errno = EACCES; + } + if (fd == -1) { +- if (errno == ENOENT || errno == EACCES) ++ if (errno == ENOENT) + e_debug(event, "open(%s) failed: %m", path); ++ else if (errno == EACCES) ++ e_debug(event, "%s", eacces_error_get("open", path)); + else + e_error(event, "open(%s) failed: %m", path); + }