Currently, slapd links libsystemd to notify service state to systemd.
However, libsystemd link several unnecessary libraries, which increases security risks.
The systemd documentation provides a method to send state notifications to systemd using a simple protocol without the need to link against libsystemd.
https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html
AUTH_LIBS = @AUTH_LIBS@
ARGON2_LIBS = @ARGON2_LIBS@
SECURITY_LIBS = $(SASL_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
-SYSTEMD_LIBS = @SYSTEMD_LIBS@
MODULES_CPPFLAGS = @SLAPD_MODULES_CPPFLAGS@
MODULES_LDFLAGS = @SLAPD_MODULES_LDFLAGS@
SLAPD_SQL_INCLUDES = @SLAPD_SQL_INCLUDES@
SLAPD_SQL_LIBS = @SLAPD_SQL_LIBS@
-SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@ $(SYSTEMD_LIBS)
+SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@
LLOADD_LIBS = @BALANCER_LIBS@ $(LEVENT_LIBS)
# Our Defaults
SLAPI_LIBS=
LIBSLAPI=
AUTH_LIBS=
-SYSTEMD_LIBS=
SLAPD_SLP_LIBS=
SLAPD_GMP_LIBS=
dnl
dnl Check for systemd (only if we have a server)
dnl
-WITH_SYSTEMD=no
systemdsystemunitdir=
-ol_link_systemd=no
if test $ol_enable_slapd = no && test $ol_enable_balancer != yes ; then
if test $ol_with_systemd != no ; then
AC_MSG_WARN([servers disabled, ignoring --with-systemd=$ol_with_systemd argument])
ol_with_systemd=no
fi
fi
-if test $ol_with_systemd != no ; then
- AC_CHECK_HEADERS(systemd/sd-daemon.h)
+if test $ol_with_systemd = auto; then
+ AC_CHECK_HEADERS(systemd/sd-daemon.h)
if test $ac_cv_header_systemd_sd_daemon_h = yes; then
- AC_CHECK_LIB(systemd, sd_notify,
- [ol_link_systemd="-lsystemd"])
+ ol_with_systemd=yes
fi
+fi
- if test $ol_link_systemd = no ; then
- if test $ol_with_systemd != auto ; then
- AC_MSG_ERROR([Could not locate systemd])
+if test $ol_with_systemd = yes ; then
+ AC_DEFINE(HAVE_SYSTEMD,1,[define if you have systemd])
+ PKG_CHECK_VAR(systemdsystemunitdir, systemd, systemdsystemunitdir)
+ if test -z "$systemdsystemunitdir"; then
+ if test -d /usr/lib/systemd/system; then
+ systemdsystemunitdir=/usr/lib/systemd/system
else
- AC_MSG_WARN([Could not locate systemd])
- AC_MSG_WARN([systemd service notification not supported!])
- fi
- else
- AC_DEFINE(HAVE_SYSTEMD,1,[define if you have systemd])
- SYSTEMD_LIBS="$ol_link_systemd"
- WITH_SYSTEMD=yes
-
- PKG_CHECK_VAR(systemdsystemunitdir, systemd, systemdsystemunitdir)
- if test -z "$systemdsystemunitdir"; then
- if test -d /usr/lib/systemd/system; then
- systemdsystemunitdir=/usr/lib/systemd/system
- else
- systemdsystemunitdir=/lib/systemd/system
- fi
+ systemdsystemunitdir=/lib/systemd/system
fi
fi
fi
AC_SUBST(WITH_TLS)
AC_SUBST(WITH_MODULES_ENABLED)
AC_SUBST(WITH_ACI_ENABLED)
-AC_SUBST(WITH_SYSTEMD)
AC_SUBST(BUILD_THREAD)
AC_SUBST(BUILD_LIBS_DYNAMIC)
AC_SUBST(OL_VERSIONED_SYMBOLS)
AC_SUBST(LIBSLAPI)
AC_SUBST(AUTH_LIBS)
AC_SUBST(ARGON2_LIBS)
-AC_SUBST(SYSTEMD_LIBS)
AC_SUBST(SLAPD_SLP_LIBS)
AC_SUBST(SLAPD_GMP_LIBS)
--- /dev/null
+/* SPDX-License-Identifier: MIT-0 */
+/* Implement the systemd notify protocol without external dependencies.
+ * Supports both readiness notification on startup and on reloading,
+ * according to the protocol defined at:
+ * https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
+ * This protocol is guaranteed to be stable as per:
+ * https://systemd.io/PORTABILITY_AND_STABILITY/ */
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define _cleanup_(f) __attribute__((cleanup(f)))
+static void closep(int *fd) {
+ if (!fd || *fd < 0)
+ return;
+ close(*fd);
+ *fd = -1;
+}
+
+static int sd_notify(int ignore, const char *message) {
+ union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_un sun;
+ } socket_addr = {
+ .sun.sun_family = AF_UNIX,
+ };
+ size_t path_length, message_length;
+ _cleanup_(closep) int fd = -1;
+ const char *socket_path;
+
+ socket_path = getenv("NOTIFY_SOCKET");
+ if (!socket_path)
+ return 0; /* Not running under systemd? Nothing to do */
+
+ if (!message)
+ return -EINVAL;
+
+ message_length = strlen(message);
+ if (message_length == 0)
+ return -EINVAL;
+
+ /* Only AF_UNIX is supported, with path or abstract sockets */
+ if (socket_path[0] != '/' && socket_path[0] != '@')
+ return -EAFNOSUPPORT;
+
+ path_length = strlen(socket_path);
+ /* Ensure there is room for NUL byte */
+ if (path_length >= sizeof(socket_addr.sun.sun_path))
+ return -E2BIG;
+
+ memcpy(socket_addr.sun.sun_path, socket_path, path_length);
+
+ /* Support for abstract socket */
+ if (socket_addr.sun.sun_path[0] == '@')
+ socket_addr.sun.sun_path[0] = 0;
+
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return -errno;
+
+ if (connect(fd, &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + path_length) != 0)
+ return -errno;
+
+ ssize_t written = write(fd, message, message_length);
+ if (written != (ssize_t) message_length)
+ return written < 0 ? -errno : -EPROTO;
+
+ return 1; /* Notified! */
+}
all-local-srv: $(PROGRAMS) all-cffiles
-XXLIBS += $(SYSTEMD_LIBS)
-
lloadd: $(LLOADD_DEPENDS) version.o
$(LTLINK) -o $@ $(OBJS) version.o $(LIBS)
#include "ldap_rq.h"
-#ifdef HAVE_SYSTEMD_SD_DAEMON_H
-#include <systemd/sd-daemon.h>
+#ifdef HAVE_SYSTEMD
+#include "sd-notify.h"
#endif
#ifdef LDAP_PF_LOCAL
#include "ldap_rq.h"
-#ifdef HAVE_SYSTEMD_SD_DAEMON_H
-#include <systemd/sd-daemon.h>
+#ifdef HAVE_SYSTEMD
+#include "sd-notify.h"
#endif
#ifdef HAVE_POLL