service(8): use an environment more consistent with init(8)
init(8) sets the "daemon" login class without specifying a pw entry (so no substitutions are done on the variables). service(8)'s use of env -L had the effect of specifying root's pw entry, with two effects: getpwnam and getpwuid are being called, which may not be entirely safe depending on what nsswitch is up to and what stage of boot we are at, and substitutions would have been done. Fix by teaching env(8) to allow -L -/classname to set the class environment with no pw entry at all specified, and use it in service(8). PR: 253959
This commit is contained in:
parent
aff9b9ee89
commit
55deb0a5f0
7
usr.bin/env/env.1
vendored
7
usr.bin/env/env.1
vendored
@ -31,7 +31,7 @@
|
|||||||
.\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp
|
.\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 11, 2020
|
.Dd March 3, 2021
|
||||||
.Dt ENV 1
|
.Dt ENV 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -104,6 +104,11 @@ is used, then the specified user's
|
|||||||
.Pa ~/.login_conf
|
.Pa ~/.login_conf
|
||||||
is read as well.
|
is read as well.
|
||||||
The user may be specified by name or by uid.
|
The user may be specified by name or by uid.
|
||||||
|
If a username of
|
||||||
|
.Sq Li \&-
|
||||||
|
is given, then no user lookup will be done, the login class will default to
|
||||||
|
.Sq Li default
|
||||||
|
if not explicitly given, and no substitutions will be done on the values.
|
||||||
.\" -P
|
.\" -P
|
||||||
.It Fl P Ar altpath
|
.It Fl P Ar altpath
|
||||||
Search the set of directories as specified by
|
Search the set of directories as specified by
|
||||||
|
25
usr.bin/env/env.c
vendored
25
usr.bin/env/env.c
vendored
@ -144,16 +144,23 @@ main(int argc, char **argv)
|
|||||||
login_class = strchr(login_name, '/');
|
login_class = strchr(login_name, '/');
|
||||||
if (login_class)
|
if (login_class)
|
||||||
*login_class++ = '\0';
|
*login_class++ = '\0';
|
||||||
pw = getpwnam(login_name);
|
if (*login_name != '\0' && strcmp(login_name,"-") != 0) {
|
||||||
if (pw == NULL) {
|
pw = getpwnam(login_name);
|
||||||
char *endp = NULL;
|
if (pw == NULL) {
|
||||||
errno = 0;
|
char *endp = NULL;
|
||||||
uid = strtoul(login_name, &endp, 10);
|
errno = 0;
|
||||||
if (errno == 0 && *endp == '\0')
|
uid = strtoul(login_name, &endp, 10);
|
||||||
pw = getpwuid(uid);
|
if (errno == 0 && *endp == '\0')
|
||||||
|
pw = getpwuid(uid);
|
||||||
|
}
|
||||||
|
if (pw == NULL)
|
||||||
|
errx(EXIT_FAILURE, "no such user: %s", login_name);
|
||||||
}
|
}
|
||||||
if (pw == NULL)
|
/*
|
||||||
errx(EXIT_FAILURE, "no such user: %s", login_name);
|
* Note that it is safe for pw to be null here; the libutil
|
||||||
|
* code handles that, bypassing substitution of $ and using
|
||||||
|
* the class "default" if no class name is given either.
|
||||||
|
*/
|
||||||
if (login_class != NULL) {
|
if (login_class != NULL) {
|
||||||
lc = login_getclass(login_class);
|
lc = login_getclass(login_class);
|
||||||
if (lc == NULL)
|
if (lc == NULL)
|
||||||
|
@ -171,7 +171,7 @@ cd /
|
|||||||
for dir in /etc/rc.d $local_startup; do
|
for dir in /etc/rc.d $local_startup; do
|
||||||
if [ -x "$dir/$script" ]; then
|
if [ -x "$dir/$script" ]; then
|
||||||
[ -n "$VERBOSE" ] && echo "$script is located in $dir"
|
[ -n "$VERBOSE" ] && echo "$script is located in $dir"
|
||||||
exec env -i -L 0/daemon HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin "$dir/$script" "$@"
|
exec env -i -L -/daemon HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin "$dir/$script" "$@"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user