diff -up openssh-6.8p1/log.c.log-in-chroot openssh-6.8p1/log.c --- openssh-6.8p1/log.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/log.c 2015-03-18 12:59:29.694022313 +0100 @@ -241,6 +241,11 @@ debug3(const char *fmt,...) void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { + log_init_handler(av0, level, facility, on_stderr, 1); +} + +void +log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif @@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, Sysl exit(1); } - log_handler = NULL; - log_handler_ctx = NULL; + if (reset_handler) { + log_handler = NULL; + log_handler_ctx = NULL; + } log_on_stderr = on_stderr; if (on_stderr) diff -up openssh-6.8p1/log.h.log-in-chroot openssh-6.8p1/log.h --- openssh-6.8p1/log.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/log.h 2015-03-18 12:59:29.694022313 +0100 @@ -49,6 +49,7 @@ typedef enum { typedef void (log_handler_fn)(LogLevel, const char *, void *); void log_init(char *, LogLevel, SyslogFacility, int); +void log_init_handler(char *, LogLevel, SyslogFacility, int, int); void log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); diff -up openssh-6.8p1/monitor.c.log-in-chroot openssh-6.8p1/monitor.c --- openssh-6.8p1/monitor.c.log-in-chroot 2015-03-18 12:59:29.669022374 +0100 +++ openssh-6.8p1/monitor.c 2015-03-18 13:01:52.894671198 +0100 @@ -357,6 +357,8 @@ monitor_child_preauth(Authctxt *_authctx close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + pmonitor->m_state = "preauth"; + authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); @@ -465,6 +467,8 @@ monitor_child_postauth(struct monitor *p close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; + pmonitor->m_state = "postauth"; + monitor_set_child_handler(pmonitor->m_pid); signal(SIGHUP, &monitor_child_handler); signal(SIGTERM, &monitor_child_handler); @@ -566,7 +570,7 @@ monitor_read_log(struct monitor *pmonito if (log_level_name(level) == NULL) fatal("%s: invalid log level %u (corrupted message?)", __func__, level); - do_log2(level, "%s [preauth]", msg); + do_log2(level, "%s [%s]", msg, pmonitor->m_state); buffer_free(&logmsg); free(msg); @@ -1998,13 +2002,28 @@ monitor_init(void) (ssh_packet_comp_free_func *)mm_zfree); } + mon->m_state = ""; + return mon; } void -monitor_reinit(struct monitor *mon) +monitor_reinit(struct monitor *mon, const char *chroot_dir) { - monitor_openfds(mon, 0); + struct stat dev_log_stat; + char *dev_log_path; + int do_logfds = 0; + + if (chroot_dir != NULL) { + xasprintf(&dev_log_path, "%s/dev/log", chroot_dir); + + if (stat(dev_log_path, &dev_log_stat) != 0) { + debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir); + do_logfds = 1; + } + free(dev_log_path); + } + monitor_openfds(mon, do_logfds); } #ifdef GSSAPI diff -up openssh-6.8p1/monitor.h.log-in-chroot openssh-6.8p1/monitor.h --- openssh-6.8p1/monitor.h.log-in-chroot 2015-03-18 12:59:29.695022310 +0100 +++ openssh-6.8p1/monitor.h 2015-03-18 13:02:56.926514197 +0100 @@ -83,10 +83,11 @@ struct monitor { struct mm_master *m_zlib; struct kex **m_pkex; pid_t m_pid; + char *m_state; }; struct monitor *monitor_init(void); -void monitor_reinit(struct monitor *); +void monitor_reinit(struct monitor *, const char *); void monitor_sync(struct monitor *); struct Authctxt; diff -up openssh-6.8p1/session.c.log-in-chroot openssh-6.8p1/session.c --- openssh-6.8p1/session.c.log-in-chroot 2015-03-18 12:59:29.675022359 +0100 +++ openssh-6.8p1/session.c 2015-03-18 12:59:29.696022308 +0100 @@ -161,6 +161,7 @@ login_cap_t *lc; static int is_child = 0; static int in_chroot = 0; +static int have_dev_log = 1; /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; @@ -506,8 +508,8 @@ do_exec_no_pty(Session *s, const char *c is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ - log_init(__progname, options.log_level, - options.log_facility, log_stderr); + log_init_handler(__progname, options.log_level, + options.log_facility, log_stderr, have_dev_log); /* * Create a new session and process group since the 4.4BSD @@ -675,8 +677,8 @@ do_exec_pty(Session *s, const char *comm close(ptymaster); /* Child. Reinitialize the log because the pid has changed. */ - log_init(__progname, options.log_level, - options.log_facility, log_stderr); + log_init_handler(__progname, options.log_level, + options.log_facility, log_stderr, have_dev_log); /* Close the master side of the pseudo tty. */ close(ptyfd); @@ -780,6 +782,7 @@ do_exec(Session *s, const char *command) int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; + struct stat dev_log_stat; if (options.adm_forced_command) { original_command = command; @@ -837,6 +840,10 @@ do_exec(Session *s, const char *command) tty += 5; } + if (lstat("/dev/log", &dev_log_stat) != 0) { + have_dev_log = 0; + } + verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", @@ -1678,14 +1685,6 @@ child_close_fds(void) * descriptors left by system functions. They will be closed later. */ endpwent(); - - /* - * Close any extra open file descriptors so that we don't have them - * hanging around in clients. Note that we want to do this after - * initgroups, because at least on Solaris 2.3 it leaves file - * descriptors open. - */ - closefrom(STDERR_FILENO + 1); } /* @@ -1831,8 +1830,6 @@ do_child(Session *s, const char *command exit(1); } - closefrom(STDERR_FILENO + 1); - if (!options.use_login) do_rc_files(s, shell); @@ -1856,9 +1853,17 @@ do_child(Session *s, const char *command argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; - exit(sftp_server_main(i, argv, s->pw)); + exit(sftp_server_main(i, argv, s->pw, have_dev_log)); } + /* + * Close any extra open file descriptors so that we don't have them + * hanging around in clients. Note that we want to do this after + * initgroups, because at least on Solaris 2.3 it leaves file + * descriptors open. + */ + closefrom(STDERR_FILENO + 1); + fflush(NULL); if (options.use_login) { diff -up openssh-6.8p1/sftp-server-main.c.log-in-chroot openssh-6.8p1/sftp-server-main.c --- openssh-6.8p1/sftp-server-main.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/sftp-server-main.c 2015-03-18 12:59:29.696022308 +0100 @@ -47,5 +47,5 @@ main(int argc, char **argv) return 1; } - return (sftp_server_main(argc, argv, user_pw)); + return (sftp_server_main(argc, argv, user_pw, 0)); } diff -up openssh-6.8p1/sftp-server.c.log-in-chroot openssh-6.8p1/sftp-server.c --- openssh-6.8p1/sftp-server.c.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/sftp-server.c 2015-03-18 13:03:52.510377911 +0100 @@ -1502,7 +1502,7 @@ sftp_server_usage(void) } int -sftp_server_main(int argc, char **argv, struct passwd *user_pw) +sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) { fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; @@ -1515,7 +1515,7 @@ sftp_server_main(int argc, char **argv, ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); - log_init(__progname, log_level, log_facility, log_stderr); + log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); pw = pwcopy(user_pw); @@ -1586,7 +1586,7 @@ sftp_server_main(int argc, char **argv, } } - log_init(__progname, log_level, log_facility, log_stderr); + log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* diff -up openssh-6.8p1/sftp.h.log-in-chroot openssh-6.8p1/sftp.h --- openssh-6.8p1/sftp.h.log-in-chroot 2015-03-17 06:49:20.000000000 +0100 +++ openssh-6.8p1/sftp.h 2015-03-18 12:59:29.696022308 +0100 @@ -97,5 +97,5 @@ struct passwd; -int sftp_server_main(int, char **, struct passwd *); +int sftp_server_main(int, char **, struct passwd *, int); void sftp_server_cleanup_exit(int) __attribute__((noreturn)); diff -up openssh-6.8p1/sshd.c.log-in-chroot openssh-6.8p1/sshd.c --- openssh-6.8p1/sshd.c.log-in-chroot 2015-03-18 12:59:29.691022320 +0100 +++ openssh-6.8p1/sshd.c 2015-03-18 12:59:29.697022305 +0100 @@ -744,7 +744,7 @@ privsep_postauth(Authctxt *authctxt) } /* New socket pair */ - monitor_reinit(pmonitor); + monitor_reinit(pmonitor, options.chroot_directory); pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) @@ -762,6 +762,11 @@ privsep_postauth(Authctxt *authctxt) close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; + close(pmonitor->m_log_recvfd); + pmonitor->m_log_recvfd = -1; + + if (pmonitor->m_log_sendfd != -1) + set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ demote_sensitive_data();