summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-11-11 17:41:16 +0000
committerRoy Marples <roy@marples.name>2020-11-11 17:41:16 +0000
commit040561d61e157e7fb371f1311f0cee3536dee0d2 (patch)
tree162dea972f50117b6a17790f26ea8e50893905e0
parentc49db0e1ced7c95d49fb6c844b918cf6ca899d4f (diff)
downloaddhcpcd-040561d61e157e7fb371f1311f0cee3536dee0d2.tar.xz
control: create an unpriv socket for non master mode
This allows `dhcpcd -U4 eth0` to work once more.
-rw-r--r--src/control.c36
-rw-r--r--src/defs.h5
-rw-r--r--src/dhcpcd.c3
-rw-r--r--src/dhcpcd.h1
4 files changed, 25 insertions, 20 deletions
diff --git a/src/control.c b/src/control.c
index e704df7f..71405ed1 100644
--- a/src/control.c
+++ b/src/control.c
@@ -274,9 +274,11 @@ control_handle_unpriv(void *arg)
}
static int
-make_path(char *path, size_t len, const char *ifname, sa_family_t family)
+make_path(char *path, size_t len, const char *ifname, sa_family_t family,
+ bool unpriv)
{
const char *per;
+ const char *sunpriv;
switch(family) {
case AF_INET:
@@ -289,8 +291,13 @@ make_path(char *path, size_t len, const char *ifname, sa_family_t family)
per = "";
break;
}
+ if (unpriv)
+ sunpriv = ifname ? ".unpriv" : "unpriv.";
+ else
+ sunpriv = "";
return snprintf(path, len, CONTROLSOCKET,
- ifname ? ifname : "", ifname ? per : "", ifname ? "." : "");
+ ifname ? ifname : "", ifname ? per : "",
+ sunpriv, ifname ? "." : "");
}
static int
@@ -303,10 +310,7 @@ make_sock(struct sockaddr_un *sa, const char *ifname, sa_family_t family,
return -1;
memset(sa, 0, sizeof(*sa));
sa->sun_family = AF_UNIX;
- if (unpriv)
- strlcpy(sa->sun_path, UNPRIVSOCKET, sizeof(sa->sun_path));
- else
- make_path(sa->sun_path, sizeof(sa->sun_path), ifname, family);
+ make_path(sa->sun_path, sizeof(sa->sun_path), ifname, family, unpriv);
return fd;
}
@@ -346,9 +350,12 @@ control_start1(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family,
}
#endif
- if ((fmode & S_UNPRIV) != S_UNPRIV)
+ if ((fmode & S_PRIV) == S_PRIV)
strlcpy(ctx->control_sock, sa.sun_path,
sizeof(ctx->control_sock));
+ else
+ strlcpy(ctx->control_sock_unpriv, sa.sun_path,
+ sizeof(ctx->control_sock_unpriv));
return fd;
}
@@ -360,7 +367,9 @@ control_start(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family)
#ifdef PRIVSEP
if (IN_PRIVSEP_SE(ctx)) {
make_path(ctx->control_sock, sizeof(ctx->control_sock),
- ifname, family);
+ ifname, family, false);
+ make_path(ctx->control_sock_unpriv, sizeof(ctx->control_sock),
+ ifname, family, true);
return 0;
}
#endif
@@ -371,11 +380,7 @@ control_start(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family)
ctx->control_fd = fd;
eloop_event_add(ctx->eloop, fd, control_handle, ctx);
- if (ifname == NULL &&
- (fd = control_start1(ctx, NULL, AF_UNSPEC, S_UNPRIV)) != -1)
- {
- /* We must be in master mode, so create an unprivileged socket
- * to allow normal users to learn the status of dhcpcd. */
+ if ((fd = control_start1(ctx, ifname, family, S_UNPRIV)) != -1) {
ctx->control_unpriv_fd = fd;
eloop_event_add(ctx->eloop, fd, control_handle_unpriv, ctx);
}
@@ -414,8 +419,7 @@ control_stop(struct dhcpcd_ctx *ctx)
if (IN_PRIVSEP_SE(ctx)) {
if (ps_root_unlink(ctx, ctx->control_sock) == -1)
retval = -1;
- if (ctx->options & DHCPCD_MASTER &&
- control_unlink(ctx, UNPRIVSOCKET) == -1)
+ if (ps_root_unlink(ctx, ctx->control_sock_unpriv) == -1)
retval = -1;
return retval;
} else if (ctx->options & DHCPCD_FORKED)
@@ -434,7 +438,7 @@ control_stop(struct dhcpcd_ctx *ctx)
eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd);
close(ctx->control_unpriv_fd);
ctx->control_unpriv_fd = -1;
- if (control_unlink(ctx, UNPRIVSOCKET) == -1)
+ if (control_unlink(ctx, ctx->control_sock_unpriv) == -1)
retval = -1;
}
diff --git a/src/defs.h b/src/defs.h
index de3abfcd..2233de7e 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -60,10 +60,7 @@
# define PIDFILE RUNDIR "/%s%s%spid"
#endif
#ifndef CONTROLSOCKET
-# define CONTROLSOCKET RUNDIR "/%s%s%ssock"
-#endif
-#ifndef UNPRIVSOCKET
-# define UNPRIVSOCKET RUNDIR "/unpriv.sock"
+# define CONTROLSOCKET RUNDIR "/%s%s%s%ssock"
#endif
#ifndef RDM_MONOFILE
# define RDM_MONOFILE DBDIR "/rdm_monotonic"
diff --git a/src/dhcpcd.c b/src/dhcpcd.c
index f106abd9..7377fcc6 100644
--- a/src/dhcpcd.c
+++ b/src/dhcpcd.c
@@ -2179,6 +2179,9 @@ printpidfile:
if (!(ctx.options & DHCPCD_MASTER))
ctx.control_fd = control_open(argv[optind], family,
ctx.options & DHCPCD_DUMPLEASE);
+ if (!(ctx.options & DHCPCD_MASTER) && ctx.control_fd == -1)
+ ctx.control_fd = control_open(argv[optind], AF_UNSPEC,
+ ctx.options & DHCPCD_DUMPLEASE);
if (ctx.control_fd == -1)
ctx.control_fd = control_open(NULL, AF_UNSPEC,
ctx.options & DHCPCD_DUMPLEASE);
diff --git a/src/dhcpcd.h b/src/dhcpcd.h
index 97d7a322..e18919de 100644
--- a/src/dhcpcd.h
+++ b/src/dhcpcd.h
@@ -180,6 +180,7 @@ struct dhcpcd_ctx {
int control_unpriv_fd;
struct fd_list_head control_fds;
char control_sock[sizeof(CONTROLSOCKET) + IF_NAMESIZE];
+ char control_sock_unpriv[sizeof(CONTROLSOCKET) + IF_NAMESIZE + 7];
gid_t control_group;
/* DHCP Enterprise options, RFC3925 */