aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gmid.c28
-rw-r--r--proc.c18
2 files changed, 38 insertions, 8 deletions
diff --git a/gmid.c b/gmid.c
index 0949e7f..463b7ae 100644
--- a/gmid.c
+++ b/gmid.c
@@ -51,7 +51,7 @@ static struct privsep_proc procs[] = {
{ "logger", PROC_LOGGER, main_dispatch_logger, logger },
};
-static const char *opts = "c:D:fI:hnP:T:Vv";
+static const char *opts = "c:D:fI:hnP:T:U:VvX:";
static const struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
@@ -169,6 +169,7 @@ main(int argc, char **argv)
struct conf *conf;
struct privsep *ps;
const char *errstr, *title = NULL;
+ const char *user = NULL, *chroot = NULL;
size_t i;
int ch, conftest = 0;
int proc_instance = 0;
@@ -214,12 +215,18 @@ main(int argc, char **argv)
if (proc_id == PROC_MAX)
fatalx("invalid process name");
break;
+ case 'U':
+ user = optarg;
+ break;
case 'V':
puts("Version: " GMID_STRING);
return 0;
case 'v':
verbose = 1;
break;
+ case 'X':
+ chroot = optarg;
+ break;
default:
usage();
return 1;
@@ -231,10 +238,21 @@ main(int argc, char **argv)
conf = config_new();
- if (parse_conf(conf, config_path) == -1)
- fatalx("failed to load configuration file");
- if (*conf->chroot != '\0' && *conf->user == '\0')
- fatalx("can't chroot without a user to switch to after.");
+ /*
+ * Only the parent loads the config, the others get user and
+ * chroot via flags and the rest via imsg.
+ */
+ if (proc_id == PROC_PARENT) {
+ if (parse_conf(conf, config_path) == -1)
+ fatalx("failed to load configuration file");
+ if (*conf->chroot != '\0' && *conf->user == '\0')
+ fatalx("can't chroot without a user to switch to.");
+ } else {
+ if (user)
+ strlcpy(conf->user, user, sizeof(conf->user));
+ if (chroot)
+ strlcpy(conf->chroot, chroot, sizeof(conf->chroot));
+ }
if (conftest) {
fprintf(stderr, "config OK\n");
diff --git a/proc.c b/proc.c
index 62d3b87..3060e65 100644
--- a/proc.c
+++ b/proc.c
@@ -89,14 +89,14 @@ void
proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc,
int debug, int argc, char **argv)
{
- unsigned int proc, nargc, i, proc_i;
+ unsigned int proc, nargc, i, proc_i, proc_X = 0;
const char **nargv;
struct privsep_proc *p;
char num[32];
int fd;
/* Prepare the new process argv. */
- nargv = calloc(argc + 5, sizeof(char *));
+ nargv = calloc(argc + 9, sizeof(char *));
if (nargv == NULL)
fatal("%s: calloc", __func__);
@@ -109,6 +109,16 @@ proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc,
proc_i = nargc;
nargc++;
+ /* Set user and chroot */
+ if (ps->ps_pw != NULL) {
+ nargv[nargc++] = "-U";
+ nargv[nargc++] = ps->ps_pw->pw_name;
+
+ nargv[nargc++] = "-X";
+ proc_X = nargc;
+ nargc++;
+ }
+
/* Point process instance arg to stack and copy the original args. */
nargv[nargc++] = "-I";
nargv[nargc++] = num;
@@ -120,8 +130,10 @@ proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc,
for (proc = 0; proc < nproc; proc++) {
p = &procs[proc];
- /* Update args with process title. */
+ /* Update args with process title and chroot. */
nargv[proc_i] = (char *)(uintptr_t)p->p_title;
+ if (proc_X && p->p_chroot != NULL)
+ nargv[proc_X] = p->p_chroot;
/* Fire children processes. */
for (i = 0; i < ps->ps_instances[p->p_id]; i++) {