commit b78d5d201ec9dff659184a2fe49da41100a6d3a7
parent 543329e56561498d53f24b95d26cc33341abef6d
Author: Gerrit Pape <pape@smarden.org>
Date: Tue, 27 Apr 2004 17:32:47 +0000
chpst: support -/ chroot.
Diffstat:
4 files changed, 78 insertions(+), 56 deletions(-)
diff --git a/debian/rules b/debian/rules
@@ -38,19 +38,24 @@ endif
DIR =`pwd`/debian/runit
-build: deb-checkdir build-stamp
-build-stamp:
- -gcc -v
- tar xfzp runit-1.0.2.tar.gz
+unpack: deb-checkdir unpack-stamp
+unpack-stamp:
+ tar xzf runit-1.0.2.tar.gz
ln -s runit-1.0.2 admin/runit
+ (cd admin/runit && patch -p0) <debian/diff/chpst-chroot.diff
echo "$(CC) $(CFLAGS)" >admin/runit/src/conf-cc
echo "$(CC) $(LDFLAGS)" >admin/runit/src/conf-ld
+ touch unpack-stamp
+
+build: deb-checkdir build-stamp
+build-stamp: unpack-stamp
+ -gcc -v
$(MAKE) -Cadmin/runit/src default check
touch build-stamp
clean: deb-checkdir deb-checkuid
rm -rf admin
- rm -f build-stamp
+ rm -f unpack-stamp build-stamp
rm -rf "$(DIR)"
rm -f debian/files debian/substvars changelog
@@ -112,6 +117,6 @@ binary-arch: install runit.deb
binary: binary-indep binary-arch
-.PHONY: build clean install binary-indep binary-arch binary
+.PHONY: unpack build clean install binary-indep binary-arch binary
include debian/implicit
diff --git a/doc/chpst.8.html b/doc/chpst.8.html
@@ -12,21 +12,21 @@
chpst - runs a program with a changed process state
<h2><a name='sect1'>Synopsis</a></h2>
<b>chpst</b> [-vP012]
-[-u <i>user</i>] [-U <i>user</i>] [-e <i>dir</i>] [-l|-L <i>lock</i>] [-m <i>bytes</i>] [-o <i>n</i>] [-p <i>n</i>] [-f <i>bytes</i>] [-c
-<i>bytes</i>] <i>prog</i>
+[-u <i>user</i>] [-U <i>user</i>] [-e <i>dir</i>] [-/ <i>root</i>] [-l|-L <i>lock</i>] [-m <i>bytes</i>] [-o <i>n</i>] [-p <i>n</i>] [-f <i>bytes</i>]
+[-c <i>bytes</i>] <i>prog</i>
<h2><a name='sect2'>Description</a></h2>
<i>prog</i> consists of one or more arguments. <p>
-<b>chpst</b> changes
-the process state according to the given options, and runs <i>prog</i>.
+<b>chpst</b>
+changes the process state according to the given options, and runs <i>prog</i>.
+
<h2><a name='sect3'>Options</a></h2>
<dl>
-<dt><b>-u
-<i>user[:group]</b> </i></dt>
-<dd>setuidgid. Set uid and gid to the <i>user</i>’s uid and gid. If <i>user</i>
-is followed by a colon and a <i>group</i>, set the gid to <i>group</i>’s gid instead of
-<i>user</i>’s gid. All supplementary groups are removed. </dd>
+<dt><b>-u <i>user[:group]</b> </i></dt>
+<dd>setuidgid. Set uid and gid to the <i>user</i>’s uid and gid.
+If <i>user</i> is followed by a colon and a <i>group</i>, set the gid to <i>group</i>’s gid instead
+of <i>user</i>’s gid. All supplementary groups are removed. </dd>
<dt><b>-U <i>user[:group]</b> </i></dt>
<dd>envuidgid.
@@ -43,69 +43,73 @@ adds the environment variable <i>k</i> with the value <i>v</i>. The name <i>k</i
to newlines. If the file <i>k</i> is empty (0 bytes long), <b>chpst</b> removes the environment
variable <i>k</i> if it exists, without adding a new variable. </dd>
+<dt><b>-/ <i>root</b> </i></dt>
+<dd>chroot. Change
+the root directory to <i>root</i> before starting <i>prog</i>. </dd>
+
<dt><b>-l <i>lock</b> </i></dt>
-<dd>lock. Open
-the file <i>lock</i> for writing, and obtain an exclusive lock on it. <i>lock</i> will
-be created if it does not exist. If <i>lock</i> is locked by another process, wait
-until a new lock can be obtained. </dd>
+<dd>lock. Open the file
+<i>lock</i> for writing, and obtain an exclusive lock on it. <i>lock</i> will be created
+if it does not exist. If <i>lock</i> is locked by another process, wait until a
+new lock can be obtained. </dd>
<dt><b>-L <i>lock</b> </i></dt>
-<dd>The same as -l, but fail immediately
-if <i>lock</i> is locked by another process. </dd>
+<dd>The same as -l, but fail immediately if
+<i>lock</i> is locked by another process. </dd>
<dt><b>-m <i>bytes</b> </i></dt>
-<dd>limit memory. Limit the data
-segment, stack segment, locked physical pages, and total of all segment
-per process to <i>bytes</i> bytes each. </dd>
+<dd>limit memory. Limit the data segment,
+stack segment, locked physical pages, and total of all segment per process
+to <i>bytes</i> bytes each. </dd>
<dt><b>-o <i>n</b> </i></dt>
-<dd>limit open files. Limit the number of
-open file descriptors per process to <i>n</i>. </dd>
+<dd>limit open files. Limit the number of open file
+descriptors per process to <i>n</i>. </dd>
<dt><b>-p <i>n</b> </i></dt>
-<dd>limit processes. Limit the number
-of processes per uid to <i>n</i>. </dd>
+<dd>limit processes. Limit the number of processes
+per uid to <i>n</i>. </dd>
<dt><b>-f <i>bytes</b> </i></dt>
-<dd>limit output size. Limit the output file
-size to <i>bytes</i> bytes. </dd>
+<dd>limit output size. Limit the output file size to <i>bytes</i>
+bytes. </dd>
<dt><b>-c <i>bytes</b> </i></dt>
-<dd>limit core size. Limit the core file size to
-<i>bytes</i> bytes. </dd>
+<dd>limit core size. Limit the core file size to <i>bytes</i> bytes. </dd>
-<dt><b>-v</b> </dt>
-<dd>verbose. Print verbose messages to standard error. This includes
-warnings about limits unsupported by the system. </dd>
+<dt><b>-v</b>
+</dt>
+<dd>verbose. Print verbose messages to standard error. This includes warnings
+about limits unsupported by the system. </dd>
<dt><b>-P</b> </dt>
-<dd>pgrphack. Run <i>prog</i> in
-a new process group. </dd>
+<dd>pgrphack. Run <i>prog</i> in a new process
+group. </dd>
<dt><b>-0</b> </dt>
-<dd>Close standard input before running <i>prog</i>. </dd>
+<dd>Close standard input before starting <i>prog</i>. </dd>
<dt><b>-1</b> </dt>
-<dd>Close
-standard output before running <i>prog</i>. </dd>
+<dd>Close standard output
+before starting <i>prog</i>. </dd>
<dt><b>-2</b> </dt>
-<dd>Close standard error before running
-<i>prog</i>. </dd>
+<dd>Close standard error before starting <i>prog</i>. </dd>
</dl>
<h2><a name='sect4'>Exit Codes</a></h2>
-<b>chpst</b> exits 100 when called with wrong options. It prints
-an error message and exits 111 if it has trouble changing the process state.
-Otherwise its exit code is the same as that of <i>prog</i>.
+<b>chpst</b>
+exits 100 when called with wrong options. It prints an error message and
+exits 111 if it has trouble changing the process state. Otherwise its exit
+code is the same as that of <i>prog</i>.
<h2><a name='sect5'>Emulation</a></h2>
-If <b>chpst</b> is
-called as <i><b>envdir</b>(8)</i>, <i><b>envuidgid</b>(8)</i>, <i><b>pgrphack</b>(8)</i>, <i><b>setlock</b>(8)</i>, <i><b>setuidgid</b>(8)</i>,
-or <i><b>softlimit</b>(8)</i>, it emulates the functionality of these programs from the
-daemontools package respectively.
+If <b>chpst</b> is called as <i><b>envdir</b>(8)</i>,
+<i><b>envuidgid</b>(8)</i>, <i><b>pgrphack</b>(8)</i>, <i><b>setlock</b>(8)</i>, <i><b>setuidgid</b>(8)</i>, or <i><b>softlimit</b>(8)</i>, it
+emulates the functionality of these programs from the daemontools package
+respectively.
<h2><a name='sect6'>See Also</a></h2>
-<i>runsv(8)</i>, <i>runsvctrl(8)</i>, <i>runsvstat(8)</i>,
-<i>runsvdir(8)</i>, <i>setsid(2)</i> <p>
+<i>runsv(8)</i>, <i>runsvctrl(8)</i>, <i>runsvstat(8)</i>, <i>runsvdir(8)</i>,
+<i>setsid(2)</i> <p>
<i>http://smarden.org/runit/</i><br>
<i>http://cr.yp.to/daemontools.html</i><br>
diff --git a/man/chpst.8 b/man/chpst.8
@@ -10,6 +10,8 @@ chpst \- runs a program with a changed process state
.IR user ]
[-e
.IR dir ]
+[\-/
+.IR root ]
[-l|-L
.IR lock ]
[-m
@@ -96,6 +98,13 @@ removes the environment variable
.I k
if it exists, without adding a new variable.
.TP
+.B \-/ \fIroot
+chroot.
+Change the root directory to
+.I root
+before starting
+.IR prog .
+.TP
.B \-l \fIlock
lock.
Open the file
@@ -153,15 +162,15 @@ Run
in a new process group.
.TP
.B \-0
-Close standard input before running
+Close standard input before starting
.IR prog .
.TP
.B \-1
-Close standard output before running
+Close standard output before starting
.IR prog .
.TP
.B \-2
-Close standard error before running
+Close standard error before starting
.IR prog .
.SH EXIT CODES
.B chpst
diff --git a/src/chpst.c b/src/chpst.c
@@ -20,7 +20,7 @@
#include "openreadclose.h"
#include "direntry.h"
-#define USAGE_MAIN " [-vP012] [-u user[:group]] [-U user[:group]] [-e dir] [-l|-L lock] [-m n] [-o n] [-p n] [-f n] [-c n] prog"
+#define USAGE_MAIN " [-vP012] [-u user[:group]] [-U user[:group]] [-e dir] [-/ root] [-l|-L lock] [-m n] [-o n] [-p n] [-f n] [-c n] prog"
#define FATAL "chpst: fatal: "
#define WARNING "chpst: warning: "
@@ -57,6 +57,7 @@ long limitc =-2;
long limitr =-2;
long limitt =-2;
const char *lock =0;
+const char *root =0;
unsigned int lockdelay;
void suidgid(char *user, unsigned int dogrp) {
@@ -270,7 +271,8 @@ int main(int argc, const char *const *argv) {
if (str_equal(progname, "setlock")) setlock(argc, argv);
if (str_equal(progname, "softlimit")) softlimit(argc, argv);
- while ((opt =getopt(argc, argv, "u:U:e:m:o:p:f:c:r:t:l:L:vP012V")) != opteof)
+ while ((opt =getopt(argc, argv, "u:U:e:m:o:p:f:c:r:t:/:l:L:vP012V"))
+ != opteof)
switch(opt) {
case 'u': set_user =(char*)optarg; break;
case 'U': env_user =(char*)optarg; break;
@@ -285,6 +287,7 @@ int main(int argc, const char *const *argv) {
case 'c': if (optarg[scan_ulong(optarg, &limitc)]) usage(); break;
case 'r': if (optarg[scan_ulong(optarg, &limitr)]) usage(); break;
case 't': if (optarg[scan_ulong(optarg, &limitt)]) usage(); break;
+ case '/': root =optarg; break;
case 'l': if (lock) usage(); lock =optarg; lockdelay =1; break;
case 'L': if (lock) usage(); lock =optarg; lockdelay =0; break;
case 'v': verbose =1; break;
@@ -300,6 +303,7 @@ int main(int argc, const char *const *argv) {
if (pgrp) setsid();
if (env_dir) edir(env_dir);
+ if (root) if (chroot(root) == -1) fatal("unable to change root directory");
if (env_user) euidgid(env_user, 1);
if (set_user) suidgid(set_user, 1);
slimit();