Sync
This commit is contained in:
parent
d37f9bca9d
commit
b652e16f07
|
@ -1034,7 +1034,7 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
|
|||
auth = NULL; /* appease GCC */
|
||||
auth_len = 0;
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
ssize_t alen = dhcp_auth_encode(&ifo->auth,
|
||||
ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
|
||||
state->auth.token,
|
||||
NULL, 0, 4, type, NULL, 0);
|
||||
if (alen != -1 && alen > UINT8_MAX) {
|
||||
|
@ -1129,7 +1129,7 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
|
|||
|
||||
#ifdef AUTH
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
|
||||
dhcp_auth_encode(&ifo->auth, state->auth.token,
|
||||
dhcp_auth_encode(ifp->ctx, &ifo->auth, state->auth.token,
|
||||
(uint8_t *)bootp, len, 4, type, auth, auth_len);
|
||||
#endif
|
||||
|
||||
|
@ -2747,6 +2747,18 @@ dhcp_drop(struct interface *ifp, const char *reason)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef AUTH
|
||||
else if (state->auth.reconf != NULL) {
|
||||
/*
|
||||
* Drop the lease as the token may only be present
|
||||
* in the initial reply message and not subsequent
|
||||
* renewals.
|
||||
* If dhcpcd is restarted, the token is lost.
|
||||
* XXX persist this in another file?
|
||||
*/
|
||||
dhcp_unlink(ifp->ctx, state->leasefile);
|
||||
}
|
||||
#endif
|
||||
|
||||
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
|
||||
#ifdef AUTH
|
||||
|
@ -4176,3 +4188,24 @@ dhcp_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
|
|||
|
||||
return ia;
|
||||
}
|
||||
|
||||
#ifndef SMALL
|
||||
int
|
||||
dhcp_dump(struct interface *ifp)
|
||||
{
|
||||
struct dhcp_state *state;
|
||||
|
||||
ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
|
||||
if (state == NULL) {
|
||||
logerr(__func__);
|
||||
return -1;
|
||||
}
|
||||
state->new_len = read_lease(ifp, &state->new);
|
||||
if (state->new == NULL) {
|
||||
logerr("read_lease");
|
||||
return -1;
|
||||
}
|
||||
state->reason = "DUMP";
|
||||
return script_runreason(ifp, state->reason);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -881,7 +881,7 @@ dhcp6_makemessage(struct interface *ifp)
|
|||
#ifdef AUTH
|
||||
auth_len = 0;
|
||||
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
ssize_t alen = dhcp_auth_encode(&ifo->auth,
|
||||
ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
|
||||
state->auth.token, NULL, 0, 6, type, NULL, 0);
|
||||
if (alen != -1 && alen > UINT16_MAX) {
|
||||
errno = ERANGE;
|
||||
|
@ -1196,9 +1196,9 @@ dhcp6_update_auth(struct interface *ifp, struct dhcp6_message *m, size_t len)
|
|||
return -1;
|
||||
|
||||
state = D6_STATE(ifp);
|
||||
return dhcp_auth_encode(&ifp->options->auth, state->auth.token,
|
||||
(uint8_t *)state->send, state->send_len,
|
||||
6, state->send->type, opt, opt_len);
|
||||
return dhcp_auth_encode(ifp->ctx, &ifp->options->auth,
|
||||
state->auth.token, (uint8_t *)state->send, state->send_len, 6,
|
||||
state->send->type, opt, opt_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1483,7 +1483,7 @@ void dhcp6_renew(struct interface *ifp)
|
|||
dhcp6_startrenew(ifp);
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
dhcp6_dadcompleted(const struct interface *ifp)
|
||||
{
|
||||
const struct dhcp6_state *state;
|
||||
|
@ -1493,9 +1493,9 @@ dhcp6_dadcompleted(const struct interface *ifp)
|
|||
TAILQ_FOREACH(ap, &state->addrs, next) {
|
||||
if (ap->flags & IPV6_AF_ADDED &&
|
||||
!(ap->flags & IPV6_AF_DADCOMPLETED))
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3319,7 +3319,7 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
|
|||
loginfox("%s: accepted reconfigure key", ifp->name);
|
||||
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
|
||||
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
|
||||
logerr("%s: no authentication from %s",
|
||||
logerrx("%s: no authentication from %s",
|
||||
ifp->name, sfrom);
|
||||
return;
|
||||
}
|
||||
|
@ -3595,16 +3595,13 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
|
|||
}
|
||||
|
||||
if (r->type == DHCP6_RECONFIGURE) {
|
||||
logdebugx("%s: RECONFIGURE6 recv from %s,"
|
||||
" sending to all interfaces",
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) {
|
||||
logerrx("%s: RECONFIGURE6 recv from %s, not LL",
|
||||
ifp->name, sfrom);
|
||||
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
|
||||
state = D6_CSTATE(ifp);
|
||||
if (state != NULL && state->send != NULL)
|
||||
dhcp6_recvif(ifp, sfrom, r, len);
|
||||
}
|
||||
return;
|
||||
}
|
||||
goto recvif;
|
||||
}
|
||||
|
||||
state = D6_CSTATE(ifp);
|
||||
if (state == NULL ||
|
||||
|
@ -3679,6 +3676,7 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
|
|||
len = (size_t)tlen;
|
||||
#endif
|
||||
|
||||
recvif:
|
||||
dhcp6_recvif(ifp, sfrom, r, len);
|
||||
}
|
||||
|
||||
|
@ -4041,6 +4039,19 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
|
|||
}
|
||||
dhcp_unlink(ifp->ctx, state->leasefile);
|
||||
}
|
||||
#ifdef AUTH
|
||||
else if (state->auth.reconf != NULL) {
|
||||
/*
|
||||
* Drop the lease as the token may only be present
|
||||
* in the initial reply message and not subsequent
|
||||
* renewals.
|
||||
* If dhcpcd is restarted, the token is lost.
|
||||
* XXX persist this in another file?
|
||||
*/
|
||||
dhcp_unlink(ifp->ctx, state->leasefile);
|
||||
}
|
||||
#endif
|
||||
|
||||
dhcp6_freedrop_addrs(ifp, drop, NULL);
|
||||
free(state->old);
|
||||
state->old = state->new;
|
||||
|
@ -4293,3 +4304,24 @@ delegated:
|
|||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SMALL
|
||||
int
|
||||
dhcp6_dump(struct interface *ifp)
|
||||
{
|
||||
struct dhcp6_state *state;
|
||||
|
||||
ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
|
||||
if (state == NULL) {
|
||||
logerr(__func__);
|
||||
return -1;
|
||||
}
|
||||
TAILQ_INIT(&state->addrs);
|
||||
if (dhcp6_readlease(ifp, 0) == -1) {
|
||||
logerr("dhcp6_readlease");
|
||||
return -1;
|
||||
}
|
||||
state->reason = "DUMP6";
|
||||
return script_runreason(ifp, state->reason);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd May 21, 2020
|
||||
.Dd May 31, 2020
|
||||
.Dt DHCPCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -72,7 +72,7 @@
|
|||
.Op interface
|
||||
.Nm
|
||||
.Fl U , Fl Fl dumplease
|
||||
.Ar interface
|
||||
.Op Ar interface
|
||||
.Nm
|
||||
.Fl Fl version
|
||||
.Nm
|
||||
|
@ -685,15 +685,20 @@ option is not sent in TEST mode so that the server does not lease an address.
|
|||
To test INFORM the interface needs to be configured with the desired address
|
||||
before starting
|
||||
.Nm .
|
||||
.It Fl U , Fl Fl dumplease Ar interface
|
||||
.It Fl U , Fl Fl dumplease Op Ar interface
|
||||
Dumps the current lease for the
|
||||
.Ar interface
|
||||
to stdout.
|
||||
If no
|
||||
.Ar interface
|
||||
is given then all interfaces are dumped.
|
||||
Use the
|
||||
.Fl 4
|
||||
or
|
||||
.Fl 6
|
||||
flags to specify an address family.
|
||||
If a lease is piped in via standard input then that is dumped.
|
||||
In this case, specifying an address family is mandatory.
|
||||
.It Fl V , Fl Fl variables
|
||||
Display a list of option codes, the associated variable and encoding for use in
|
||||
.Xr dhcpcd-run-hooks 8 .
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
const char dhcpcd_copyright[] = "Copyright (c) 2006-2020 Roy Marples";
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -86,6 +87,7 @@ const int dhcpcd_signals[] = {
|
|||
SIGHUP,
|
||||
SIGUSR1,
|
||||
SIGUSR2,
|
||||
SIGCHLD,
|
||||
};
|
||||
const size_t dhcpcd_signals_len = __arraycount(dhcpcd_signals);
|
||||
|
||||
|
@ -1340,6 +1342,9 @@ stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts)
|
|||
struct interface *ifp;
|
||||
|
||||
ctx->options |= DHCPCD_EXITING;
|
||||
if (ctx->ifaces == NULL)
|
||||
return;
|
||||
|
||||
/* Drop the last interface first */
|
||||
TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) {
|
||||
if (!ifp->active)
|
||||
|
@ -1395,7 +1400,7 @@ dhcpcd_signal_cb(int sig, void *arg)
|
|||
unsigned long long opts;
|
||||
int exit_code;
|
||||
|
||||
if (ctx->options & DHCPCD_FORKED) {
|
||||
if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) {
|
||||
pid_t pid = pidfile_read(ctx->pidfile);
|
||||
if (pid == -1) {
|
||||
if (errno != ENOENT)
|
||||
|
@ -1441,6 +1446,10 @@ dhcpcd_signal_cb(int sig, void *arg)
|
|||
if (logopen(ctx->logfile) == -1)
|
||||
logerr(__func__);
|
||||
return;
|
||||
case SIGCHLD:
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0)
|
||||
;
|
||||
return;
|
||||
default:
|
||||
logerrx("received signal %d but don't know what to do with it",
|
||||
sig);
|
||||
|
@ -1663,20 +1672,13 @@ dumperr:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *dumpskip[] = {
|
||||
"PATH=",
|
||||
"pid=",
|
||||
"chroot=",
|
||||
};
|
||||
|
||||
static int
|
||||
dhcpcd_readdump(struct dhcpcd_ctx *ctx)
|
||||
{
|
||||
int error = 0;
|
||||
size_t nifaces, buflen = 0, dlen, i;
|
||||
size_t nifaces, buflen = 0, dlen;
|
||||
ssize_t len;
|
||||
char *buf = NULL, *dp, *de;
|
||||
const char *skip;
|
||||
char *buf = NULL;
|
||||
|
||||
again1:
|
||||
len = read(ctx->control_fd, &nifaces, sizeof(nifaces));
|
||||
|
@ -1723,26 +1725,7 @@ again3:
|
|||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
dp = buf;
|
||||
de = dp + dlen;
|
||||
if (*(de - 1) != '\0') {
|
||||
errno = EINVAL;
|
||||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
while (dp < de) {
|
||||
for (i = 0; i < __arraycount(dumpskip); i++) {
|
||||
skip = dumpskip[i];
|
||||
if (strncmp(dp, skip, strlen(skip)) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == __arraycount(dumpskip)) {
|
||||
if (strncmp(dp, "new_", 4) == 0)
|
||||
dp += 4;
|
||||
printf("%s\n", dp);
|
||||
}
|
||||
dp += strlen(dp) + 1;
|
||||
}
|
||||
script_dump(buf, dlen);
|
||||
fflush(stdout);
|
||||
if (nifaces != 1)
|
||||
putchar('\n');
|
||||
|
@ -2061,13 +2044,9 @@ printpidfile:
|
|||
signal(dhcpcd_signals_ignore[si], SIG_IGN);
|
||||
|
||||
/* Save signal mask, block and redirect signals to our handler */
|
||||
if (eloop_signal_set_cb(ctx.eloop,
|
||||
eloop_signal_set_cb(ctx.eloop,
|
||||
dhcpcd_signals, dhcpcd_signals_len,
|
||||
dhcpcd_signal_cb, &ctx) == -1)
|
||||
{
|
||||
logerr("%s: eloop_signal_set_cb", __func__);
|
||||
goto exit_failure;
|
||||
}
|
||||
dhcpcd_signal_cb, &ctx);
|
||||
if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
|
||||
logerr("%s: eloop_signal_mask", __func__);
|
||||
goto exit_failure;
|
||||
|
@ -2107,6 +2086,45 @@ printpidfile:
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef SMALL
|
||||
if (ctx.options & DHCPCD_DUMPLEASE &&
|
||||
ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 &&
|
||||
i > 0)
|
||||
{
|
||||
ifp = calloc(1, sizeof(*ifp));
|
||||
if (ifp == NULL) {
|
||||
logerr(__func__);
|
||||
goto exit_failure;
|
||||
}
|
||||
ifp->ctx = &ctx;
|
||||
ifp->options = ifo;
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
#ifdef INET
|
||||
if (dhcp_dump(ifp) == -1)
|
||||
goto exit_failure;
|
||||
break;
|
||||
#else
|
||||
logerrx("No DHCP support");
|
||||
goto exit_failure;
|
||||
#endif
|
||||
case AF_INET6:
|
||||
#ifdef DHCP6
|
||||
if (dhcp6_dump(ifp) == -1)
|
||||
goto exit_failure;
|
||||
break;
|
||||
#else
|
||||
logerrx("No DHCP6 support");
|
||||
goto exit_failure;
|
||||
#endif
|
||||
default:
|
||||
logerrx("Family not specified. Please use -4 or -6.");
|
||||
goto exit_failure;
|
||||
}
|
||||
goto exit_success;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test against siga instead of sig to avoid gcc
|
||||
* warning about a bogus potential signed overflow.
|
||||
* The end result will be the same. */
|
||||
|
@ -2194,7 +2212,6 @@ printpidfile:
|
|||
logerr("fork");
|
||||
goto exit_failure;
|
||||
case 0:
|
||||
eloop_requeue(ctx.eloop);
|
||||
break;
|
||||
default:
|
||||
ctx.options |= DHCPCD_FORKED; /* A lie */
|
||||
|
@ -2203,7 +2220,6 @@ printpidfile:
|
|||
}
|
||||
break;
|
||||
default:
|
||||
waitpid(pid, &i, 0);
|
||||
ctx.options |= DHCPCD_FORKED; /* A lie */
|
||||
ctx.fork_fd = sigpipe[0];
|
||||
close(sigpipe[1]);
|
||||
|
|
|
@ -100,10 +100,12 @@
|
|||
#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
|
||||
#endif
|
||||
|
||||
/* Ignore these interface names which look like ethernet but are virtual. */
|
||||
/* Ignore these interface names which look like ethernet but are virtual or
|
||||
* just won't work without explicit configuration. */
|
||||
static const char * const ifnames_ignore[] = {
|
||||
"bridge",
|
||||
"fwe", /* Firewire */
|
||||
"fwip", /* Firewire */
|
||||
"tap",
|
||||
"xvif", /* XEN DOM0 -> guest interface */
|
||||
NULL
|
||||
|
|
|
@ -131,6 +131,41 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ps_setbuf0(int fd, int ctl, int minlen)
|
||||
{
|
||||
int len;
|
||||
socklen_t slen;
|
||||
|
||||
slen = sizeof(len);
|
||||
if (getsockopt(fd, SOL_SOCKET, ctl, &len, &slen) == -1)
|
||||
return -1;
|
||||
|
||||
#ifdef __linux__
|
||||
len /= 2;
|
||||
#endif
|
||||
if (len >= minlen)
|
||||
return 0;
|
||||
|
||||
return setsockopt(fd, SOL_SOCKET, ctl, &minlen, sizeof(minlen));
|
||||
}
|
||||
|
||||
static int
|
||||
ps_setbuf(int fd)
|
||||
{
|
||||
/* Ensure we can receive a fully sized privsep message.
|
||||
* Double the send buffer. */
|
||||
int minlen = (int)sizeof(struct ps_msg);
|
||||
|
||||
if (ps_setbuf0(fd, SO_RCVBUF, minlen) == -1 ||
|
||||
ps_setbuf0(fd, SO_SNDBUF, minlen * 2) == -1)
|
||||
{
|
||||
logerr(__func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t
|
||||
ps_dostart(struct dhcpcd_ctx *ctx,
|
||||
pid_t *priv_pid, int *priv_fd,
|
||||
|
@ -160,11 +195,13 @@ ps_dostart(struct dhcpcd_ctx *ctx,
|
|||
case 0:
|
||||
*priv_fd = fd[1];
|
||||
close(fd[0]);
|
||||
ps_setbuf(*priv_fd);
|
||||
break;
|
||||
default:
|
||||
*priv_pid = pid;
|
||||
*priv_fd = fd[0];
|
||||
close(fd[1]);
|
||||
ps_setbuf(*priv_fd);
|
||||
if (recv_unpriv_msg == NULL)
|
||||
;
|
||||
#ifdef HAVE_CAPSICUM
|
||||
|
@ -206,12 +243,8 @@ ps_dostart(struct dhcpcd_ctx *ctx,
|
|||
ctx->ps_inet_fd = -1;
|
||||
}
|
||||
|
||||
if (eloop_signal_set_cb(ctx->eloop,
|
||||
dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx) == -1)
|
||||
{
|
||||
logerr("%s: eloop_signal_set_cb", __func__);
|
||||
goto errexit;
|
||||
}
|
||||
eloop_signal_set_cb(ctx->eloop,
|
||||
dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx);
|
||||
|
||||
/* ctx->sigset aready has the initial sigmask set in main() */
|
||||
if (eloop_signal_mask(ctx->eloop, NULL) == -1) {
|
||||
|
@ -251,67 +284,35 @@ errexit:
|
|||
(void)ps_sendcmd(ctx, *priv_fd, PS_STOP, 0, NULL, 0);
|
||||
shutdown(*priv_fd, SHUT_RDWR);
|
||||
*priv_fd = -1;
|
||||
eloop_exit(ctx->eloop, EXIT_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd)
|
||||
{
|
||||
int status;
|
||||
int err = 0;
|
||||
|
||||
#ifdef PRIVSEP_DEBUG
|
||||
logdebugx("%s: pid %d fd %d", __func__, *pid, *fd);
|
||||
#endif
|
||||
if (*pid == 0)
|
||||
return 0;
|
||||
|
||||
if (*fd != -1) {
|
||||
eloop_event_delete(ctx->eloop, *fd);
|
||||
if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1 &&
|
||||
errno != ECONNRESET)
|
||||
logerr(__func__);
|
||||
if (shutdown(*fd, SHUT_RDWR) == -1 && errno != ENOTCONN)
|
||||
if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1 ||
|
||||
shutdown(*fd, SHUT_RDWR) == -1)
|
||||
{
|
||||
logerr(__func__);
|
||||
err = -1;
|
||||
}
|
||||
close(*fd);
|
||||
*fd = -1;
|
||||
/* We won't have permission for all processes .... */
|
||||
#if 0
|
||||
if (kill(*pid, SIGTERM) == -1)
|
||||
logerr(__func__);
|
||||
#endif
|
||||
status = 0;
|
||||
|
||||
#ifdef HAVE_CAPSICUM
|
||||
unsigned int cap_mode = 0;
|
||||
int cap_err = cap_getmode(&cap_mode);
|
||||
|
||||
if (cap_err == -1) {
|
||||
if (errno != ENOSYS)
|
||||
logerr("%s: cap_getmode", __func__);
|
||||
} else if (cap_mode != 0)
|
||||
goto nowait;
|
||||
#endif
|
||||
|
||||
/* Wait for the process to finish */
|
||||
while (waitpid(*pid, &status, 0) == -1) {
|
||||
if (errno != EINTR) {
|
||||
logerr("%s: waitpid", __func__);
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
#ifdef PRIVSEP_DEBUG
|
||||
else
|
||||
logerr("%s: waitpid ", __func__);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_CAPSICUM
|
||||
nowait:
|
||||
#endif
|
||||
|
||||
/* Don't wait for the process as it may not respond to the shutdown
|
||||
* request. We'll reap the process on receipt of SIGCHLD. */
|
||||
*pid = 0;
|
||||
|
||||
#ifdef PRIVSEP_DEBUG
|
||||
logdebugx("%s: status %d", __func__, status);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -507,7 +508,8 @@ ps_sendpsmmsg(struct dhcpcd_ctx *ctx, int fd,
|
|||
#ifdef PRIVSEP_DEBUG
|
||||
logdebugx("%s: %zd", __func__, len);
|
||||
#endif
|
||||
if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED)
|
||||
if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
|
||||
!(ctx->options & DHCPCD_PRIVSEPROOT))
|
||||
eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
return len;
|
||||
}
|
||||
|
@ -650,8 +652,12 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, uint16_t cmd, int wfd)
|
|||
#ifdef PRIVSEP_DEBUG
|
||||
logdebugx("%s: recv fd %d, %zd bytes", __func__, rfd, len);
|
||||
#endif
|
||||
if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED) {
|
||||
eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
|
||||
if (len == -1 || len == 0) {
|
||||
if (ctx->options & DHCPCD_FORKED &&
|
||||
!(ctx->options & DHCPCD_PRIVSEPROOT))
|
||||
eloop_exit(ctx->eloop,
|
||||
len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -660,7 +666,8 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int rfd, uint16_t cmd, int wfd)
|
|||
#ifdef PRIVSEP_DEBUG
|
||||
logdebugx("%s: send fd %d, %zu bytes", __func__, wfd, len);
|
||||
#endif
|
||||
if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED)
|
||||
if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
|
||||
!(ctx->options & DHCPCD_PRIVSEPROOT))
|
||||
eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
return len;
|
||||
}
|
||||
|
@ -682,8 +689,6 @@ ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd,
|
|||
logdebugx("%s: %zd", __func__, len);
|
||||
#endif
|
||||
|
||||
if (len == -1 && (errno == ECONNRESET || errno == EBADF))
|
||||
len = 0;
|
||||
if (len == -1 || len == 0)
|
||||
stop = true;
|
||||
else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* stSPDX-License-Identifier: BSD-2-Clause */
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
* Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
|
||||
|
@ -193,6 +193,8 @@ script_buftoenv(struct dhcpcd_ctx *ctx, char *buf, size_t len)
|
|||
}
|
||||
}
|
||||
assert(*(bufp - 1) == '\0');
|
||||
if (nenv == 0)
|
||||
return NULL;
|
||||
|
||||
if (ctx->script_envlen < nenv) {
|
||||
env = reallocarray(ctx->script_env, nenv + 1, sizeof(*env));
|
||||
|
@ -235,6 +237,7 @@ make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp,
|
|||
#ifdef DHCP6
|
||||
const struct dhcp6_state *d6_state;
|
||||
#endif
|
||||
bool is_stdin = ifp->name[0] == '\0';
|
||||
|
||||
#ifdef HAVE_OPEN_MEMSTREAM
|
||||
if (ctx->script_fp == NULL) {
|
||||
|
@ -264,23 +267,19 @@ make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!(ifp->ctx->options & DHCPCD_DUMPLEASE)) {
|
||||
/* Needed for scripts */
|
||||
path = getenv("PATH");
|
||||
if (efprintf(fp, "PATH=%s", path == NULL ? DEFAULT_PATH:path) == -1)
|
||||
goto eexit;
|
||||
if (efprintf(fp, "reason=%s", reason) == -1)
|
||||
if (efprintf(fp, "PATH=%s",
|
||||
path == NULL ? DEFAULT_PATH : path) == -1)
|
||||
goto eexit;
|
||||
if (efprintf(fp, "pid=%d", getpid()) == -1)
|
||||
goto eexit;
|
||||
|
||||
#ifdef PRIVSEP
|
||||
if (ctx->options & DHCPCD_PRIVSEP && ctx->ps_user != NULL) {
|
||||
if (efprintf(fp, "chroot=%s", ctx->ps_user->pw_dir) == -1)
|
||||
}
|
||||
if (!is_stdin) {
|
||||
if (efprintf(fp, "reason=%s", reason) == -1)
|
||||
goto eexit;
|
||||
}
|
||||
if (strcmp(reason, "CHROOT") == 0)
|
||||
goto make;
|
||||
#endif
|
||||
|
||||
ifo = ifp->options;
|
||||
#ifdef INET
|
||||
|
@ -340,9 +339,10 @@ make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp,
|
|||
protocol = PROTO_DHCP;
|
||||
#endif
|
||||
|
||||
|
||||
if (!is_stdin) {
|
||||
if (efprintf(fp, "interface=%s", ifp->name) == -1)
|
||||
goto eexit;
|
||||
}
|
||||
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
|
||||
goto dumplease;
|
||||
if (efprintf(fp, "ifcarrier=%s",
|
||||
|
@ -508,9 +508,6 @@ dumplease:
|
|||
goto eexit;
|
||||
}
|
||||
|
||||
#ifdef PRIVSEP
|
||||
make:
|
||||
#endif
|
||||
/* Convert buffer to argv */
|
||||
fflush(fp);
|
||||
|
||||
|
@ -536,6 +533,9 @@ make:
|
|||
fp = NULL;
|
||||
#endif
|
||||
|
||||
if (is_stdin)
|
||||
return buf_pos;
|
||||
|
||||
if (script_buftoenv(ctx, ctx->script_buf, (size_t)buf_pos) == NULL)
|
||||
goto eexit;
|
||||
|
||||
|
@ -685,6 +685,27 @@ script_run(struct dhcpcd_ctx *ctx, char **argv)
|
|||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
int
|
||||
script_dump(const char *env, size_t len)
|
||||
{
|
||||
const char *ep = env + len;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (*(ep - 1) != '\0') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (; env < ep; env += strlen(env) + 1) {
|
||||
if (strncmp(env, "new_", 4) == 0)
|
||||
env += 4;
|
||||
printf("%s\n", env);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
script_runreason(const struct interface *ifp, const char *reason)
|
||||
{
|
||||
|
@ -692,17 +713,21 @@ script_runreason(const struct interface *ifp, const char *reason)
|
|||
char *argv[2];
|
||||
int status = 0;
|
||||
struct fd_list *fd;
|
||||
long buflen;
|
||||
|
||||
if (ctx->script == NULL &&
|
||||
TAILQ_FIRST(&ifp->ctx->control_fds) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Make our env */
|
||||
if (make_env(ifp->ctx, ifp, reason) == -1) {
|
||||
if ((buflen = make_env(ifp->ctx, ifp, reason)) == -1) {
|
||||
logerr(__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(reason, "DUMP", 4) == 0)
|
||||
return script_dump(ctx->script_buf, (size_t)buflen);
|
||||
|
||||
if (ctx->script == NULL)
|
||||
goto send_listeners;
|
||||
|
||||
|
|
Loading…
Reference in New Issue