Merge branch 'jn/config-ignore-inaccessible' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Jun 2013 00:06:55 +0000 (17:06 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Jun 2013 00:06:56 +0000 (17:06 -0700)
A git daemon that starts as "root" and then drops privilege often
leaves $HOME set to that of the root user, which is unreadable by
the daemon process, which was diagnosed as a configuration error.

Make per-user configuration files that are inaccessible due to
EACCES as though these files do not exist to avoid this issue, as
the tightening which was originally meant as an additional security
has annoyed enough sysadmins.

* jn/config-ignore-inaccessible:
config: allow inaccessible configuration under $HOME

builtin/config.c
config.c
dir.c
git-compat-util.h
wrapper.c
index 33c9bf9d84f514330f12de5cbd9dfb610a1b16de..19ffcaf18776e8b100ee3f57c7ca7447436c5476 100644 (file)
@@ -379,8 +379,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                         */
                        die("$HOME not set");
 
-               if (access_or_warn(user_config, R_OK) &&
-                   xdg_config && !access_or_warn(xdg_config, R_OK))
+               if (access_or_warn(user_config, R_OK, 0) &&
+                   xdg_config && !access_or_warn(xdg_config, R_OK, 0))
                        given_config_file = xdg_config;
                else
                        given_config_file = user_config;
index aefd80b12a079d4a3c91d43c8a2c33ed6fbd0a38..830ee14b437ca74a3db9e56ea8cedff78b7964b6 100644 (file)
--- a/config.c
+++ b/config.c
@@ -58,7 +58,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc
                path = buf.buf;
        }
 
-       if (!access_or_die(path, R_OK)) {
+       if (!access_or_die(path, R_OK, 0)) {
                if (++inc->depth > MAX_INCLUDE_DEPTH)
                        die(include_depth_advice, MAX_INCLUDE_DEPTH, path,
                            cf && cf->name ? cf->name : "the command line");
@@ -954,23 +954,23 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 
        home_config_paths(&user_config, &xdg_config, "config");
 
-       if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK)) {
+       if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0)) {
                ret += git_config_from_file(fn, git_etc_gitconfig(),
                                            data);
                found += 1;
        }
 
-       if (xdg_config && !access_or_die(xdg_config, R_OK)) {
+       if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK)) {
                ret += git_config_from_file(fn, xdg_config, data);
                found += 1;
        }
 
-       if (user_config && !access_or_die(user_config, R_OK)) {
+       if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK)) {
                ret += git_config_from_file(fn, user_config, data);
                found += 1;
        }
 
-       if (repo_config && !access_or_die(repo_config, R_OK)) {
+       if (repo_config && !access_or_die(repo_config, R_OK, 0)) {
                ret += git_config_from_file(fn, repo_config, data);
                found += 1;
        }
diff --git a/dir.c b/dir.c
index 13858fefa56b2d72f8ce6ce35f6bb8646f11ca81..897c87403e978ab2123ce088cf2d3265e21d7dde 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1545,9 +1545,9 @@ void setup_standard_excludes(struct dir_struct *dir)
                home_config_paths(NULL, &xdg_path, "ignore");
                excludes_file = xdg_path;
        }
-       if (!access_or_warn(path, R_OK))
+       if (!access_or_warn(path, R_OK, 0))
                add_excludes_from_file(dir, path);
-       if (excludes_file && !access_or_warn(excludes_file, R_OK))
+       if (excludes_file && !access_or_warn(excludes_file, R_OK, 0))
                add_excludes_from_file(dir, excludes_file);
 }
 
index e955bb5e8b3101cc8c753cf541beabf5cd037b39..c1f8a477fb96730612e1ddd06294270a4651649f 100644 (file)
@@ -692,8 +692,9 @@ int remove_or_warn(unsigned int mode, const char *path);
  * Call access(2), but warn for any error except "missing file"
  * (ENOENT or ENOTDIR).
  */
-int access_or_warn(const char *path, int mode);
-int access_or_die(const char *path, int mode);
+#define ACCESS_EACCES_OK (1U << 0)
+int access_or_warn(const char *path, int mode, unsigned flag);
+int access_or_die(const char *path, int mode, unsigned flag);
 
 /* Warn on an inaccessible file that ought to be accessible */
 void warn_on_inaccessible(const char *path);
index bac59d2c41bae7441038b30728c696b6280f4c2d..dd7ecbb115edd979f657e2e209126d364e6ccfac 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -408,18 +408,24 @@ void warn_on_inaccessible(const char *path)
        warning(_("unable to access '%s': %s"), path, strerror(errno));
 }
 
-int access_or_warn(const char *path, int mode)
+static int access_error_is_ok(int err, unsigned flag)
+{
+       return err == ENOENT || err == ENOTDIR ||
+               ((flag & ACCESS_EACCES_OK) && err == EACCES);
+}
+
+int access_or_warn(const char *path, int mode, unsigned flag)
 {
        int ret = access(path, mode);
-       if (ret && errno != ENOENT && errno != ENOTDIR)
+       if (ret && !access_error_is_ok(errno, flag))
                warn_on_inaccessible(path);
        return ret;
 }
 
-int access_or_die(const char *path, int mode)
+int access_or_die(const char *path, int mode, unsigned flag)
 {
        int ret = access(path, mode);
-       if (ret && errno != ENOENT && errno != ENOTDIR)
+       if (ret && !access_error_is_ok(errno, flag))
                die_errno(_("unable to access '%s'"), path);
        return ret;
 }