.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 2, 2020
+.Dd October 30, 2020
.Dt DHCPCD 8
.Os
.Sh NAME
.Sh AUTHORS
.An Roy Marples Aq Mt roy@marples.name
.Sh BUGS
-If
-.Nm
-is running in a
-.Xr chroot 2
-then re-opening the
-.Fl Fl logfile
-from SIGUSR2 may not work.
-.Pp
Please report them to
.Lk http://roy.marples.name/projects/dhcpcd
return;
case SIGUSR2:
loginfox(sigmsg, "SIGUSR2", "reopening log");
- /* XXX This may not work that well in a chroot */
- logclose();
- if (logopen(ctx->logfile) == -1)
- logerr(__func__);
+ if (IN_PRIVSEP(ctx)) {
+ if (ps_root_logreopen(ctx) == -1)
+ logerr("ps_root_logreopen");
+ } else {
+ logclose();
+ if (logopen(ctx->logfile) == -1)
+ logerr("logopen");
+ }
return;
case SIGCHLD:
while (waitpid(-1, NULL, WNOHANG) > 0)
ctx.dhcp6_wfd = -1;
#endif
#ifdef PRIVSEP
- ctx.ps_root_fd = ctx.ps_syslog_fd = ctx.ps_data_fd = -1;
+ ctx.ps_root_fd = ctx.ps_log_fd = ctx.ps_data_fd = -1;
ctx.ps_inet_fd = ctx.ps_control_fd = -1;
TAILQ_INIT(&ctx.ps_processes);
#endif
/* We have now forked, setsid, forked once more.
* From this point on, we are the controlling daemon. */
ctx.options |= DHCPCD_STARTED;
+ logdebugx("spawned master process on PID %d", getpid());
if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
logerr("%s: pidfile_lock %d", __func__, pid);
#ifdef PRIVSEP
struct passwd *ps_user; /* struct passwd for privsep user */
pid_t ps_root_pid;
int ps_root_fd; /* Privileged Actioneer commands */
- int ps_syslog_fd; /* syslog(3) wrapper */
+ int ps_log_fd; /* chroot logging */
int ps_data_fd; /* Data from root spawned processes */
struct eloop *ps_eloop; /* eloop for polling root data */
struct ps_process_head ps_processes; /* List of spawned processes */
#endif
/* syslog protocol is 1k message max, RFC 3164 section 4.1 */
-#define LOGERR_SYSLOGBUF 1024 + sizeof(int)
+#define LOGERR_SYSLOGBUF 1024 + sizeof(int) + sizeof(pid_t)
#define UNUSED(a) (void)(a)
struct logctx {
char log_buf[BUFSIZ];
unsigned int log_opts;
- int log_syslogfd;
+ int log_fd;
+ pid_t log_pid;
#ifndef SMALL
FILE *log_file;
#ifdef LOGERR_TAG
static struct logctx _logctx = {
/* syslog style, but without the hostname or tag. */
.log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
- .log_syslogfd = -1,
+ .log_fd = -1,
+ .log_pid = 0,
};
#if defined(__linux__)
log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
(stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
if (log_pid) {
- if ((e = fprintf(stream, "[%d]", getpid())) == -1)
+ pid_t pid;
+
+ if (ctx->log_pid == 0)
+ pid = getpid();
+ else
+ pid = ctx->log_pid;
+ if ((e = fprintf(stream, "[%d]", pid)) == -1)
return -1;
len += e;
}
struct logctx *ctx = &_logctx;
int len = 0;
- if (ctx->log_syslogfd != -1) {
+ if (ctx->log_fd != -1) {
char buf[LOGERR_SYSLOGBUF];
+ pid_t pid;
memcpy(buf, &pri, sizeof(pri));
- len = vsnprintf(buf + sizeof(pri), sizeof(buf) - sizeof(pri),
+ pid = getpid();
+ memcpy(buf + sizeof(pri), &pid, sizeof(pid));
+ len = vsnprintf(buf + sizeof(pri) + sizeof(pid),
+ sizeof(buf) - sizeof(pri) - sizeof(pid),
fmt, args);
if (len != -1)
- len = (int)write(ctx->log_syslogfd, buf,
- ((size_t)++len) + sizeof(pri));
+ len = (int)write(ctx->log_fd, buf,
+ ((size_t)++len) + sizeof(pri) + sizeof(pid));
return len;
}
}
int
-loggetsyslogfd(void)
+loggetfd(void)
{
struct logctx *ctx = &_logctx;
- return ctx->log_syslogfd;
+ return ctx->log_fd;
}
void
-logsetsyslogfd(int fd)
+logsetfd(int fd)
{
struct logctx *ctx = &_logctx;
- ctx->log_syslogfd = fd;
+ ctx->log_fd = fd;
+#ifndef SMALL
+ if (fd != -1 && ctx->log_file != NULL) {
+ fclose(ctx->log_file);
+ ctx->log_file = NULL;
+ }
+#endif
}
int
-loghandlesyslogfd(int fd)
+logreadfd(int fd)
{
+ struct logctx *ctx = &_logctx;
char buf[LOGERR_SYSLOGBUF];
int len, pri;
if (len == -1)
return -1;
- /* Ensure we have pri and a terminator */
- if (len < (int)sizeof(pri) + 1 || buf[len - 1] != '\0') {
+ /* Ensure we have pri, pid and a terminator */
+ if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) ||
+ buf[len - 1] != '\0')
+ {
errno = EINVAL;
return -1;
}
memcpy(&pri, buf, sizeof(pri));
- logmessage(pri, "%s", buf + sizeof(pri));
+ memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid));
+ logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid));
+ ctx->log_pid = 0;
return len;
}
#define logerr(...) log_err(__VA_ARGS__)
#define logerrx(...) log_errx(__VA_ARGS__)
-/* For syslog in a chroot */
-int loggetsyslogfd(void);
-void logsetsyslogfd(int);
-int loghandlesyslogfd(int);
+/* For logging in a chroot */
+int loggetfd(void);
+void logsetfd(int);
+int logreadfd(int);
unsigned int loggetopts(void);
void logsetopts(unsigned int);
rlen = sizeof(mtime);
}
break;
+ case PS_LOGREOPEN:
+ logclose();
+ err = logopen(ctx->logfile);
+ break;
#ifdef AUTH
case PS_AUTH_MONORDM:
err = ps_root_monordm(data, len);
}
static void
-ps_root_syslog(void *arg)
+ps_root_log(void *arg)
{
struct dhcpcd_ctx *ctx = arg;
- if (loghandlesyslogfd(ctx->ps_syslog_fd) == -1)
+ if (logreadfd(ctx->ps_log_fd) == -1)
logerr(__func__);
}
ps_root_startcb, ps_root_signalcb, 0);
if (pid == 0) {
- ctx->ps_syslog_fd = logfd[1];
- if (eloop_event_add(ctx->eloop, ctx->ps_syslog_fd,
- ps_root_syslog, ctx) == -1)
+ ctx->ps_log_fd = logfd[1];
+ if (eloop_event_add(ctx->eloop, ctx->ps_log_fd,
+ ps_root_log, ctx) == -1)
return -1;
close(logfd[0]);
ctx->ps_data_fd = datafd[1];
} else if (pid == -1)
return -1;
- logsetsyslogfd(logfd[0]);
+ logsetfd(logfd[0]);
close(logfd[1]);
ctx->ps_data_fd = datafd[0];
return ps_root_readerror(ctx, time, sizeof(*time));
}
+ssize_t
+ps_root_logreopen(struct dhcpcd_ctx *ctx)
+{
+
+ if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_LOGREOPEN, 0, NULL, 0) == -1)
+ return -1;
+ return ps_root_readerror(ctx, NULL, 0);
+}
+
#ifdef PRIVSEP_GETIFADDRS
int
ps_root_getifaddrs(struct dhcpcd_ctx *ctx, struct ifaddrs **ifahead)
ssize_t ps_root_readfile(struct dhcpcd_ctx *, const char *, void *, size_t);
ssize_t ps_root_writefile(struct dhcpcd_ctx *, const char *, mode_t,
const void *, size_t);
+ssize_t ps_root_logreopen(struct dhcpcd_ctx *);
ssize_t ps_root_script(struct dhcpcd_ctx *, const void *, size_t);
int ps_root_getauthrdm(struct dhcpcd_ctx *, uint64_t *);
#ifdef PRIVSEP_GETIFADDRS
#define PS_AUTH_MONORDM 0x0017
#define PS_CTL 0x0018
#define PS_CTL_EOF 0x0019
+#define PS_LOGREOPEN 0x0020
/* BSD Commands */
#define PS_IOCTLLINK 0x0101