tCheck $HOME and home dir of $USER before getpwuid()->pw_dir - surf - customized build of surf, the suckless webkit browser
 (HTM) git clone git://src.adamsgaard.dk/surf
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit cee8f0186ce3277add9b6a8ac07588be40f0f080
 (DIR) parent 3530d18d8ed04710d5e5a0bfbf6af948c59549bf
 (HTM) Author: Dmitry Bogatov <KAction@gnu.org>
       Date:   Sun, 29 May 2016 11:56:51 +0200
       
       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>
       
       Diffstat:
         M surf.c                              |      43 ++++++++++++++++++++++++++-----
       
       1 file changed, 36 insertions(+), 7 deletions(-)
       ---
 (DIR) diff --git a/surf.c b/surf.c
       t@@ -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);
                }