diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-12-16 04:59:31 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-12-16 04:59:31 +0100 |
commit | 2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2 (patch) | |
tree | ee79409a34b1f30d7323bb68064aed7183b0e0a6 /src/shared | |
parent | 213298fb822258bb69c6b85b7c8d7f019fd2306a (diff) |
core: refuse doing %h, %s, %U specifier resolving in PID 1
These specifiers require NSS lookups to work, and we really shouldn't do
them from PID 1 hence. With this change they are now only supported for
user systemd instance, or when the configured user for a unit is root.
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/util.c | 51 | ||||
-rw-r--r-- | src/shared/util.h | 1 |
2 files changed, 50 insertions, 2 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index b5ffaa1c3c..20aec2a5c9 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5220,10 +5220,10 @@ int make_console_stdio(void) { } int get_home_dir(char **_h) { - char *h; + struct passwd *p; const char *e; + char *h; uid_t u; - struct passwd *p; assert(_h); @@ -5266,6 +5266,53 @@ int get_home_dir(char **_h) { return 0; } +int get_shell(char **_s) { + struct passwd *p; + const char *e; + char *s; + uid_t u; + + assert(_s); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + s = strdup(e); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + s = strdup("/bin/sh"); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + s = strdup(p->pw_shell); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; +} + bool filename_is_safe(const char *p) { if (isempty(p)) diff --git a/src/shared/util.h b/src/shared/util.h index d5fa81c6a5..6fc77808d4 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -552,6 +552,7 @@ bool in_initrd(void); void warn_melody(void); int get_home_dir(char **ret); +int get_shell(char **_ret); static inline void freep(void *p) { free(*(void**) p); |