diff --git a/sshd.c b/sshd.c index 865331b461e..6306b7b3cbe 100644 --- a/sshd.c +++ b/sshd.c @@ -158,6 +158,12 @@ int debug_flag = 0; */ static int test_flag = 0; +/* + * The file descriptor where a newline should be written after listening on + * the socket. + */ +static int notify_fd = 0; + /* Flag indicating that the daemon is being started from inetd. */ static int inetd_flag = 0; @@ -899,6 +905,7 @@ usage(void) "usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n" " [-E log_file] [-f config_file] [-g login_grace_time]\n" " [-h host_key_file] [-o option] [-p port] [-u len]\n" +" [-3 newline-fd]\n" ); exit(1); } @@ -1591,7 +1598,7 @@ main(int ac, char **av) /* Parse command-line arguments. */ while ((opt = getopt(ac, av, - "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { + "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV3:")) != -1) { switch (opt) { case '4': options.address_family = AF_INET; @@ -1699,6 +1706,15 @@ main(int ac, char **av) fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSH_OPENSSL_VERSION); exit(0); + case '3': + /* implies process will be supervised */ + no_daemon_flag = 1; + notify_fd = (int)strtonum(optarg, 3, INT_MAX, NULL); + if (notify_fd == 0) { + fprintf(stderr, "Invalid notification file-descriptor.\n"); + exit(1); + } + break; default: usage(); break; @@ -1708,9 +1724,12 @@ main(int ac, char **av) rexec_flag = 0; if (!test_flag && !do_dump_cfg && rexec_flag && !path_absolute(av[0])) fatal("sshd re-exec requires execution with an absolute path"); - if (rexeced_flag) + if (rexeced_flag) { closefrom(REEXEC_MIN_FREE_FD); - else + /* avoid writing newline */ + notify_fd = 0; + } else if (notify_fd == 0) + /* must inherit fd from supervisor parent */ closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); seed_rng(); @@ -2077,6 +2096,10 @@ main(int ac, char **av) ssh_signal(SIGTERM, sigterm_handler); ssh_signal(SIGQUIT, sigterm_handler); + if (notify_fd >= 3) { + write(notify_fd, "\n", 1); + close(notify_fd); + } platform_post_listen(); /*