summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/util.c51
-rw-r--r--src/shared/util.h1
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);