| |
@@ -0,0 +1,201 @@
|
| |
+ diff --git a/configure.ac b/configure.ac
|
| |
+ index 379cd746b..15e2ecdb7 100644
|
| |
+ --- a/configure.ac
|
| |
+ +++ b/configure.ac
|
| |
+ @@ -907,6 +907,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
| |
+ AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
|
| |
+ AC_DEFINE([USE_BTMP])
|
| |
+ AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])
|
| |
+ + AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload])
|
| |
+ inet6_default_4in6=yes
|
| |
+ case `uname -r` in
|
| |
+ 1.*|2.0.*)
|
| |
+ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
|
| |
+ index 0457e28d0..df7290246 100644
|
| |
+ --- a/openbsd-compat/port-linux.c
|
| |
+ +++ b/openbsd-compat/port-linux.c
|
| |
+ @@ -21,16 +21,23 @@
|
| |
+
|
| |
+ #include "includes.h"
|
| |
+
|
| |
+ -#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
|
| |
+ +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) || \
|
| |
+ + defined(SYSTEMD_NOTIFY)
|
| |
+ +#include <sys/socket.h>
|
| |
+ +#include <sys/un.h>
|
| |
+ +
|
| |
+ #include <errno.h>
|
| |
+ +#include <inttypes.h>
|
| |
+ #include <stdarg.h>
|
| |
+ #include <string.h>
|
| |
+ #include <stdio.h>
|
| |
+ #include <stdlib.h>
|
| |
+ +#include <time.h>
|
| |
+
|
| |
+ #include "log.h"
|
| |
+ #include "xmalloc.h"
|
| |
+ #include "port-linux.h"
|
| |
+ +#include "misc.h"
|
| |
+
|
| |
+ #ifdef WITH_SELINUX
|
| |
+ #include <selinux/selinux.h>
|
| |
+ @@ -310,4 +317,90 @@ oom_adjust_restore(void)
|
| |
+ return;
|
| |
+ }
|
| |
+ #endif /* LINUX_OOM_ADJUST */
|
| |
+ -#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */
|
| |
+ +
|
| |
+ +#ifdef SYSTEMD_NOTIFY
|
| |
+ +
|
| |
+ +static void ssh_systemd_notify(const char *, ...)
|
| |
+ + __attribute__((__format__ (printf, 1, 2))) __attribute__((__nonnull__ (1)));
|
| |
+ +
|
| |
+ +static void
|
| |
+ +ssh_systemd_notify(const char *fmt, ...)
|
| |
+ +{
|
| |
+ + char *s = NULL;
|
| |
+ + const char *path;
|
| |
+ + struct stat sb;
|
| |
+ + struct sockaddr_un addr;
|
| |
+ + int fd = -1;
|
| |
+ + va_list ap;
|
| |
+ +
|
| |
+ + if ((path = getenv("NOTIFY_SOCKET")) == NULL || strlen(path) == 0)
|
| |
+ + return;
|
| |
+ +
|
| |
+ + va_start(ap, fmt);
|
| |
+ + xvasprintf(&s, fmt, ap);
|
| |
+ + va_end(ap);
|
| |
+ +
|
| |
+ + /* Only AF_UNIX is supported, with path or abstract sockets */
|
| |
+ + if (path[0] != '/' && path[0] != '@') {
|
| |
+ + error_f("socket \"%s\" is not compatible with AF_UNIX", path);
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ +
|
| |
+ + if (path[0] == '/' && stat(path, &sb) != 0) {
|
| |
+ + error_f("socket \"%s\" stat: %s", path, strerror(errno));
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ +
|
| |
+ + memset(&addr, 0, sizeof(addr));
|
| |
+ + addr.sun_family = AF_UNIX;
|
| |
+ + if (strlcpy(addr.sun_path, path,
|
| |
+ + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
|
| |
+ + error_f("socket path \"%s\" too long", path);
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ + /* Support for abstract socket */
|
| |
+ + if (addr.sun_path[0] == '@')
|
| |
+ + addr.sun_path[0] = 0;
|
| |
+ + if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1) {
|
| |
+ + error_f("socket \"%s\": %s", path, strerror(errno));
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ + if (connect(fd, &addr, sizeof(addr)) != 0) {
|
| |
+ + error_f("socket \"%s\" connect: %s", path, strerror(errno));
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ + if (write(fd, s, strlen(s)) != (ssize_t)strlen(s)) {
|
| |
+ + error_f("socket \"%s\" write: %s", path, strerror(errno));
|
| |
+ + goto out;
|
| |
+ + }
|
| |
+ + debug_f("socket \"%s\" notified %s", path, s);
|
| |
+ + out:
|
| |
+ + if (fd != -1)
|
| |
+ + close(fd);
|
| |
+ + free(s);
|
| |
+ +}
|
| |
+ +
|
| |
+ +void
|
| |
+ +ssh_systemd_notify_ready(void)
|
| |
+ +{
|
| |
+ + ssh_systemd_notify("READY=1");
|
| |
+ +}
|
| |
+ +
|
| |
+ +void
|
| |
+ +ssh_systemd_notify_reload(void)
|
| |
+ +{
|
| |
+ + struct timespec now;
|
| |
+ +
|
| |
+ + monotime_ts(&now);
|
| |
+ + if (now.tv_sec < 0 || now.tv_nsec < 0) {
|
| |
+ + error_f("monotime returned negative value");
|
| |
+ + ssh_systemd_notify("RELOADING=1");
|
| |
+ + } else {
|
| |
+ + ssh_systemd_notify("RELOADING=1\nMONOTONIC_USEC=%llu",
|
| |
+ + ((uint64_t)now.tv_sec * 1000000ULL) +
|
| |
+ + ((uint64_t)now.tv_nsec / 1000ULL));
|
| |
+ + }
|
| |
+ +}
|
| |
+ +#endif /* SYSTEMD_NOTIFY */
|
| |
+ +
|
| |
+ +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST || SYSTEMD_NOTIFY */
|
| |
+ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
| |
+ index 3c22a854d..14064f87d 100644
|
| |
+ --- a/openbsd-compat/port-linux.h
|
| |
+ +++ b/openbsd-compat/port-linux.h
|
| |
+ @@ -30,4 +30,9 @@ void oom_adjust_restore(void);
|
| |
+ void oom_adjust_setup(void);
|
| |
+ #endif
|
| |
+
|
| |
+ +#ifdef SYSTEMD_NOTIFY
|
| |
+ +void ssh_systemd_notify_ready(void);
|
| |
+ +void ssh_systemd_notify_reload(void);
|
| |
+ +#endif
|
| |
+ +
|
| |
+ #endif /* ! _PORT_LINUX_H */
|
| |
+ diff --git a/platform.c b/platform.c
|
| |
+ index 4fe8744ee..9cf818153 100644
|
| |
+ --- a/platform.c
|
| |
+ +++ b/platform.c
|
| |
+ @@ -44,6 +44,14 @@ platform_pre_listen(void)
|
| |
+ #endif
|
| |
+ }
|
| |
+
|
| |
+ +void
|
| |
+ +platform_post_listen(void)
|
| |
+ +{
|
| |
+ +#ifdef SYSTEMD_NOTIFY
|
| |
+ + ssh_systemd_notify_ready();
|
| |
+ +#endif
|
| |
+ +}
|
| |
+ +
|
| |
+ void
|
| |
+ platform_pre_fork(void)
|
| |
+ {
|
| |
+ @@ -55,6 +63,9 @@ platform_pre_fork(void)
|
| |
+ void
|
| |
+ platform_pre_restart(void)
|
| |
+ {
|
| |
+ +#ifdef SYSTEMD_NOTIFY
|
| |
+ + ssh_systemd_notify_reload();
|
| |
+ +#endif
|
| |
+ #ifdef LINUX_OOM_ADJUST
|
| |
+ oom_adjust_restore();
|
| |
+ #endif
|
| |
+ diff --git a/platform.h b/platform.h
|
| |
+ index 7fef8c983..5dec23276 100644
|
| |
+ --- a/platform.h
|
| |
+ +++ b/platform.h
|
| |
+ @@ -21,6 +21,7 @@
|
| |
+ void platform_pre_listen(void);
|
| |
+ void platform_pre_fork(void);
|
| |
+ void platform_pre_restart(void);
|
| |
+ +void platform_post_listen(void);
|
| |
+ void platform_post_fork_parent(pid_t child_pid);
|
| |
+ void platform_post_fork_child(void);
|
| |
+ int platform_privileged_uidswap(void);
|
| |
+ diff --git a/sshd.c b/sshd.c
|
| |
+ index 9cbe92293..3c3f2dd6b 100644
|
| |
+ --- a/sshd.c
|
| |
+ +++ b/sshd.c
|
| |
+ @@ -2077,6 +2077,8 @@ main(int ac, char **av)
|
| |
+ ssh_signal(SIGTERM, sigterm_handler);
|
| |
+ ssh_signal(SIGQUIT, sigterm_handler);
|
| |
+
|
| |
+ + platform_post_listen();
|
| |
+ +
|
| |
+ /*
|
| |
+ * Write out the pid file after the sigterm handler
|
| |
+ * is setup and the listen sockets are bound
|
| |
This change removes the dependency on libsystemd, replacing it with the reference implementation from:
https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes