diff options
author | Dmitry Bogatov <KAction@gnu.org> | 2016-05-29 11:56:51 +0200 |
---|---|---|
committer | Quentin Rameau <quinq@fifth.space> | 2016-07-05 13:01:56 +0200 |
commit | cee8f0186ce3277add9b6a8ac07588be40f0f080 (patch) | |
tree | 237d094d90ca3497343b179e7a4d8c91b8f0e101 | |
parent | 3530d18d8ed04710d5e5a0bfbf6af948c59549bf (diff) | |
download | surf-cee8f0186ce3277add9b6a8ac07588be40f0f080.tar.gz surf-cee8f0186ce3277add9b6a8ac07588be40f0f080.tar.bz2 surf-cee8f0186ce3277add9b6a8ac07588be40f0f080.zip |
Check $HOME and home dir of $USER before getpwuid()->pw_dir
getpwnam(3) recommends to use $HOME instead of getpwuid()->pw_dir,
as it allows users to point programs to a different path.
Using getpwuid() also breaks namespaces-related use cases,
like `unshare -r`.
Patch was submitted by Dmitry Bogatov on the Debian bug tracker:
https://bugs.debian.org/825397
Signed-off-by: Christoph Lohmann <20h@r-36.net>
-rw-r--r-- | surf.c | 43 |
1 files changed, 36 insertions, 7 deletions
@@ -350,29 +350,58 @@ buildfile(const char *path) return fpath; } +static const char* +get_user_homedir(const char *user) { + struct passwd *pw = getpwnam(user); + if (!pw) { + die("Can't get user `%s' home directory.\n", user); + } + return pw->pw_dir; +} + +static const char* +get_current_user_homedir() { + const char *homedir; + const char *user; + struct passwd *pw; + + homedir = getenv("HOME"); + if (homedir) { + return homedir; + } + + user = getenv("USER"); + if (user) { + return get_user_homedir(user); + } + + pw = getpwuid(getuid()); + if (!pw) { + die("Can't get current user home directory\n"); + } + return pw->pw_dir; +} + char * buildpath(const char *path) { - struct passwd *pw; char *apath, *name, *p, *fpath; if (path[0] == '~') { + const char *homedir; if (path[1] == '/' || path[1] == '\0') { p = (char *)&path[1]; - pw = getpwuid(getuid()); + homedir = get_current_user_homedir(); } else { if ((p = strchr(path, '/'))) name = g_strndup(&path[1], --p - path); else name = g_strdup(&path[1]); - if (!(pw = getpwnam(name))) { - die("Can't get user %s home directory: %s.\n", - name, path); - } + homedir = get_user_homedir(name); g_free(name); } - apath = g_build_filename(pw->pw_dir, p, NULL); + apath = g_build_filename(homedir, p, NULL); } else { apath = g_strdup(path); } |