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.
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);
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;
- }
-}
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
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;
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");
}
#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)
#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;
}
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;
#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,
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");
close(ctx->fork_fd);
ctx->fork_fd = -1;
}
- control_close(ctx);
pidfile_clean();
eloop_clear(ctx->eloop);
#include "privsep-bpf.h"
#endif
+int ps_init(struct dhcpcd_ctx *);
int ps_start(struct dhcpcd_ctx *);
int ps_stop(struct dhcpcd_ctx *);