summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/s6-rc-compile.html17
-rw-r--r--package/deps.mak2
-rw-r--r--src/s6-rc/s6-rc-compile.c55
3 files changed, 59 insertions, 15 deletions
diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html
index 1464ea5..a11acfb 100644
--- a/doc/s6-rc-compile.html
+++ b/doc/s6-rc-compile.html
@@ -36,7 +36,7 @@ the current service database via
<h2> Interface </h2>
<pre>
- s6-rc-compile [ -v <em>verbosity</em> ] <em>compiled</em> <em>source...</em>
+ s6-rc-compile [ -v <em>verbosity</em> ] [ -u <em>uids</em> ] [ -g <em>gids</em> ] <em>compiled</em> <em>source...</em>
</pre>
<ul>
@@ -56,8 +56,23 @@ services declared in every <em>source</em> argument. </li>
verbose. Default is 1: warning and error messages will be printed to
stderr. 0 silences warnings. 2 adds a bit more information about
what s6-rc-compile is doing. 3 or more is heavy debug output. </li>
+ <li> <tt>-u&nbsp;<em>uids</em></tt>&nbsp;: list users allowed to
+use this database with <a href="s6-rc.html">s6-rc</a> to start and
+stop services. <em>uids</em> must be a comma-separated list of
+numerical UIDs. </li>
+ <li> <tt>-g&nbsp;<em>gids</em></tt>&nbsp;: list groups allowed to
+use this database with <a href="s6-rc.html">s6-rc</a> to start and
+stop services. <em>gids</em> must be a comma-separated list of
+numerical GIDs. </li>
</ul>
+<p>
+ If the <tt>-u</tt> or <tt>-g</tt> option is used, then <tt>0</tt>
+must be explicitly listed in <em>uids</em> in order to allow root
+to operate the database. If neither option is used, then root
+(and only root) is implicitly allowed.
+</p>
+
<h2> Source format </h2>
<p>
diff --git a/package/deps.mak b/package/deps.mak
index e3a1dfd..520f9a3 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -14,7 +14,7 @@ src/s6-rc/s6-rc-compile.o src/s6-rc/s6-rc-compile.lo: src/s6-rc/s6-rc-compile.c
src/s6-rc/s6-rc-db.o src/s6-rc/s6-rc-db.lo: src/s6-rc/s6-rc-db.c src/include/s6-rc/s6rc.h
src/s6-rc/s6-rc-dryrun.o src/s6-rc/s6-rc-dryrun.lo: src/s6-rc/s6-rc-dryrun.c
src/s6-rc/s6-rc-init.o src/s6-rc/s6-rc-init.lo: src/s6-rc/s6-rc-init.c src/include/s6-rc/s6rc.h
-src/s6-rc/s6-rc-update.o src/s6-rc/s6-rc-update.lo: src/s6-rc/s6-rc-update.c
+src/s6-rc/s6-rc-update.o src/s6-rc/s6-rc-update.lo: src/s6-rc/s6-rc-update.c src/include/s6-rc/s6rc-constants.h
src/s6-rc/s6-rc.o src/s6-rc/s6-rc.lo: src/s6-rc/s6-rc.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h
libs6rc.a: src/libs6rc/s6rc_db_check_depcycles.o src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_graph_closure.o
diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c
index 3324637..a16f311 100644
--- a/src/s6-rc/s6-rc-compile.c
+++ b/src/s6-rc/s6-rc-compile.c
@@ -5,7 +5,9 @@
#include <unistd.h>
#include <errno.h>
#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
#include <skalibs/uint.h>
+#include <skalibs/gidstuff.h>
#include <skalibs/bytestr.h>
#include <skalibs/bitarray.h>
#include <skalibs/strerr2.h>
@@ -25,7 +27,7 @@
#include <s6/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-compile [ -v verbosity ] destdir sources..."
+#define USAGE "s6-rc-compile [ -v verbosity ] [ -u okuid,okuid... ] [ -g okgid,okgid... ] destdir sources..."
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_dief1x(111, "out of memory") ;
@@ -38,6 +40,8 @@ S6_EXTBINPREFIX "s6-ipcserverd -1 --\n" \
S6_EXTBINPREFIX "s6-ipcserver-access -v0 -E -l0 -i data/rules --\n" \
S6_EXTBINPREFIX "s6-sudod -t 2000 --\n"
+#define BASE_RULES "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/gid"
+
static unsigned int verbosity = 1 ;
static stralloc keep = STRALLOC_ZERO ;
static stralloc data = STRALLOC_ZERO ;
@@ -833,19 +837,38 @@ static inline void write_sizes (char const *compiled, s6rc_db_t const *db)
auto_file(compiled, "n", pack, 20) ;
}
-static inline void write_specials (char const *compiled)
+static inline void write_specials (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn)
{
+ unsigned int i = uidn ;
+ char fn[sizeof(BASE_RULES) + UINT64_FMT + 6] = BASE_RULES ;
auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER) ;
auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/notification-fd", "3\n", 2) ;
- auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data") ;
- auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules") ;
- auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/uid") ;
- auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/uid/default") ;
- auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/uid/default/deny", "", 0) ;
- auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/uid/0") ;
- auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/uid/0/allow", "", 0) ;
auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", S6RC_ONESHOT_RUNNER_RUNSCRIPT, sizeof(S6RC_ONESHOT_RUNNER_RUNSCRIPT) - 1) ;
auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ;
+ auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data") ;
+ auto_dir(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules") ;
+ if (gidn) auto_dir(compiled, fn) ;
+ fn[sizeof(BASE_RULES) - 4] = 'u' ;
+ auto_dir(compiled, fn) ;
+ fn[sizeof(BASE_RULES) - 1] = '/' ;
+ while (i--)
+ {
+ unsigned int len = uint64_fmt(fn + sizeof(BASE_RULES), uids[i]) ;
+ fn[sizeof(BASE_RULES) + len] = 0 ;
+ auto_dir(compiled, fn) ;
+ byte_copy(fn + sizeof(BASE_RULES) + len, 7, "/allow") ;
+ auto_file(compiled, fn, "", 0) ;
+ }
+ fn[sizeof(BASE_RULES) - 4] = 'g' ;
+ i = gidn ;
+ while (i--)
+ {
+ unsigned int len = gid_fmt(fn + sizeof(BASE_RULES), gids[i]) ;
+ fn[sizeof(BASE_RULES) + len] = 0 ;
+ auto_dir(compiled, fn) ;
+ byte_copy(fn + sizeof(BASE_RULES) + len, 7, "/allow") ;
+ auto_file(compiled, fn, "", 0) ;
+ }
}
static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps)
@@ -1128,14 +1151,14 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db)
strerr_diefu2sys(111, "write to ", dbfn) ;
}
-static inline void write_compiled (char const *compiled, s6rc_db_t const *db, char const *const *srcdirs, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps, unsigned int maxnamelen)
+static inline void write_compiled (char const *compiled, s6rc_db_t const *db, char const *const *srcdirs, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps, unsigned int maxnamelen, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn)
{
if (verbosity >= 2) strerr_warni2x("writing compiled information to ", compiled) ;
init_compiled(compiled) ;
write_sizes(compiled, db) ;
write_resolve(compiled, db, bundles, nbundles, bdeps) ;
write_db(compiled, db) ;
- write_specials(compiled) ;
+ write_specials(compiled, uids, uidn, gids, gidn) ;
write_servicedirs(compiled, db, srcdirs, maxnamelen) ;
}
@@ -1143,22 +1166,28 @@ int main (int argc, char const *const *argv)
{
before_t before = BEFORE_ZERO ;
char const *compiled ;
+ unsigned int uidn = 0, gidn = 0 ;
+ uint64 uids[256] ;
+ gid_t gids[256] ;
PROG = "s6-rc-compile" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- register int opt = subgetopt_r(argc, argv, "v:", &l) ;
+ register int opt = subgetopt_r(argc, argv, "v:u:g:", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
+ case 'u' : if (!uint64_scanlist(uids, 255, l.arg, &uidn)) dieusage() ; break ;
+ case 'g' : if (!gid_scanlist(gids, 255, l.arg, &gidn)) dieusage() ; break ;
default : dieusage() ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc < 2) dieusage() ;
+ if (!uidn && !gidn) uids[uidn++] = 0 ;
compiled = *argv++ ;
add_specials(&before) ;
for (; *argv ; argv++) add_sources(&before, *argv) ;
@@ -1197,7 +1226,7 @@ int main (int argc, char const *const *argv)
uint32 deps[db.ndeps << 1] ;
db.deps = deps ;
flatlist_services(&db, sarray) ;
- write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, maxnamelen) ;
+ write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, maxnamelen, uids, uidn, gids, gidn) ;
}
}