summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-04-23 14:56:00 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2021-04-23 14:56:00 +0000
commit27f1ba99521c4bdf081e6364ca4bea841aee8557 (patch)
tree87e37daeb930903a16341c6b42ff5f0fadc24c66
parent3bde455795bb3273922ec7be293e3911913576c2 (diff)
downloads6-linux-init-27f1ba99521c4bdf081e6364ca4bea841aee8557.tar.xz
Hack s6-l-i-m so it doesn't fail when run as non-root
-rw-r--r--doc/s6-linux-init-maker.html5
-rw-r--r--package/modes2
-rw-r--r--src/init/s6-linux-init-maker.c56
3 files changed, 41 insertions, 22 deletions
diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html
index 9bf44ac..9b148de 100644
--- a/doc/s6-linux-init-maker.html
+++ b/doc/s6-linux-init-maker.html
@@ -68,8 +68,11 @@ machine</em>. If it is not the case, the system will fail to boot.
</pre>
<ul>
- <li> s6-linux-init-maker must be run as root, on the machine
+ <li> s6-linux-init-maker must be run on the machine
that will boot an s6-based system. </li>
+ <li> It normally should be <em>run as root</em>. It supports
+not running as root for a small amount of very specific cases; but
+you should run it as root unless you know exactly what you are doing. </li>
<li> s6-linux-init-maker parses options on its command line. </li>
<li> It writes data into a directory <em>dir</em>, which must not
exist beforehand. </li>
diff --git a/package/modes b/package/modes
index 0cc7f74..395d000 100644
--- a/package/modes
+++ b/package/modes
@@ -7,4 +7,4 @@ s6-linux-init-logouthookd 0744
s6-linux-init-echo 0755
s6-linux-init-nuke 0744
s6-linux-init-umountall 0744
-s6-linux-init-maker 0744
+s6-linux-init-maker 0755
diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c
index c505e04..af67bf7 100644
--- a/src/init/s6-linux-init-maker.c
+++ b/src/init/s6-linux-init-maker.c
@@ -46,7 +46,7 @@ static char const *initial_path = INITPATH ;
static char const *env_store = 0 ;
static char const *early_getty = 0 ;
static char const *slashdev = 0 ;
-static char const *log_user = "root" ;
+static char const *log_user = 0 ;
static char const *initdefault = 0 ;
static char const *skeldir = S6_LINUX_INIT_SKELDIR ;
static unsigned int initial_umask = 0022 ;
@@ -57,9 +57,11 @@ static int console = 0 ;
static int logouthookd = 0 ;
static int inns = 0 ;
static int nologger = 0 ;
+static uid_t myuid = -1 ;
+static gid_t mygid = -1 ;
#ifdef S6_LINUX_INIT_UTMPD_PATH
-static char const *utmp_user = "" ;
+static char const *utmp_user = 0 ;
#endif
typedef int writetobuf_func_t (buffer *, char const *) ;
@@ -153,7 +155,7 @@ static int s6_svscan_log_script (buffer *b, char const *data)
EXECLINE_EXTBINPREFIX "redirfd -w 1 /dev/null") < 0
|| buffer_puts(b, "\n"
EXECLINE_EXTBINPREFIX "redirfd -rnb 0 " LOGGER_FIFO "\n") < 0) return 0 ;
- if (strcmp(log_user, "root"))
+ if (log_user && strcmp(log_user, "root"))
{
size_t sabase = satmp.len ;
if (buffer_puts(b, S6_EXTBINPREFIX "s6-setuidgid ") < 0
@@ -323,7 +325,7 @@ static void auto_dir_internal (char const *base, char const *dir, uid_t uid, gid
}
else
{
- if (chown(fn, uid, gid) < 0) goto err ;
+ if (!myuid && !mygid && chown(fn, uid, gid) < 0) goto err ;
if (mode & 07000 && chmod(fn, mode) < 0) goto err ;
}
return ;
@@ -469,17 +471,25 @@ static void make_env (char const *base, char const *envname, char *modif, size_t
static void getug (char const *base, char const *s, uid_t *uid, gid_t *gid)
{
- struct passwd *pw ;
- errno = 0 ;
- pw = getpwnam(s) ;
- if (!pw)
+ if (!s || myuid || mygid)
{
- cleanup(base) ;
- if (!errno) strerr_diefu3x(100, "find user ", s, " in passwd database") ;
- else strerr_diefu2sys(111, "getpwnam for ", s) ;
+ *uid = myuid ;
+ *gid = mygid ;
+ }
+ else
+ {
+ struct passwd *pw ;
+ errno = 0 ;
+ pw = getpwnam(s) ;
+ if (!pw)
+ {
+ cleanup(base) ;
+ if (!errno) strerr_diefu3x(100, "find user ", s, " in passwd database") ;
+ else strerr_diefu2sys(111, "getpwnam for ", s) ;
+ }
+ *uid = pw->pw_uid ;
+ *gid = pw->pw_gid ;
}
- *uid = pw->pw_uid ;
- *gid = pw->pw_gid ;
}
#ifdef S6_LINUX_INIT_UTMPD_PATH
@@ -504,12 +514,16 @@ static int utmpd_script (buffer *b, char const *aux)
size_t sabase = satmp.len ;
if (!put_shebang(b)
|| buffer_puts(b,
- EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n"
- S6_EXTBINPREFIX "s6-setuidgid ") < 0
- || !string_quote(&satmp, utmp_user, strlen(utmp_user))) return 0 ;
- if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ;
- satmp.len = sabase ;
- if (buffer_puts(b, "\n"
+ EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n") < 0) return 0 ;
+ if (utmp_user)
+ {
+ if (!buffer_puts(b, S6_EXTBINPREFIX "s6-setuidgid ") < 0
+ || !string_quote(&satmp, utmp_user, strlen(utmp_user))) return 0 ;
+ if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ;
+ satmp.len = sabase ;
+ if (buffer_put(b, "\n", 1) < 0) return 0 ;
+ }
+ if (buffer_puts(b,
EXECLINE_EXTBINPREFIX "cd " S6_LINUX_INIT_TMPFS "/" UTMPS_DIR "\n"
EXECLINE_EXTBINPREFIX "fdmove 1 3\n"
S6_EXTBINPREFIX "s6-ipcserver -1 -c 1000 -- " UTMPS_UTMPD_PATH "\n"
@@ -597,7 +611,7 @@ static inline void make_image (char const *base)
}
#ifdef S6_LINUX_INIT_UTMPD_PATH
- if (utmp_user[0]) make_utmps(base) ;
+ if (utmp_user) make_utmps(base) ;
#endif
}
@@ -676,6 +690,8 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (inns && slashdev)
strerr_warnw1x("both -C and -d options given; are you sure your container does not come with a pre-mounted /dev?") ;
+ myuid = getuid() ;
+ mygid = getgid() ;
umask(0) ;
if (mkdir(argv[0], 0755) < 0)
strerr_diefu2sys(111, "mkdir ", argv[0]) ;