mirror of
https://github.com/OpenRC/openrc.git
synced 2024-11-23 09:53:45 +08:00
start-stop-daemon, supervise-daemon: before chroot
pam_start(3) must be called before chroot(2), because chroots usually do not have PAM-related files present. New options --std{out,err}{-logger,}-before-chroot in start-stop-daemon source and also described in the manpage. Manpage start-stop-daemon.8: -background => --background, remove duplicate --stderr entry.
This commit is contained in:
parent
c3545b54f3
commit
3104e5929f
@ -139,14 +139,14 @@ is an integer, it is passed directly to sched_setscheduler(2).
|
||||
Sets the priority parameter of the scheduling policy of the daemon. See sched(7) for details.
|
||||
.It Fl 1 , -stdout Ar logfile
|
||||
Redirect the standard output of the process to logfile when started with
|
||||
.Fl background .
|
||||
.Fl -background .
|
||||
The logfile Must be an absolute pathname, but relative to the path
|
||||
optionally given with
|
||||
.Fl r , -chroot .
|
||||
The logfile can also be a named pipe.
|
||||
.It Fl 2 , -stderr Ar logfile
|
||||
Redirect the standard error of the process to logfile when started with
|
||||
.Fl background .
|
||||
.Fl -background .
|
||||
The logfile must be an absolute pathname, but relative to the path
|
||||
optionally given with
|
||||
.Fl r , -chroot .
|
||||
@ -154,7 +154,7 @@ The logfile can also be a named pipe.
|
||||
.It Fl 3 , -stdout-logger Ar cmd
|
||||
Run cmd as a child process redirecting the standard output to the
|
||||
standard input of cmd when started with
|
||||
.Fl background .
|
||||
.Fl -background .
|
||||
Cmd must be an absolute pathname, but relative to the path optionally given with
|
||||
.Fl r , -chroot .
|
||||
This process must be prepared to accept input on stdin and be able to
|
||||
@ -163,11 +163,35 @@ log it or send it to another location.
|
||||
Run cmd as a child process and
|
||||
Redirect the standard error of the process to the standard input of cmd
|
||||
when started with
|
||||
.Fl background .
|
||||
.Fl -background .
|
||||
Cmd must be an absolute pathname, but relative to the path optionally given with
|
||||
.Fl r , -chroot .
|
||||
This process must be prepared to accept input on stdin and be able to
|
||||
log it or send it to another location.
|
||||
.It Fl 5 , -stdout-before-chroot Ar logfile
|
||||
Same as
|
||||
.Fl -stdout ,
|
||||
except that
|
||||
.Ar logfile
|
||||
is opened before entering the chroot.
|
||||
.It Fl 6 , -stderr-before-chroot Ar logfile
|
||||
Same as
|
||||
.Fl -stderr ,
|
||||
except that
|
||||
.Ar logfile
|
||||
is opened before entering the chroot.
|
||||
.It Fl 7 , -stdout-logger-before-chroot Ar cmd
|
||||
Same as
|
||||
.Fl -stdout-logger ,
|
||||
except that
|
||||
.Ar cmd
|
||||
is executed before entering the chroot.
|
||||
.It Fl 8 , -stderr-logger-before-chroot Ar cmd
|
||||
Same as
|
||||
.Fl -stderr-logger ,
|
||||
except that
|
||||
.Ar cmd
|
||||
is executed before entering the chroot.
|
||||
.It Fl -capabilities Ar cap-list
|
||||
Start the daemon with the listed inheritable, ambient and bounding capabilities.
|
||||
The format is the same as in cap_iab(3).
|
||||
@ -183,10 +207,6 @@ Wait
|
||||
after starting and check that daemon is still running.
|
||||
Useful for daemons that check configuration after forking or stopping race
|
||||
conditions where the pidfile is written out after forking.
|
||||
.It Fl 2 , -stderr Ar logfile
|
||||
The same thing as
|
||||
.Fl 1 , -stdout
|
||||
but with the standard error output.
|
||||
.El
|
||||
.Pp
|
||||
These options are only used for stopping daemons:
|
||||
|
@ -94,43 +94,47 @@ enum {
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:" \
|
||||
const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:5:6:7:8:" \
|
||||
getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "capabilities", 1, NULL, LONGOPT_CAPABILITIES},
|
||||
{ "secbits", 1, NULL, LONGOPT_SECBITS},
|
||||
{ "no-new-privs", 0, NULL, LONGOPT_NO_NEW_PRIVS},
|
||||
{ "ionice", 1, NULL, 'I'},
|
||||
{ "stop", 0, NULL, 'K'},
|
||||
{ "nicelevel", 1, NULL, 'N'},
|
||||
{ "oom-score-adj",1, NULL, LONGOPT_OOM_SCORE_ADJ},
|
||||
{ "retry", 1, NULL, 'R'},
|
||||
{ "start", 0, NULL, 'S'},
|
||||
{ "startas", 1, NULL, 'a'},
|
||||
{ "background", 0, NULL, 'b'},
|
||||
{ "chuid", 1, NULL, 'c'},
|
||||
{ "chdir", 1, NULL, 'd'},
|
||||
{ "env", 1, NULL, 'e'},
|
||||
{ "umask", 1, NULL, 'k'},
|
||||
{ "group", 1, NULL, 'g'},
|
||||
{ "interpreted", 0, NULL, 'i'},
|
||||
{ "make-pidfile", 0, NULL, 'm'},
|
||||
{ "name", 1, NULL, 'n'},
|
||||
{ "oknodo", 0, NULL, 'o'},
|
||||
{ "pidfile", 1, NULL, 'p'},
|
||||
{ "signal", 1, NULL, 's'},
|
||||
{ "test", 0, NULL, 't'},
|
||||
{ "user", 1, NULL, 'u'},
|
||||
{ "chroot", 1, NULL, 'r'},
|
||||
{ "wait", 1, NULL, 'w'},
|
||||
{ "exec", 1, NULL, 'x'},
|
||||
{ "stdout", 1, NULL, '1'},
|
||||
{ "stderr", 1, NULL, '2'},
|
||||
{ "stdout-logger",1, NULL, '3'},
|
||||
{ "stderr-logger",1, NULL, '4'},
|
||||
{ "progress", 0, NULL, 'P'},
|
||||
{ "scheduler", 1, NULL, LONGOPT_SCHEDULER},
|
||||
{ "scheduler-priority", 1, NULL, LONGOPT_SCHEDULER_PRIO},
|
||||
{ "capabilities", 1, NULL, LONGOPT_CAPABILITIES},
|
||||
{ "secbits", 1, NULL, LONGOPT_SECBITS},
|
||||
{ "no-new-privs", 0, NULL, LONGOPT_NO_NEW_PRIVS},
|
||||
{ "ionice", 1, NULL, 'I'},
|
||||
{ "stop", 0, NULL, 'K'},
|
||||
{ "nicelevel", 1, NULL, 'N'},
|
||||
{ "oom-score-adj", 1, NULL, LONGOPT_OOM_SCORE_ADJ},
|
||||
{ "retry", 1, NULL, 'R'},
|
||||
{ "start", 0, NULL, 'S'},
|
||||
{ "startas", 1, NULL, 'a'},
|
||||
{ "background", 0, NULL, 'b'},
|
||||
{ "chuid", 1, NULL, 'c'},
|
||||
{ "chdir", 1, NULL, 'd'},
|
||||
{ "env", 1, NULL, 'e'},
|
||||
{ "umask", 1, NULL, 'k'},
|
||||
{ "group", 1, NULL, 'g'},
|
||||
{ "interpreted", 0, NULL, 'i'},
|
||||
{ "make-pidfile", 0, NULL, 'm'},
|
||||
{ "name", 1, NULL, 'n'},
|
||||
{ "oknodo", 0, NULL, 'o'},
|
||||
{ "pidfile", 1, NULL, 'p'},
|
||||
{ "signal", 1, NULL, 's'},
|
||||
{ "test", 0, NULL, 't'},
|
||||
{ "user", 1, NULL, 'u'},
|
||||
{ "chroot", 1, NULL, 'r'},
|
||||
{ "wait", 1, NULL, 'w'},
|
||||
{ "exec", 1, NULL, 'x'},
|
||||
{ "stdout", 1, NULL, '1'},
|
||||
{ "stderr", 1, NULL, '2'},
|
||||
{ "stdout-logger", 1, NULL, '3'},
|
||||
{ "stderr-logger", 1, NULL, '4'},
|
||||
{ "stdout-before-chroot", 1, NULL, '5'},
|
||||
{ "stderr-before-chroot", 1, NULL, '6'},
|
||||
{ "stdout-logger-before-chroot", 1, NULL, '7'},
|
||||
{ "stderr-logger-before-chroot", 1, NULL, '8'},
|
||||
{ "progress", 0, NULL, 'P'},
|
||||
{ "scheduler", 1, NULL, LONGOPT_SCHEDULER},
|
||||
{ "scheduler-priority", 1, NULL, LONGOPT_SCHEDULER_PRIO},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
@ -165,6 +169,10 @@ const char * const longopts_help[] = {
|
||||
"Redirect stderr to file",
|
||||
"Redirect stdout to process",
|
||||
"Redirect stderr to process",
|
||||
"Redirect stdout to file, opened before chrooting",
|
||||
"Redirect stderr to file, opened before chrooting",
|
||||
"Redirect stdout to process, executed before chrooting",
|
||||
"Redirect stderr to process, ecxcuted before chrooting",
|
||||
"Print dots each second while waiting",
|
||||
"Set process scheduler",
|
||||
"Set process scheduler priority",
|
||||
@ -320,10 +328,14 @@ int main(int argc, char **argv)
|
||||
gid_t gid = 0;
|
||||
char *home = NULL;
|
||||
int tid = 0;
|
||||
char *redirect_stderr = NULL;
|
||||
char *redirect_stdout = NULL;
|
||||
char *stderr_process = NULL;
|
||||
char *redirect_stderr = NULL;
|
||||
char *stdout_process = NULL;
|
||||
char *stderr_process = NULL;
|
||||
char *redirect_stdout_before_chroot = NULL;
|
||||
char *redirect_stderr_before_chroot = NULL;
|
||||
char *stdout_process_before_chroot = NULL;
|
||||
char *stderr_process_before_chroot = NULL;
|
||||
int stdin_fd;
|
||||
int stdout_fd;
|
||||
int stderr_fd;
|
||||
@ -609,6 +621,22 @@ int main(int argc, char **argv)
|
||||
stderr_process = optarg;
|
||||
break;
|
||||
|
||||
case '5': /* --stdout-before-chroot /path/to/stdout.logfile */
|
||||
redirect_stdout_before_chroot = optarg;
|
||||
break;
|
||||
|
||||
case '6': /* --stderr-before-chroot /path/to/stderr.logfile */
|
||||
redirect_stderr_before_chroot = optarg;
|
||||
break;
|
||||
|
||||
case '7': /* --stdout-logger-before-chroot "command outside of chroot to run for stdout logging" */
|
||||
stdout_process_before_chroot = optarg;
|
||||
break;
|
||||
|
||||
case '8': /* --stderr-logger-before-chroot "command outside of chroot to run for stderr logging" */
|
||||
stderr_process_before_chroot = optarg;
|
||||
break;
|
||||
|
||||
case LONGOPT_SCHEDULER: /* --scheduler "Process scheduler policy" */
|
||||
scheduler = optarg;
|
||||
break;
|
||||
@ -653,6 +681,13 @@ int main(int argc, char **argv)
|
||||
++argc;
|
||||
};
|
||||
|
||||
if ((redirect_stdout_before_chroot && redirect_stdout)
|
||||
|| (redirect_stderr_before_chroot && redirect_stderr)
|
||||
|| (stdout_process_before_chroot && stdout_process)
|
||||
|| (stderr_process_before_chroot && stderr_process))
|
||||
eerrorx("%s: stream redirection and logging options can't be used together with"
|
||||
" their before-chroot variants", applet);
|
||||
|
||||
if (stop || sig != -1) {
|
||||
if (sig == -1)
|
||||
sig = SIGTERM;
|
||||
@ -899,6 +934,60 @@ int main(int argc, char **argv)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PAM
|
||||
if (changeuser != NULL) {
|
||||
pamr = pam_start("start-stop-daemon",
|
||||
changeuser, &conv, &pamh);
|
||||
|
||||
if (pamr == PAM_SUCCESS)
|
||||
pamr = pam_acct_mgmt(pamh, PAM_SILENT);
|
||||
if (pamr == PAM_SUCCESS)
|
||||
pamr = pam_open_session(pamh, PAM_SILENT);
|
||||
if (pamr != PAM_SUCCESS)
|
||||
eerrorx("%s: pam error: %s",
|
||||
applet, pam_strerror(pamh, pamr));
|
||||
}
|
||||
#endif
|
||||
|
||||
stdin_fd = devnull_fd;
|
||||
stdout_fd = devnull_fd;
|
||||
stderr_fd = devnull_fd;
|
||||
|
||||
#define log_redirection(redirect_stdout,redirect_stderr,stdout_process,stderr_process) \
|
||||
if (redirect_stdout) { \
|
||||
if ((stdout_fd = open(redirect_stdout, \
|
||||
O_WRONLY | O_CREAT | O_APPEND, \
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1) \
|
||||
eerrorx("%s: unable to open the logfile" \
|
||||
" for stdout `%s': %s", \
|
||||
applet, redirect_stdout, strerror(errno)); \
|
||||
}else if (stdout_process) { \
|
||||
stdout_fd = rc_pipe_command(stdout_process); \
|
||||
if (stdout_fd == -1) \
|
||||
eerrorx("%s: unable to open the logging process" \
|
||||
" for stdout `%s': %s", \
|
||||
applet, stdout_process, strerror(errno)); \
|
||||
} \
|
||||
if (redirect_stderr) { \
|
||||
if ((stderr_fd = open(redirect_stderr, \
|
||||
O_WRONLY | O_CREAT | O_APPEND, \
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1) \
|
||||
eerrorx("%s: unable to open the logfile" \
|
||||
" for stderr `%s': %s", \
|
||||
applet, redirect_stderr, strerror(errno)); \
|
||||
}else if (stderr_process) { \
|
||||
stderr_fd = rc_pipe_command(stderr_process); \
|
||||
if (stderr_fd == -1) \
|
||||
eerrorx("%s: unable to open the logging process" \
|
||||
" for stderr `%s': %s", \
|
||||
applet, stderr_process, strerror(errno)); \
|
||||
}
|
||||
|
||||
log_redirection(redirect_stdout_before_chroot,
|
||||
redirect_stderr_before_chroot,
|
||||
stdout_process_before_chroot,
|
||||
stderr_process_before_chroot)
|
||||
|
||||
if (ch_root && chroot(ch_root) < 0)
|
||||
eerrorx("%s: chroot `%s': %s",
|
||||
applet, ch_root, strerror(errno));
|
||||
@ -916,21 +1005,6 @@ int main(int argc, char **argv)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PAM
|
||||
if (changeuser != NULL) {
|
||||
pamr = pam_start("start-stop-daemon",
|
||||
changeuser, &conv, &pamh);
|
||||
|
||||
if (pamr == PAM_SUCCESS)
|
||||
pamr = pam_acct_mgmt(pamh, PAM_SILENT);
|
||||
if (pamr == PAM_SUCCESS)
|
||||
pamr = pam_open_session(pamh, PAM_SILENT);
|
||||
if (pamr != PAM_SUCCESS)
|
||||
eerrorx("%s: pam error: %s",
|
||||
applet, pam_strerror(pamh, pamr));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gid && setgid(gid))
|
||||
eerrorx("%s: unable to set groupid to %d",
|
||||
applet, gid);
|
||||
@ -1043,37 +1117,10 @@ int main(int argc, char **argv)
|
||||
setenv("PATH", newpath, 1);
|
||||
}
|
||||
|
||||
stdin_fd = devnull_fd;
|
||||
stdout_fd = devnull_fd;
|
||||
stderr_fd = devnull_fd;
|
||||
if (redirect_stdout) {
|
||||
if ((stdout_fd = open(redirect_stdout,
|
||||
O_WRONLY | O_CREAT | O_APPEND,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
|
||||
eerrorx("%s: unable to open the logfile"
|
||||
" for stdout `%s': %s",
|
||||
applet, redirect_stdout, strerror(errno));
|
||||
}else if (stdout_process) {
|
||||
stdout_fd = rc_pipe_command(stdout_process);
|
||||
if (stdout_fd == -1)
|
||||
eerrorx("%s: unable to open the logging process"
|
||||
" for stdout `%s': %s",
|
||||
applet, stdout_process, strerror(errno));
|
||||
}
|
||||
if (redirect_stderr) {
|
||||
if ((stderr_fd = open(redirect_stderr,
|
||||
O_WRONLY | O_CREAT | O_APPEND,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
|
||||
eerrorx("%s: unable to open the logfile"
|
||||
" for stderr `%s': %s",
|
||||
applet, redirect_stderr, strerror(errno));
|
||||
}else if (stderr_process) {
|
||||
stderr_fd = rc_pipe_command(stderr_process);
|
||||
if (stderr_fd == -1)
|
||||
eerrorx("%s: unable to open the logging process"
|
||||
" for stderr `%s': %s",
|
||||
applet, stderr_process, strerror(errno));
|
||||
}
|
||||
log_redirection(redirect_stdout,
|
||||
redirect_stderr,
|
||||
stdout_process,
|
||||
stderr_process)
|
||||
|
||||
if (background)
|
||||
dup2(stdin_fd, STDIN_FILENO);
|
||||
|
@ -406,12 +406,6 @@ static void child_process(char *exec, char **argv)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (ch_root && chroot(ch_root) < 0)
|
||||
eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
|
||||
|
||||
if (ch_dir && chdir(ch_dir) < 0)
|
||||
eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
|
||||
|
||||
#ifdef HAVE_PAM
|
||||
if (changeuser != NULL) {
|
||||
pamr = pam_start("supervise-daemon",
|
||||
@ -426,6 +420,12 @@ static void child_process(char *exec, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ch_root && chroot(ch_root) < 0)
|
||||
eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
|
||||
|
||||
if (ch_dir && chdir(ch_dir) < 0)
|
||||
eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
|
||||
|
||||
if (gid && setgid(gid))
|
||||
eerrorx("%s: unable to set groupid to %d", applet, gid);
|
||||
if (changeuser && initgroups(changeuser, gid))
|
||||
|
Loading…
Reference in New Issue
Block a user