summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2016-01-07 10:17:38 -0500
committerJakub Hrozek <jhrozek@redhat.com>2016-06-29 21:46:09 +0200
commite5911e72198df96ec7cfe486ff66363c2297a5f7 (patch)
treec425850775acad2e06fd1f9331014b69660b6952
parent4f3a9d837a55b49448eca3c713c85a406207e523 (diff)
downloadsssd-e5911e72198df96ec7cfe486ff66363c2297a5f7.tar.gz
sssd-e5911e72198df96ec7cfe486ff66363c2297a5f7.tar.xz
sssd-e5911e72198df96ec7cfe486ff66363c2297a5f7.zip
Responders: Add support for socket activation
Add helper that uses systemd socket activation if available to accept a pre-listining socket at startup. Related: https://fedorahosted.org/sssd/ticket/2913 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--Makefile.am14
-rw-r--r--src/responder/common/responder.h2
-rw-r--r--src/responder/common/responder_common.c74
-rw-r--r--src/tests/cwrap/Makefile.am2
4 files changed, 90 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 273842ccb..4c8bea8a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1230,6 +1230,7 @@ sssd_nss_LDADD = \
$(SSSD_LIBS) \
libsss_idmap.la \
libsss_cert.la \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS)
sssd_pam_SOURCES = \
@@ -1245,6 +1246,7 @@ sssd_pam_LDADD = \
$(SSSD_LIBS) \
$(SELINUX_LIBS) \
$(PAM_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
$(NULL)
@@ -1258,6 +1260,7 @@ sssd_sudo_SOURCES = \
$(SSSD_RESPONDER_OBJ)
sssd_sudo_LDADD = \
$(SSSD_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS)
endif
@@ -1269,6 +1272,7 @@ sssd_autofs_SOURCES = \
$(SSSD_RESPONDER_OBJ)
sssd_autofs_LDADD = \
$(SSSD_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS)
endif
@@ -1282,6 +1286,7 @@ sssd_ssh_SOURCES = \
sssd_ssh_LDADD = \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_cert.la \
$(NULL)
endif
@@ -1298,6 +1303,7 @@ sssd_pac_LDADD = \
$(NDR_KRB5PAC_LIBS) \
$(TDB_LIBS) \
$(SSSD_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_idmap.la \
$(SSSD_INTERNAL_LTLIBS)
@@ -1319,6 +1325,7 @@ sssd_ifp_CFLAGS = \
$(AM_CFLAGS)
sssd_ifp_LDADD = \
$(SSSD_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
libsss_cert.la \
$(NULL)
@@ -1961,6 +1968,7 @@ responder_socket_access_tests_LDADD = \
$(CHECK_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la
endif
@@ -2091,6 +2099,7 @@ nss_srv_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la \
libsss_cert.la \
libsss_idmap.la
@@ -2124,6 +2133,7 @@ pam_srv_tests_LDADD = \
$(PAM_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la \
libsss_idmap.la \
$(NULL)
@@ -2143,6 +2153,7 @@ responder_get_domains_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la
sbus_internal_tests_SOURCES = \
@@ -2205,6 +2216,7 @@ test_negcache_CFLAGS = \
test_negcache_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
libsss_test_common.la \
libsss_idmap.la
@@ -2502,6 +2514,7 @@ ifp_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la
sss_sifp_tests_SOURCES = \
@@ -2701,6 +2714,7 @@ responder_cache_req_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la \
$(NULL)
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index adf7b3d19..8db9e9894 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -194,6 +194,8 @@ errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
struct sss_domain_info **_ret_dom);
int create_pipe_fd(const char *sock_name, int *_fd, mode_t umaskval);
+int activate_unix_sockets(struct resp_ctx *rctx,
+ connection_setup_t conn_setup);
/* responder_cmd.c */
int sss_cmd_empty_packet(struct sss_packet *packet);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index e67456bb1..6fb2ed365 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -44,6 +44,10 @@
#include "sbus/sbus_client.h"
#include "util/util_creds.h"
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
static errno_t set_close_on_exec(int fd)
{
int v;
@@ -758,11 +762,77 @@ static int set_unix_socket(struct resp_ctx *rctx,
return EOK;
failed:
- close(rctx->lfd);
- close(rctx->priv_lfd);
+ if (rctx->lfd >= 0) close(rctx->lfd);
+ if (rctx->priv_lfd >= 0) close(rctx->priv_lfd);
return EIO;
}
+int activate_unix_sockets(struct resp_ctx *rctx,
+ connection_setup_t conn_setup)
+{
+ int ret;
+
+ /* by default we want to open sockets ourselves */
+ rctx->lfd = -1;
+ rctx->priv_lfd = -1;
+
+#ifdef HAVE_SYSTEMD
+ int numfds = (rctx->sock_name ? 1 : 0)
+ + (rctx->priv_sock_name ? 1 : 0);
+ /* but if systemd support is available, check if the sockets
+ * have been opened for us, via socket activation */
+ ret = sd_listen_fds(1);
+ if (ret < 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Unexpected error probing for active sockets. "
+ "Will proceed with no sockets. [Error %d (%s)]\n",
+ -ret, sss_strerror(-ret));
+ } else if (ret > numfds) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Too many activated sockets have been found, "
+ "expected %d, found %d\n", numfds, ret);
+ ret = E2BIG;
+ goto done;
+ }
+
+ if (ret == numfds) {
+ rctx->lfd = SD_LISTEN_FDS_START;
+ ret = sd_is_socket_unix(rctx->lfd, SOCK_STREAM, 1, NULL, 0);
+ if (ret < 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Activated socket is not a UNIX listening socket\n");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = sss_fd_nonblocking(rctx->lfd);
+ if (ret != EOK) goto done;
+ if (numfds == 2) {
+ rctx->priv_lfd = SD_LISTEN_FDS_START + 1;
+ ret = sd_is_socket_unix(rctx->priv_lfd, SOCK_STREAM, 1, NULL, 0);
+ if (ret < 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Activated priv socket is not a UNIX listening socket\n");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = sss_fd_nonblocking(rctx->priv_lfd);
+ if (ret != EOK) goto done;
+ }
+ }
+#endif
+
+ ret = set_unix_socket(rctx, conn_setup);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error initializing sockets\n");
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
int sss_connection_setup(struct cli_ctx *cctx)
{
cctx->protocol_ctx = talloc_zero(cctx, struct cli_protocol);
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
index 8005d9974..d8a49f143 100644
--- a/src/tests/cwrap/Makefile.am
+++ b/src/tests/cwrap/Makefile.am
@@ -145,6 +145,7 @@ responder_common_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SELINUX_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(abs_top_builddir)/libsss_util.la \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_test_common.la \
@@ -162,6 +163,7 @@ negcache_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
$(SELINUX_LIBS) \
+ $(SYSTEMD_DAEMON_LIBS) \
$(abs_top_builddir)/libsss_util.la \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_test_common.la \