diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index fbbfd4f514..5cb83afa57 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2152,16 +2152,17 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy LogExtraFields= - Configures additional log metadata fields to include in all log records generated by processes - associated with this unit. This setting takes one or more journal field assignments in the format - FIELD=VALUE separated by whitespace. See - systemd.journal-fields7 for - details on the journal field concept. Even though the underlying journal implementation permits binary field - values, this setting accepts only valid UTF-8 values. To include space characters in a journal field value, - enclose the assignment in double quotes ("). The usual specifiers are expanded in all assignments (see - below). Note that this setting is not only useful for attaching additional metadata to log records of a unit, - but given that all fields and values are indexed may also be used to implement cross-unit log record - matching. Assign an empty string to reset the list. + Configures additional log metadata fields to include in all log records generated by + processes associated with this unit. This setting takes one or more journal field assignments in the + format FIELD=VALUE separated by whitespace. See + systemd.journal-fields7 + for details on the journal field concept. Even though the underlying journal implementation permits + binary field values, this setting accepts only valid UTF-8 values. To include space characters in a + journal field value, enclose the assignment in double quotes ("). + The usual specifiers are expanded in all assignments (see below). Note that this setting is not only + useful for attaching additional metadata to log records of a unit, but given that all fields and + values are indexed may also be used to implement cross-unit log record matching. Assign an empty + string to reset the list. @@ -2355,10 +2356,16 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy $PATH - Colon-separated list of directories to use - when launching executables. systemd uses a fixed value of - /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin. - + Colon-separated list of directories to use when launching + executables. systemd uses a fixed value of + /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin + in the system manager. When compiled for systems with "unmerged /usr" (/bin is + not a symlink to /usr/bin), + :/sbin:/bin is appended. In case of the + the user manager, each bin/ and sbin/ pair is switched, so + that programs from /usr/bin have higher priority than programs from + /usr/sbin, etc. It is recommended to not rely on this in any way, and have only + one program with a given name in $PATH. diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 1f46cd65c9..71fb7041a3 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -11,30 +11,38 @@ #include "time-util.h" #define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin" +#define PATH_SPLIT_BIN_SBIN(x) x "bin:" x "sbin" #define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0" #define PATH_NORMAL_SBIN_BIN(x) x "bin" +#define PATH_NORMAL_BIN_SBIN(x) x "bin" #define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0" #if HAVE_SPLIT_BIN # define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x) +# define PATH_BIN_SBIN(x) PATH_SPLIT_BIN_SBIN(x) # define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x) #else # define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x) +# define PATH_BIN_SBIN(x) PATH_NORMAL_BIN_SBIN(x) # define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x) #endif #define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/") +#define DEFAULT_USER_PATH_NORMAL PATH_BIN_SBIN("/usr/local/") ":" PATH_BIN_SBIN("/usr/") #define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/") #define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/") +#define DEFAULT_USER_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_BIN_SBIN("/") #define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/") #define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/") #if HAVE_SPLIT_USR # define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR +# define DEFAULT_USER_PATH DEFAULT_USER_PATH_SPLIT_USR # define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR #else # define DEFAULT_PATH DEFAULT_PATH_NORMAL +# define DEFAULT_USER_PATH DEFAULT_USER_PATH_NORMAL # define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR #endif diff --git a/src/core/manager.c b/src/core/manager.c index 00bf6f70bc..d9114bb0c5 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -603,6 +603,8 @@ static char** sanitize_environment(char **l) { } int manager_default_environment(Manager *m) { + int r; + assert(m); m->transient_environment = strv_free(m->transient_environment); @@ -616,16 +618,29 @@ int manager_default_environment(Manager *m) { * /proc/self/environ valid; it is used for tagging * the init process inside containers. */ m->transient_environment = strv_new("PATH=" DEFAULT_PATH); + if (!m->transient_environment) + return log_oom(); /* Import locale variables LC_*= from configuration */ (void) locale_setup(&m->transient_environment); - } else - /* The user manager passes its own environment - * along to its children. */ - m->transient_environment = strv_copy(environ); + } else { + _cleanup_free_ char *k = NULL; - if (!m->transient_environment) - return log_oom(); + /* The user manager passes its own environment + * along to its children, except for $PATH. */ + m->transient_environment = strv_copy(environ); + if (!m->transient_environment) + return log_oom(); + + k = strdup("PATH=" DEFAULT_USER_PATH); + if (!k) + return log_oom(); + + r = strv_env_replace(&m->transient_environment, k); + if (r < 0) + return log_oom(); + TAKE_PTR(k); + } sanitize_environment(m->transient_environment);