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