about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-08-16 17:28:57 -0400
committerJune McEnroe <june@causal.agency>2020-08-16 17:28:57 -0400
commit7d04a0f5e055a9067e0f6618de54c3bd56bdc999 (patch)
tree2d46aedcc2bc33f2ff990096f1999efc5c0bdf74
parentClear groups list for services (diff)
downloadcatsit-7d04a0f5e055a9067e0f6618de54c3bd56bdc999.tar.gz
catsit-7d04a0f5e055a9067e0f6618de54c3bd56bdc999.zip
Add privileged services
This allows running things like kfcgi which do their own privilege
dropping and chrooting. Need to update the examples with something like
that.
-rw-r--r--catsit.conf.515
-rw-r--r--daemon.h1
-rw-r--r--service.c16
3 files changed, 25 insertions, 7 deletions
diff --git a/catsit.conf.5 b/catsit.conf.5
index 36fc463..eee5ed2 100644
--- a/catsit.conf.5
+++ b/catsit.conf.5
@@ -1,4 +1,4 @@
-.Dd August 13, 2020
+.Dd August 16, 2020
 .Dt CATSIT.CONF 5
 .Os
 .
@@ -45,6 +45,19 @@ is executed using the shell.
 The shell variable
 .Va $0
 is set to the name of the service.
+.
+.It Ar @service Ar command ...
+Service names beginning with
+.Ql @
+define
+.Em privileged
+services,
+which are started with the same user and group as
+.Xr catsitd 8 .
+This can be used for services
+which drop their own privileges
+or which call
+.Xr chroot 2 .
 .El
 .
 .Sh EXAMPLES
diff --git a/daemon.h b/daemon.h
index 0dcf4de..d625df2 100644
--- a/daemon.h
+++ b/daemon.h
@@ -112,6 +112,7 @@ enum State {
 struct Service {
 	char *name;
 	char *command;
+	bool privileged;
 	enum State intent;
 	enum State state;
 	pid_t pid;
diff --git a/service.c b/service.c
index e27437f..3178f79 100644
--- a/service.c
+++ b/service.c
@@ -100,6 +100,8 @@ int serviceAdd(const char *name, const char *command) {
 	service->command = strdup(command);
 	if (!service->command) goto err;
 
+	if (name[0] == '@') service->privileged = true;
+
 	int error = pipe2(service->outPipe, O_CLOEXEC);
 	if (error) goto err;
 
@@ -181,14 +183,16 @@ void serviceStart(struct Service *service) {
 	int error = chdir(serviceDir);
 	if (error) err(ExitNoExec, "%s", serviceDir);
 
-	error = setgid(serviceGID);
-	if (error) err(ExitNoExec, "setgid");
+	if (!service->privileged) {
+		error = setgid(serviceGID);
+		if (error) err(ExitNoExec, "setgid");
 
-	error = setgroups(1, &serviceGID);
-	if (error) err(ExitNoExec, "setgroups");
+		error = setgroups(1, &serviceGID);
+		if (error) err(ExitNoExec, "setgroups");
 
-	error = setuid(serviceUID);
-	if (error) err(ExitNoExec, "setuid");
+		error = setuid(serviceUID);
+		if (error) err(ExitNoExec, "setuid");
+	}
 
 	size_t len = 0;
 	char command[ARG_MAX];