]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Delay control startup after starting privsep
authorRoy Marples <roy@marples.name>
Thu, 9 Jan 2020 15:39:18 +0000 (15:39 +0000)
committerRoy Marples <roy@marples.name>
Thu, 9 Jan 2020 15:39:18 +0000 (15:39 +0000)
This means we don't need to close it for other processes.
Add ps_init so that we can change directory permissions before
starting privsep itself.

src/control.c
src/control.h
src/dhcpcd.c
src/privsep.c
src/privsep.h

index f148987812019dddfd849e106fc0f3ed8c58142b..c81d2cb340ac5973072cc092b4c74628f4cf402b 100644 (file)
@@ -269,25 +269,22 @@ control_stop(struct dhcpcd_ctx *ctx)
        int retval = 0;
        struct fd_list *l;
 
-       if (ctx->options & DHCPCD_FORKED)
-               goto freeit;
-
-       if (ctx->control_fd == -1)
-               return 0;
-
-       control_close(ctx);
-       if (unlink(ctx->control_sock) == -1)
-               retval = -1;
+       if (ctx->control_fd != -1) {
+               eloop_event_delete(ctx->eloop, ctx->control_fd);
+               close(ctx->control_fd);
+               ctx->control_fd = -1;
+               if (unlink(ctx->control_sock) == -1 && errno != ENOENT)
+                       retval = -1;
+       }
 
        if (ctx->control_unpriv_fd != -1) {
                eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd);
                close(ctx->control_unpriv_fd);
                ctx->control_unpriv_fd = -1;
-               if (unlink(UNPRIVSOCKET) == -1)
+               if (unlink(UNPRIVSOCKET) == -1 && errno != ENOENT)
                        retval = -1;
        }
 
-freeit:
        while ((l = TAILQ_FIRST(&ctx->control_fds))) {
                TAILQ_REMOVE(&ctx->control_fds, l, next);
                eloop_event_delete(ctx->eloop, l->fd);
@@ -448,14 +445,3 @@ queue:
        eloop_event_add_w(fd->ctx->eloop, fd->fd, control_writeone, fd);
        return 0;
 }
-
-void
-control_close(struct dhcpcd_ctx *ctx)
-{
-
-       if (ctx->control_fd != -1) {
-               eloop_event_delete(ctx->eloop, ctx->control_fd);
-               close(ctx->control_fd);
-               ctx->control_fd = -1;
-       }
-}
index 4d8c5225e6610fd4ba9a8ba6c2dce9cdd5b4e9d8..72f601bfb8547ac9d40c593e439c989a64334b2c 100644 (file)
@@ -71,6 +71,5 @@ int control_stop(struct dhcpcd_ctx *);
 int control_open(const char *);
 ssize_t control_send(struct dhcpcd_ctx *, int, char * const *);
 int control_queue(struct fd_list *, void *, size_t, bool);
-void control_close(struct dhcpcd_ctx *ctx);
 
 #endif
index d2b205ab92bfeacb029f109b850288336c5fb1ea..13376b92b7a58c65f92072c7fa3fb7843d0e82fa 100644 (file)
@@ -1917,7 +1917,6 @@ printpidfile:
                if (ctx.control_fd != -1) {
                        loginfox("sending commands to master dhcpcd process");
                        len = control_send(&ctx, argc, argv);
-                       control_close(&ctx);
                        if (len > 0) {
                                logdebugx("send OK");
                                goto exit_success;
@@ -1989,6 +1988,13 @@ printpidfile:
 
        logdebugx(PACKAGE "-" VERSION " starting");
 
+#ifdef PRIVSEP
+       if (ps_init(&ctx) == -1 && errno != 0) {
+               logerr("ps_init");
+               goto exit_failure;
+       }
+#endif
+
 #ifdef USE_SIGNALS
        if (pipe(sigpipe) == -1) {
                logerr("pipe");
@@ -2038,18 +2044,6 @@ printpidfile:
        }
 #endif
 
-       if (control_start(&ctx,
-           ctx.options & DHCPCD_MASTER ? NULL : argv[optind]) == -1)
-       {
-               logerr("%s: control_start", __func__);
-               goto exit_failure;
-       }
-
-       setproctitle("%s%s%s",
-           ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind],
-           ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
-           ctx.options & DHCPCD_IPV6 ? " [ip6]" : "");
-
 #ifdef BSD
        /* Disable the kernel RTADV sysctl as early as possible. */
        if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS)
@@ -2057,7 +2051,7 @@ printpidfile:
 #endif
 
 #ifdef PRIVSEP
-       if (ps_start(&ctx) == -1 && errno != 0) {
+       if (ctx.options & DHCPCD_PRIVSEP && ps_start(&ctx) == -1) {
                logerr("ps_start");
                goto exit_failure;
        }
@@ -2065,6 +2059,18 @@ printpidfile:
                goto run_loop;
 #endif
 
+       if (control_start(&ctx,
+           ctx.options & DHCPCD_MASTER ? NULL : argv[optind]) == -1)
+       {
+               logerr("%s: control_start", __func__);
+               goto exit_failure;
+       }
+
+       setproctitle("%s%s%s",
+           ctx.options & DHCPCD_MASTER ? "[master]" : argv[optind],
+           ctx.options & DHCPCD_IPV4 ? " [ip4]" : "",
+           ctx.options & DHCPCD_IPV6 ? " [ip6]" : "");
+
        if (if_opensockets(&ctx) == -1) {
                logerr("%s: if_opensockets", __func__);
                goto exit_failure;
index 9696e5c8e4ec3dadc1083d5ab7d0a2a3c2e44c93..fb0a85b6ce3a9cbc6652c83aa1116820b2141324 100644 (file)
 #include <util.h>
 #endif
 
+int
+ps_init(struct dhcpcd_ctx *ctx)
+{
+       struct passwd *pw;
+       gid_t gid = (gid_t)-1;
+
+       errno = 0;
+       if ((pw = getpwnam(PRIVSEP_USER)) == NULL) {
+               ctx->options &= ~DHCPCD_PRIVSEP;
+               if (errno == 0) {
+                       logerrx("no such user %s", PRIVSEP_USER);
+                       /* Just incase logerrx caused an error... */
+                       errno = 0;
+               } else
+                       logerr("getpwnam");
+               return -1;
+       }
+
+
+       /* Change ownership of stuff we need to drop at exit. */
+       if (chown(ctx->pidfile, pw->pw_uid, gid) == -1)
+               logerr("chown `%s'", ctx->pidfile);
+       if (chown(DBDIR, pw->pw_uid, gid) == -1)
+               logerr("chown `%s'", DBDIR);
+       if (chown(RUNDIR, pw->pw_uid, gid) == -1)
+               logerr("chown `%s'", RUNDIR);
+       return 0;
+}
+
 pid_t
 ps_dostart(struct dhcpcd_ctx *ctx,
     pid_t *priv_pid, int *priv_fd,
@@ -80,51 +109,21 @@ ps_dostart(struct dhcpcd_ctx *ctx,
        int fd[2];
        pid_t pid;
 
-       /* Even if we're not dropping privs, we need to ensure that the unpriv
-        * user exists so the processes that do need it startup just fine. */
-       errno = 0;
-       if ((pw = getpwnam(PRIVSEP_USER)) == NULL) {
-               ctx->options &= ~DHCPCD_PRIVSEP;
-               if (errno == 0) {
-                       if (ctx == recv_ctx) { /* Only log the once. */
+       if (flags & PSF_DROPPRIVS) {
+               errno = 0;
+               if ((pw = getpwnam(PRIVSEP_USER)) == NULL) {
+                       if (errno == 0)
                                logerrx("no such user %s", PRIVSEP_USER);
-                               /* Just incase logerrx caused an error... */
-                               errno = 0;
-                       }
-               } else
-                       logerr("getpwnam");
-               return -1;
-       }
-
-       if (!(flags & PSF_DROPPRIVS)) {
+                       else
+                               logerr("getpwnam");
+                       return -1;
+               }
+       } else
                pw = NULL;
-               goto create_sp;
-       }
 
-       if (priv_pid == NULL) {
-               gid_t gid = (gid_t)-1;
-
-               /* Main process - change ownership of stuff we need to
-                * drop at exit. */
-               if (pw != NULL) {
-                       if (chown(ctx->pidfile, pw->pw_uid, gid) == -1)
-                               logerr("chown `%s'", ctx->pidfile);
-                       if (chown(DBDIR, pw->pw_uid, gid) == -1)
-                               logerr("chown `%s'", DBDIR);
-                       if (chown(RUNDIR, pw->pw_uid, gid) == -1)
-                               logerr("chown `%s'", RUNDIR);
-                       if (ctx->options & DHCPCD_MASTER) {
-                               if (chown(ctx->control_sock,
-                                   pw->pw_uid, gid) == -1)
-                                       logerr("chown `%s'", ctx->control_sock);
-                               if (chown(UNPRIVSOCKET, pw->pw_uid, gid) == -1)
-                                       logerr("chown `%s'", UNPRIVSOCKET);
-                       }
-               }
+       if (priv_fd == NULL)
                goto dropprivs;
-       }
 
-create_sp:
        stype = SOCK_CLOEXEC | SOCK_NONBLOCK;
        if (socketpair(AF_UNIX, SOCK_DGRAM | stype, 0, fd) == -1) {
                logerr("socketpair");
@@ -159,7 +158,6 @@ create_sp:
                close(ctx->fork_fd);
                ctx->fork_fd = -1;
        }
-       control_close(ctx);
        pidfile_clean();
        eloop_clear(ctx->eloop);
 
index 4c306f3db4a067e1bbbf59843a1922b521c7616e..2f63038a818bfb96ed4609bfbdd10abd13b85469 100644 (file)
@@ -130,6 +130,7 @@ TAILQ_HEAD(ps_process_head, ps_process);
 #include "privsep-bpf.h"
 #endif
 
+int ps_init(struct dhcpcd_ctx *);
 int ps_start(struct dhcpcd_ctx *);
 int ps_stop(struct dhcpcd_ctx *);