diff options
author | Simo Sorce <simo@redhat.com> | 2016-01-07 10:17:38 -0500 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2016-04-05 14:34:13 -0400 |
commit | 4610b546cb37a150ebaee12559c19a17e422708c (patch) | |
tree | c81726e6b6818908a24975fca3a3dfdbb01a65c0 /src | |
parent | 02e259e44631d228e0ec8311392e4a1a1a661b89 (diff) | |
download | sssd-4610b546cb37a150ebaee12559c19a17e422708c.tar.gz sssd-4610b546cb37a150ebaee12559c19a17e422708c.tar.xz sssd-4610b546cb37a150ebaee12559c19a17e422708c.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
Diffstat (limited to 'src')
-rw-r--r-- | src/responder/common/responder.h | 2 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 58 |
2 files changed, 58 insertions, 2 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 8fe01d71..b3a0c5a8 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -191,6 +191,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 7d32131e..f37cadd9 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; @@ -762,11 +766,61 @@ 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 = sss_fd_nonblocking(rctx->lfd); + if (ret != EOK) goto done; + if (numfds == 2) { + rctx->priv_lfd = SD_LISTEN_FDS_START + 1; + 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); |