mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
Merge pull request #7846 from poettering/nobody-getenv
some assorted fixes and additions, in particular a way to turn off "nobody" synthesizing on a specific system
This commit is contained in:
commit
a9883559e3
@ -8,3 +8,41 @@ expression s;
|
||||
@@
|
||||
- s ? s : ""
|
||||
+ strempty(s)
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- if (!s)
|
||||
- s = "";
|
||||
+ s = strempty(s);
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- s ?: "(null)"
|
||||
+ strnull(s)
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- s ? s : "(null)"
|
||||
+ strnull(s)
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- if (!s)
|
||||
- s = "(null)";
|
||||
+ s = strnull(s);
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- s ?: "n/a"
|
||||
+ strna(s)
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- s ? s : "n/a"
|
||||
+ strna(s)
|
||||
@@
|
||||
expression s;
|
||||
@@
|
||||
- if (!s)
|
||||
- s = "n/a";
|
||||
+ s = strna(s);
|
||||
|
@ -1225,8 +1225,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
|
||||
if (!filename_is_valid(fn))
|
||||
return -EINVAL;
|
||||
|
||||
if (!extra)
|
||||
extra = "";
|
||||
extra = strempty(extra);
|
||||
|
||||
t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
|
||||
if (!t)
|
||||
@ -1259,8 +1258,7 @@ int tempfn_random(const char *p, const char *extra, char **ret) {
|
||||
if (!filename_is_valid(fn))
|
||||
return -EINVAL;
|
||||
|
||||
if (!extra)
|
||||
extra = "";
|
||||
extra = strempty(extra);
|
||||
|
||||
t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
|
||||
if (!t)
|
||||
@ -1300,8 +1298,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!extra)
|
||||
extra = "";
|
||||
extra = strempty(extra);
|
||||
|
||||
t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
|
||||
if (!t)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "time-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int unlink_noerrno(const char *path);
|
||||
|
||||
@ -89,13 +90,14 @@ int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flag
|
||||
|
||||
/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */
|
||||
static inline void rmdir_and_free(char *p) {
|
||||
PROTECT_ERRNO;
|
||||
(void) rmdir(p);
|
||||
free(p);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
|
||||
|
||||
static inline void unlink_and_free(char *p) {
|
||||
(void) unlink(p);
|
||||
(void) unlink_noerrno(p);
|
||||
free(p);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||
|
@ -796,6 +796,8 @@ void sigkill_wait(pid_t pid) {
|
||||
}
|
||||
|
||||
void sigkill_waitp(pid_t *pid) {
|
||||
PROTECT_ERRNO;
|
||||
|
||||
if (!pid)
|
||||
return;
|
||||
if (*pid <= 1)
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
typedef enum RemoveFlags {
|
||||
REMOVE_ONLY_DIRECTORIES = 1,
|
||||
REMOVE_ROOT = 2,
|
||||
@ -34,6 +36,7 @@ int rm_rf(const char *path, RemoveFlags flags);
|
||||
|
||||
/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
|
||||
static inline void rm_rf_physical_and_free(char *p) {
|
||||
PROTECT_ERRNO;
|
||||
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
free(p);
|
||||
}
|
||||
|
@ -52,15 +52,15 @@ static inline bool streq_ptr(const char *a, const char *b) {
|
||||
}
|
||||
|
||||
static inline const char* strempty(const char *s) {
|
||||
return s ? s : "";
|
||||
return s ?: "";
|
||||
}
|
||||
|
||||
static inline const char* strnull(const char *s) {
|
||||
return s ? s : "(null)";
|
||||
return s ?: "(null)";
|
||||
}
|
||||
|
||||
static inline const char *strna(const char *s) {
|
||||
return s ? s : "n/a";
|
||||
return s ?: "n/a";
|
||||
}
|
||||
|
||||
static inline bool isempty(const char *p) {
|
||||
|
@ -137,7 +137,8 @@ int get_user_creds(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
|
||||
if (synthesize_nobody() &&
|
||||
STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
|
||||
*username = NOBODY_USER_NAME;
|
||||
|
||||
if (uid)
|
||||
@ -243,7 +244,8 @@ int get_group_creds(const char **groupname, gid_t *gid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
|
||||
if (synthesize_nobody() &&
|
||||
STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
|
||||
*groupname = NOBODY_GROUP_NAME;
|
||||
|
||||
if (gid)
|
||||
@ -283,7 +285,8 @@ char* uid_to_name(uid_t uid) {
|
||||
/* Shortcut things to avoid NSS lookups */
|
||||
if (uid == 0)
|
||||
return strdup("root");
|
||||
if (uid == UID_NOBODY)
|
||||
if (synthesize_nobody() &&
|
||||
uid == UID_NOBODY)
|
||||
return strdup(NOBODY_USER_NAME);
|
||||
|
||||
if (uid_is_valid(uid)) {
|
||||
@ -323,7 +326,8 @@ char* gid_to_name(gid_t gid) {
|
||||
|
||||
if (gid == 0)
|
||||
return strdup("root");
|
||||
if (gid == GID_NOBODY)
|
||||
if (synthesize_nobody() &&
|
||||
gid == GID_NOBODY)
|
||||
return strdup(NOBODY_GROUP_NAME);
|
||||
|
||||
if (gid_is_valid(gid)) {
|
||||
@ -427,7 +431,8 @@ int get_home_dir(char **_h) {
|
||||
*_h = h;
|
||||
return 0;
|
||||
}
|
||||
if (u == UID_NOBODY) {
|
||||
if (synthesize_nobody() &&
|
||||
u == UID_NOBODY) {
|
||||
h = strdup("/");
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
@ -482,7 +487,8 @@ int get_shell(char **_s) {
|
||||
*_s = s;
|
||||
return 0;
|
||||
}
|
||||
if (u == UID_NOBODY) {
|
||||
if (synthesize_nobody() &&
|
||||
u == UID_NOBODY) {
|
||||
s = strdup("/sbin/nologin");
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
@ -690,3 +696,24 @@ int maybe_setgroups(size_t size, const gid_t *list) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool synthesize_nobody(void) {
|
||||
|
||||
#ifdef NOLEGACY
|
||||
return true;
|
||||
#else
|
||||
/* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by
|
||||
* touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems
|
||||
* that used the "nobody" user name and group name for other UIDs/GIDs than 65534.
|
||||
*
|
||||
* Note that we do not employ any kind of synchronization on the following caching variable. If the variable is
|
||||
* accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that
|
||||
* shouldn't matter as each initialization should come to the same result. */
|
||||
static int cache = -1;
|
||||
|
||||
if (cache < 0)
|
||||
cache = access("/etc/systemd/dont-synthesize-nobody", F_OK) < 0;
|
||||
|
||||
return cache;
|
||||
#endif
|
||||
}
|
||||
|
@ -97,3 +97,5 @@ bool valid_gecos(const char *d);
|
||||
bool valid_home(const char *p);
|
||||
|
||||
int maybe_setgroups(size_t size, const gid_t *list);
|
||||
|
||||
bool synthesize_nobody(void);
|
||||
|
@ -618,7 +618,13 @@ int str_verscmp(const char *s1, const char *s2) {
|
||||
}
|
||||
|
||||
/* Turn off core dumps but only if we're running outside of a container. */
|
||||
void disable_core_dumps(void) {
|
||||
if (detect_container() <= 0)
|
||||
(void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
|
||||
void disable_coredumps(void) {
|
||||
int r;
|
||||
|
||||
if (detect_container() > 0)
|
||||
return;
|
||||
|
||||
r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
|
||||
}
|
||||
|
@ -192,4 +192,4 @@ int version(void);
|
||||
|
||||
int str_verscmp(const char *s1, const char *s2);
|
||||
|
||||
void disable_core_dumps(void);
|
||||
void disable_coredumps(void);
|
||||
|
@ -306,8 +306,7 @@ void job_dump(Job *j, FILE*f, const char *prefix) {
|
||||
assert(j);
|
||||
assert(f);
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
prefix = strempty(prefix);
|
||||
|
||||
fprintf(f,
|
||||
"%s-> Job %u:\n"
|
||||
|
@ -34,8 +34,7 @@ void kill_context_init(KillContext *c) {
|
||||
void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {
|
||||
assert(c);
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
prefix = strempty(prefix);
|
||||
|
||||
fprintf(f,
|
||||
"%sKillMode: %s\n"
|
||||
|
@ -1607,7 +1607,7 @@ static void initialize_coredump(bool skip_setup) {
|
||||
/* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
|
||||
* until the systemd-coredump tool is enabled via sysctl. */
|
||||
if (!skip_setup)
|
||||
disable_core_dumps();
|
||||
disable_coredumps();
|
||||
}
|
||||
|
||||
static void do_reexecute(
|
||||
|
@ -513,23 +513,31 @@ static int manager_setup_signals(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void manager_clean_environment(Manager *m) {
|
||||
static void manager_sanitize_environment(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
/* Let's remove some environment variables that we
|
||||
* need ourselves to communicate with our clients */
|
||||
/* Let's remove some environment variables that we need ourselves to communicate with our clients */
|
||||
strv_env_unset_many(
|
||||
m->environment,
|
||||
"NOTIFY_SOCKET",
|
||||
"EXIT_CODE",
|
||||
"EXIT_STATUS",
|
||||
"INVOCATION_ID",
|
||||
"JOURNAL_STREAM",
|
||||
"LISTEN_FDNAMES",
|
||||
"LISTEN_FDS",
|
||||
"LISTEN_PID",
|
||||
"MAINPID",
|
||||
"MANAGERPID",
|
||||
"LISTEN_PID",
|
||||
"LISTEN_FDS",
|
||||
"LISTEN_FDNAMES",
|
||||
"NOTIFY_SOCKET",
|
||||
"REMOTE_ADDR",
|
||||
"REMOTE_PORT",
|
||||
"SERVICE_RESULT",
|
||||
"WATCHDOG_PID",
|
||||
"WATCHDOG_USEC",
|
||||
"INVOCATION_ID",
|
||||
NULL);
|
||||
|
||||
/* Let's order the environment alphabetically, just to make it pretty */
|
||||
strv_sort(m->environment);
|
||||
}
|
||||
|
||||
static int manager_default_environment(Manager *m) {
|
||||
@ -556,8 +564,7 @@ static int manager_default_environment(Manager *m) {
|
||||
if (!m->environment)
|
||||
return -ENOMEM;
|
||||
|
||||
manager_clean_environment(m);
|
||||
strv_sort(m->environment);
|
||||
manager_sanitize_environment(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3308,8 +3315,7 @@ int manager_environment_add(Manager *m, char **minus, char **plus) {
|
||||
strv_free(b);
|
||||
|
||||
m->environment = l;
|
||||
manager_clean_environment(m);
|
||||
strv_sort(m->environment);
|
||||
manager_sanitize_environment(m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -333,8 +333,7 @@ int main(int argc, char *argv[]) {
|
||||
if (!in_container)
|
||||
sync_with_progress();
|
||||
|
||||
/* Prevent coredumps */
|
||||
disable_core_dumps();
|
||||
disable_coredumps();
|
||||
|
||||
log_info("Sending SIGTERM to remaining processes...");
|
||||
broadcast_signal(SIGTERM, true, true, arg_timeout);
|
||||
|
@ -1126,7 +1126,7 @@ static int gather_pid_metadata(
|
||||
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */
|
||||
if (is_pid1_crash((const char**) context)) {
|
||||
log_notice("Due to PID 1 having crashed coredump collection will now be turned off.");
|
||||
disable_core_dumps();
|
||||
disable_coredumps();
|
||||
}
|
||||
|
||||
set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
|
||||
|
@ -418,8 +418,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
|
||||
|
||||
fd_inc_sndbuf(fd, SNDBUF_SIZE);
|
||||
|
||||
if (!identifier)
|
||||
identifier = "";
|
||||
identifier = strempty(identifier);
|
||||
|
||||
l = strlen(identifier);
|
||||
header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
|
||||
|
@ -136,7 +136,8 @@ enum nss_status _nss_systemd_getpwnam_r(
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
if (streq(name, nobody_passwd.pw_name)) {
|
||||
if (synthesize_nobody() &&
|
||||
streq(name, nobody_passwd.pw_name)) {
|
||||
*pwd = nobody_passwd;
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@ -244,7 +245,8 @@ enum nss_status _nss_systemd_getpwuid_r(
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
if (uid == nobody_passwd.pw_uid) {
|
||||
if (synthesize_nobody() &&
|
||||
uid == nobody_passwd.pw_uid) {
|
||||
*pwd = nobody_passwd;
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@ -351,7 +353,8 @@ enum nss_status _nss_systemd_getgrnam_r(
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
if (streq(name, nobody_group.gr_name)) {
|
||||
if (synthesize_nobody() &&
|
||||
streq(name, nobody_group.gr_name)) {
|
||||
*gr = nobody_group;
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@ -456,7 +459,8 @@ enum nss_status _nss_systemd_getgrgid_r(
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
if (gid == nobody_group.gr_gid) {
|
||||
if (synthesize_nobody() &&
|
||||
gid == nobody_group.gr_gid) {
|
||||
*gr = nobody_group;
|
||||
*errnop = 0;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
|
@ -653,8 +653,7 @@ void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_
|
||||
assert(c);
|
||||
assert(f);
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
prefix = strempty(prefix);
|
||||
|
||||
fprintf(f,
|
||||
"%s\t%s: %s%s%s %s\n",
|
||||
|
@ -375,35 +375,47 @@ static struct Item* find_glob(OrderedHashmap *h, const char *match) {
|
||||
|
||||
static void load_unix_sockets(void) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
char line[LINE_MAX];
|
||||
int r;
|
||||
|
||||
if (unix_sockets)
|
||||
return;
|
||||
|
||||
/* We maintain a cache of the sockets we found in
|
||||
* /proc/net/unix to speed things up a little. */
|
||||
/* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */
|
||||
|
||||
unix_sockets = set_new(&string_hash_ops);
|
||||
if (!unix_sockets)
|
||||
return;
|
||||
|
||||
f = fopen("/proc/net/unix", "re");
|
||||
if (!f)
|
||||
return;
|
||||
if (!f) {
|
||||
log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
|
||||
"Failed to open /proc/net/unix, ignoring: %m");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Skip header */
|
||||
if (!fgets(line, sizeof(line), f))
|
||||
r = read_line(f, LONG_LINE_MAX, NULL);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to skip /proc/net/unix header line: %m");
|
||||
goto fail;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_warning("Premature end of file reading /proc/net/unix.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
char *p, *s;
|
||||
int k;
|
||||
|
||||
if (!fgets(line, sizeof(line), f))
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to read /proc/net/unix line, ignoring: %m");
|
||||
goto fail;
|
||||
}
|
||||
if (r == 0) /* EOF */
|
||||
break;
|
||||
|
||||
truncate_nl(line);
|
||||
|
||||
p = strchr(line, ':');
|
||||
if (!p)
|
||||
continue;
|
||||
@ -420,21 +432,24 @@ static void load_unix_sockets(void) {
|
||||
continue;
|
||||
|
||||
s = strdup(p);
|
||||
if (!s)
|
||||
if (!s) {
|
||||
log_oom();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
path_kill_slashes(s);
|
||||
|
||||
k = set_consume(unix_sockets, s);
|
||||
if (k < 0 && k != -EEXIST)
|
||||
r = set_consume(unix_sockets, s);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
set_free_free(unix_sockets);
|
||||
unix_sockets = NULL;
|
||||
unix_sockets = set_free_free(unix_sockets);
|
||||
}
|
||||
|
||||
static bool unix_socket_alive(const char *fn) {
|
||||
|
@ -102,8 +102,7 @@ static void get_cap_mask(struct udev_device *dev,
|
||||
unsigned long val;
|
||||
|
||||
v = udev_device_get_sysattr_value(pdev, attr);
|
||||
if (!v)
|
||||
v = "";
|
||||
v = strempty(v);
|
||||
|
||||
xsprintf(text, "%s", v);
|
||||
log_debug("%s raw kernel attribute: %s", attr, text);
|
||||
|
Loading…
x
Reference in New Issue
Block a user