From: Junio C Hamano Date: Mon, 10 Jun 2013 00:06:55 +0000 (-0700) Subject: Merge branch 'jn/config-ignore-inaccessible' into maint X-Git-Tag: v1.8.3.1~2 X-Git-Url: https://www.git.lorimer.id.au/gitweb.git/diff_plain/b1c418e155a86a1a6104c20e5424d847e516c8d7?hp=fd500302096b5b4e45d78c14d6ea9a704f556a16 Merge branch 'jn/config-ignore-inaccessible' into maint 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 --- diff --git a/builtin/config.c b/builtin/config.c index 33c9bf9d84..19ffcaf187 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -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; diff --git a/config.c b/config.c index aefd80b12a..830ee14b43 100644 --- 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 13858fefa5..897c87403e 100644 --- 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); } diff --git a/git-compat-util.h b/git-compat-util.h index e955bb5e8b..c1f8a477fb 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -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); diff --git a/wrapper.c b/wrapper.c index bac59d2c41..dd7ecbb115 100644 --- 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; }