From: Armin Schöffmann <[email protected]>
Correctly set the desired owner (from config file) and permission
settings for PF_LOCAL sockets of kopano-{server, dagent, gateway,
ical, statsd, indexd}. This was inconsistently handled before and got
substantially broken by changes introduced with commit
kopanocore-8.7.81-162-g5995dbf7c [MERGE].
[Amendement: Services normally exposed via TCP/IP get to have
S_IxOTH, services normally only exposed via PF_LOCAL socket get not
to have S_IxOTH. —jengelh]
Fixes: kopanocore-8.7.81-146-g1dbcce2e3
References: KF-2512
---
ECtools/idx_net.cpp | 3 ++-
ECtools/statsd.cpp | 3 ++-
caldav/CalDAV.cpp | 7 +++++--
gateway/Gateway.cpp | 13 +++++++++----
provider/server/ECSoapServerConnection.cpp | 15 ++++++++++-----
spooler/DAgent.cpp | 3 ++-
6 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/ECtools/idx_net.cpp b/ECtools/idx_net.cpp
index 246f34971..b624cd4a0 100644
--- a/ECtools/idx_net.cpp
+++ b/ECtools/idx_net.cpp
@@ -75,7 +75,8 @@ static int idx_listen(ECConfig *cfg, std::vector<struct
pollfd> &pollers)
x.events = POLLIN;
pollers.reserve(idx_sock.size());
for (const auto &spec : idx_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &x.fd, S_IRUSR |
S_IWUSR);
+ auto ret = ec_listen_generic(spec.c_str(), &x.fd, S_IRWUG,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0)
return ret;
pollers.push_back(x);
diff --git a/ECtools/statsd.cpp b/ECtools/statsd.cpp
index a49e8b312..27d058554 100644
--- a/ECtools/statsd.cpp
+++ b/ECtools/statsd.cpp
@@ -205,7 +205,8 @@ static HRESULT sd_listen(ECConfig *cfg, struct socks &sk)
memset(&pfd, 0, sizeof(pfd));
pfd.events = POLLIN;
for (const auto &spec : tokenize(cfg->GetSetting("statsd_listen"), ' ',
true)) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0)
return MAPI_E_NETWORK_ERROR;
sk.pollfd.push_back(pfd);
diff --git a/caldav/CalDAV.cpp b/caldav/CalDAV.cpp
index 4f68c6dd4..007509877 100644
--- a/caldav/CalDAV.cpp
+++ b/caldav/CalDAV.cpp
@@ -28,6 +28,7 @@
#include <iostream>
#include <string>
#include <getopt.h>
+#include <sys/stat.h>
#include <kopano/ECConfig.h>
#include <kopano/ECLogger.h>
#include <kopano/ECChannel.h>
@@ -334,7 +335,8 @@ static HRESULT ical_listen(ECConfig *cfg)
memset(&pfd, 0, sizeof(pfd));
pfd.events = POLLIN;
for (const auto &spec : ical_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
@@ -348,7 +350,8 @@ static HRESULT ical_listen(ECConfig *cfg)
g_socks.ssl.push_back(false);
}
for (const auto &spec : icals_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
diff --git a/gateway/Gateway.cpp b/gateway/Gateway.cpp
index b44df3af6..2d6c0d9c7 100644
--- a/gateway/Gateway.cpp
+++ b/gateway/Gateway.cpp
@@ -16,6 +16,7 @@
#include <netdb.h>
#include <poll.h>
#include <sys/resource.h>
+#include <sys/stat.h>
#include <inetmapi/inetmapi.h>
#include <mapi.h>
#include <mapix.h>
@@ -471,7 +472,8 @@ static HRESULT gw_listen(ECConfig *cfg)
memset(&pfd, 0, sizeof(pfd));
pfd.events = POLLIN;
for (const auto &spec : pop3_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
@@ -486,7 +488,8 @@ static HRESULT gw_listen(ECConfig *cfg)
g_socks.ssl.push_back(false);
}
for (const auto &spec : pop3s_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
@@ -501,7 +504,8 @@ static HRESULT gw_listen(ECConfig *cfg)
g_socks.ssl.push_back(true);
}
for (const auto &spec : imap_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
@@ -516,7 +520,8 @@ static HRESULT gw_listen(ECConfig *cfg)
g_socks.ssl.push_back(false);
}
for (const auto &spec : imaps_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &pfd.fd);
+ auto ret = ec_listen_generic(spec.c_str(), &pfd.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return MAPI_E_NETWORK_ERROR;
diff --git a/provider/server/ECSoapServerConnection.cpp
b/provider/server/ECSoapServerConnection.cpp
index 3725bc690..78f480b2f 100644
--- a/provider/server/ECSoapServerConnection.cpp
+++ b/provider/server/ECSoapServerConnection.cpp
@@ -160,7 +160,8 @@ static int ignore_shutdown(struct soap *, SOAP_SOCKET, int
shuttype)
}
static void custom_soap_bind(struct soap *soap, const char *bindspec,
- bool v6only, int port)
+ bool v6only, int port = 0, int mode = -1, const char *user = nullptr,
+ const char *group = nullptr)
{
#if GSOAP_VERSION >= 20857
/* The v6only field exists in 2.8.56, but has no effect there. */
@@ -168,7 +169,7 @@ static void custom_soap_bind(struct soap *soap, const char
*bindspec,
#endif
soap->sndbuf = soap->rcvbuf = 0;
soap->bind_flags = SO_REUSEADDR;
- auto ret = ec_listen_generic(bindspec, &soap->master);
+ auto ret = ec_listen_generic(bindspec, &soap->master, mode, user,
group);
if (ret < 0) {
ec_log_crit("Unable to bind to %s: %s. Terminating.", bindspec,
soap->fault != nullptr ? soap->fault->faultstring :
strerror(errno));
@@ -258,11 +259,15 @@ ECRESULT ECSoapServerConnection::ListenPipe(const char*
lpPipeName, bool bPriori
std::unique_ptr<struct soap, ec_soap_deleter>
lpsSoap(soap_new2(SOAP_IO_KEEPALIVE | SOAP_XML_TREE | SOAP_C_UTFSTRING,
SOAP_IO_KEEPALIVE | SOAP_XML_TREE | SOAP_C_UTFSTRING));
if (lpsSoap == nullptr)
return KCERR_NOT_ENOUGH_MEMORY;
- if (bPriority)
+ unsigned int mode = S_IRWUG;
+ if (bPriority) {
kopano_new_soap_listener(CONNECTION_TYPE_NAMED_PIPE_PRIORITY,
lpsSoap.get());
- else
+ } else {
kopano_new_soap_listener(CONNECTION_TYPE_NAMED_PIPE,
lpsSoap.get());
- custom_soap_bind(lpsSoap.get(), lpPipeName, false, 0);
+ mode |= S_IROTH | S_IWOTH;
+ }
+ custom_soap_bind(lpsSoap.get(), lpPipeName, false, 0, mode,
+ m_lpConfig->GetSetting("run_as_user"),
m_lpConfig->GetSetting("run_as_group"));
/* Manually check for attachments, independent of streaming support. */
soap_post_check_mime_attachments(lpsSoap.get());
m_lpDispatcher->AddListenSocket(std::move(lpsSoap));
diff --git a/spooler/DAgent.cpp b/spooler/DAgent.cpp
index 6b21209aa..553a1d48b 100644
--- a/spooler/DAgent.cpp
+++ b/spooler/DAgent.cpp
@@ -2841,7 +2841,8 @@ static int dagent_listen(ECConfig *cfg,
std::vector<struct pollfd> &pollers,
pollers.reserve(lmtp_sock.size());
closefd.reserve(lmtp_sock.size());
for (const auto &spec : lmtp_sock) {
- auto ret = ec_listen_generic(spec.c_str(), &x.fd, S_IRUSR |
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ auto ret = ec_listen_generic(spec.c_str(), &x.fd, S_IRWUG |
S_IROTH | S_IWOTH,
+ cfg->GetSetting("run_as_user"),
cfg->GetSetting("run_as_group"));
if (ret < 0) {
ec_log_err("Listening on %s failed: %s", spec.c_str(),
strerror(-ret));
return ret;
--
2.21.0