[master] db1a7ca Introduce a "workuser" subargument to -junix, which makes it possible to run the varnishd worker process as a different user than the VCC and CC subprocesses.

Poul-Henning Kamp phk at FreeBSD.org
Tue Apr 14 22:48:22 CEST 2015


commit db1a7ca80340dc17a3924437c1e76f45124ba7d9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Apr 14 20:46:11 2015 +0000

    Introduce a "workuser" subargument to -junix, which makes it possible
    to run the varnishd worker process as a different user than the VCC
    and CC subprocesses.
    
    It is mandatory that the workuser has the same login group as the user
    subparamter.
    
    Recommended values for packaging:
    
    	-junix,user=varnish	"varnish" user has login group "varnish"
    	-junix,workuser=vrun	"vrun" user has login group "varnish"

diff --git a/bin/varnishd/mgt/mgt_jail_unix.c b/bin/varnishd/mgt/mgt_jail_unix.c
index 8b989a8..7afc364 100644
--- a/bin/varnishd/mgt/mgt_jail_unix.c
+++ b/bin/varnishd/mgt/mgt_jail_unix.c
@@ -51,6 +51,11 @@ static gid_t vju_mgr_gid;
 static uid_t vju_uid;
 static gid_t vju_gid;
 static const char *vju_user;
+
+static uid_t vju_wrkuid;
+static gid_t vju_wrkgid;
+static const char *vju_wrkuser;
+
 static gid_t vju_cc_gid;
 static int vju_cc_gid_set;
 
@@ -79,6 +84,22 @@ vju_getuid(const char *arg)
 }
 
 static int
+vju_getwrkuid(const char *arg)
+{
+	struct passwd *pw;
+
+	pw = getpwnam(arg);
+	if (pw != NULL) {
+		vju_wrkuser = strdup(arg);
+		AN(vju_wrkuser);
+		vju_wrkuid = pw->pw_uid;
+		vju_wrkgid = pw->pw_gid;
+	}
+	endpwent();
+	return (pw == NULL ? -1 : 0);
+}
+
+static int
 vju_getccgid(const char *arg)
 {
 	struct group *gr;
@@ -121,6 +142,12 @@ vju_init(char **args)
 				    (*args) + 5);
 			continue;
 		}
+		if (!strncmp(*args, "workuser=", 9)) {
+			if (vju_getwrkuid((*args) + 9))
+				ARGV_ERR("Unix jail: %s user not found.\n",
+				    (*args) + 5);
+			continue;
+		}
 		if (!strncmp(*args, "ccgroup=", 8)) {
 			if (vju_getccgid((*args) + 8))
 				ARGV_ERR("Unix jail: %s group not found.\n",
@@ -158,8 +185,14 @@ vju_subproc(enum jail_subproc_e jse)
 	gid_t gid_list[NGID];
 
 	AZ(seteuid(0));
-	AZ(setgid(vju_gid));
-	AZ(initgroups(vju_user, vju_gid));
+	if (vju_wrkuser != NULL &&
+	    (jse == JAIL_SUBPROC_VCLLOAD || jse == JAIL_SUBPROC_WORKER)) {
+		AZ(setgid(vju_wrkgid));
+		AZ(initgroups(vju_wrkuser, vju_wrkgid));
+	} else {
+		AZ(setgid(vju_gid));
+		AZ(initgroups(vju_user, vju_gid));
+	}
 
 	if (jse == JAIL_SUBPROC_CC && vju_cc_gid_set) {
 		/* Add the optional extra group for the C-compiler access */
@@ -169,7 +202,12 @@ vju_subproc(enum jail_subproc_e jse)
 		AZ(setgroups(i, gid_list));
 	}
 
-	AZ(setuid(vju_uid));
+	if (vju_wrkuser != NULL &&
+	    (jse == JAIL_SUBPROC_VCLLOAD || jse == JAIL_SUBPROC_WORKER)) {
+		AZ(setuid(vju_wrkuid));
+	} else {
+		AZ(setuid(vju_uid));
+	}
 
 #ifdef __linux__
 	/*
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index f350614..4ee4fc7 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -172,7 +172,7 @@ run_cc(void *priv)
 		VSB_putc(sb, '%');
 	AZ(VSB_finish(sb));
 
-	(void)umask(077);
+	(void)umask(027);
 	(void)execl("/bin/sh", "/bin/sh", "-c", VSB_data(sb), (char*)0);
 	VSB_delete(sb);				// For flexelint
 }
@@ -227,7 +227,7 @@ mgt_vcc_touchfile(const char *fn, struct vsb *sb)
 {
 	int i;
 
-	i = open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+	i = open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0640);
 	if (i < 0) {
 		VSB_printf(sb, "Failed to create %s: %s", fn, strerror(errno));
 		return (2);
diff --git a/bin/varnishtest/tests/j00001.vtc b/bin/varnishtest/tests/j00001.vtc
new file mode 100644
index 0000000..25e6f3b
--- /dev/null
+++ b/bin/varnishtest/tests/j00001.vtc
@@ -0,0 +1,24 @@
+varnishtest "Run worker with different uid in UNIX jail"
+
+# The "vrun" user must have login group "varnish"
+
+feature user_varnish
+feature user_vrun
+feature group_varnish
+feature root
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 \
+	-jail "-junix,user=varnish,ccgroup=varnish,workuser=vrun" \
+	-vcl+backend {
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run
diff --git a/bin/varnishtest/tests/j00002.vtc b/bin/varnishtest/tests/j00002.vtc
new file mode 100644
index 0000000..34165a5
--- /dev/null
+++ b/bin/varnishtest/tests/j00002.vtc
@@ -0,0 +1,8 @@
+varnishtest "-junix bad subarg handling"
+
+feature root
+
+err_shell "unknown sub-argument" "${varnishd} -junix,bla=foo 2>&1"
+err_shell "user not found" "${varnishd} -junix,user=/// 2>&1"
+err_shell "user not found" "${varnishd} -junix,workuser=/// 2>&1"
+err_shell "group not found" "${varnishd} -junix,ccgroup=/// 2>&1"
diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c
index c4c9fd5..89719e8 100644
--- a/bin/varnishtest/vtc.c
+++ b/bin/varnishtest/vtc.c
@@ -573,6 +573,10 @@ cmd_feature(CMD_ARGS)
 		    getpwnam("varnish") != NULL)
 			continue;
 
+		if (!strcmp(av[i], "user_vrun") &&
+		    getpwnam("vrun") != NULL)
+			continue;
+
 		if (!strcmp(av[i], "group_varnish") &&
 		    getgrnam("varnish") != NULL)
 			continue;



More information about the varnish-commit mailing list