Merge branch 'jc/shared-literally' into maint
* jc/shared-literally: t1301: loosen test for forced modes set_shared_perm(): sometimes we know what the final mode bits should look like move_temp_to_file(): do not forget to chmod() in "Coda hack" codepath Move chmod(foo, 0444) into move_temp_to_file() "core.sharedrepository = 0mode" should set, not loosen
This commit is contained in:
commit
bff82d0cda
@ -195,6 +195,8 @@ static int create_default_files(const char *template_path)
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
is_bare_repository_cfg = init_is_bare_repository;
|
||||
|
||||
/* reading existing config may have overwrote it */
|
||||
if (init_shared_repository != -1)
|
||||
shared_repository = init_shared_repository;
|
||||
|
||||
@ -313,12 +315,15 @@ int init_db(const char *template_dir, unsigned int flags)
|
||||
* and compatibility values for PERM_GROUP and
|
||||
* PERM_EVERYBODY.
|
||||
*/
|
||||
if (shared_repository == PERM_GROUP)
|
||||
if (shared_repository < 0)
|
||||
/* force to the mode value */
|
||||
sprintf(buf, "0%o", -shared_repository);
|
||||
else if (shared_repository == PERM_GROUP)
|
||||
sprintf(buf, "%d", OLD_PERM_GROUP);
|
||||
else if (shared_repository == PERM_EVERYBODY)
|
||||
sprintf(buf, "%d", OLD_PERM_EVERYBODY);
|
||||
else
|
||||
sprintf(buf, "0%o", shared_repository);
|
||||
die("oops");
|
||||
git_config_set("core.sharedrepository", buf);
|
||||
git_config_set("receive.denyNonFastforwards", "true");
|
||||
}
|
||||
@ -398,6 +403,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
usage(init_db_usage);
|
||||
}
|
||||
|
||||
if (init_shared_repository != -1)
|
||||
shared_repository = init_shared_repository;
|
||||
|
||||
/*
|
||||
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
|
||||
* without --bare. Catch the error early.
|
||||
|
3
cache.h
3
cache.h
@ -613,7 +613,8 @@ enum sharedrepo {
|
||||
PERM_EVERYBODY = 0664,
|
||||
};
|
||||
int git_config_perm(const char *var, const char *value);
|
||||
int adjust_shared_perm(const char *path);
|
||||
int set_shared_perm(const char *path, int mode);
|
||||
#define adjust_shared_perm(path) set_shared_perm((path), 0)
|
||||
int safe_create_leading_directories(char *path);
|
||||
int safe_create_leading_directories_const(const char *path);
|
||||
char *enter_repo(char *path, int strict);
|
||||
|
@ -902,9 +902,6 @@ static char *keep_pack(char *curr_index_name)
|
||||
static const char *keep_msg = "fast-import";
|
||||
int keep_fd;
|
||||
|
||||
chmod(pack_data->pack_name, 0444);
|
||||
chmod(curr_index_name, 0444);
|
||||
|
||||
keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
|
||||
if (keep_fd < 0)
|
||||
die("cannot create keep file");
|
||||
|
@ -748,7 +748,6 @@ static void finish_request(struct transfer_request *request)
|
||||
aborted = 1;
|
||||
}
|
||||
} else if (request->state == RUN_FETCH_LOOSE) {
|
||||
fchmod(request->local_fileno, 0444);
|
||||
close(request->local_fileno); request->local_fileno = -1;
|
||||
|
||||
if (request->curl_result != CURLE_OK &&
|
||||
|
@ -231,7 +231,6 @@ static void finish_object_request(struct object_request *obj_req)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
fchmod(obj_req->local, 0444);
|
||||
close(obj_req->local); obj_req->local = -1;
|
||||
|
||||
if (obj_req->http_code == 416) {
|
||||
|
@ -823,8 +823,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
}
|
||||
if (move_temp_to_file(curr_pack_name, final_pack_name))
|
||||
die("cannot store pack file");
|
||||
}
|
||||
if (from_stdin)
|
||||
} else if (from_stdin)
|
||||
chmod(final_pack_name, 0444);
|
||||
|
||||
if (final_index_name != curr_index_name) {
|
||||
@ -835,8 +834,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
}
|
||||
if (move_temp_to_file(curr_index_name, final_index_name))
|
||||
die("cannot store index file");
|
||||
}
|
||||
chmod(final_index_name, 0444);
|
||||
} else
|
||||
chmod(final_index_name, 0444);
|
||||
|
||||
if (!from_stdin) {
|
||||
printf("%s\n", sha1_to_hex(sha1));
|
||||
|
53
path.c
53
path.c
@ -311,36 +311,49 @@ char *enter_repo(char *path, int strict)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int adjust_shared_perm(const char *path)
|
||||
int set_shared_perm(const char *path, int mode)
|
||||
{
|
||||
struct stat st;
|
||||
int mode;
|
||||
int tweak, shared, orig_mode;
|
||||
|
||||
if (!shared_repository)
|
||||
if (!shared_repository) {
|
||||
if (mode)
|
||||
return chmod(path, mode & ~S_IFMT);
|
||||
return 0;
|
||||
if (lstat(path, &st) < 0)
|
||||
return -1;
|
||||
mode = st.st_mode;
|
||||
|
||||
if (shared_repository) {
|
||||
int tweak = shared_repository;
|
||||
if (!(mode & S_IWUSR))
|
||||
tweak &= ~0222;
|
||||
mode |= tweak;
|
||||
} else {
|
||||
/* Preserve old PERM_UMASK behaviour */
|
||||
if (mode & S_IWUSR)
|
||||
mode |= S_IWGRP;
|
||||
}
|
||||
if (!mode) {
|
||||
if (lstat(path, &st) < 0)
|
||||
return -1;
|
||||
mode = st.st_mode;
|
||||
orig_mode = mode;
|
||||
} else
|
||||
orig_mode = 0;
|
||||
if (shared_repository < 0)
|
||||
shared = -shared_repository;
|
||||
else
|
||||
shared = shared_repository;
|
||||
tweak = shared;
|
||||
|
||||
if (!(mode & S_IWUSR))
|
||||
tweak &= ~0222;
|
||||
if (mode & S_IXUSR)
|
||||
/* Copy read bits to execute bits */
|
||||
tweak |= (tweak & 0444) >> 2;
|
||||
if (shared_repository < 0)
|
||||
mode = (mode & ~0777) | tweak;
|
||||
else
|
||||
mode |= tweak;
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
mode |= FORCE_DIR_SET_GID;
|
||||
|
||||
/* Copy read bits to execute bits */
|
||||
mode |= (shared_repository & 0444) >> 2;
|
||||
mode |= (shared & 0444) >> 2;
|
||||
mode |= FORCE_DIR_SET_GID;
|
||||
}
|
||||
|
||||
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
|
||||
if (((shared_repository < 0
|
||||
? (orig_mode & (FORCE_DIR_SET_GID | 0777))
|
||||
: (orig_mode & mode)) != mode) &&
|
||||
chmod(path, (mode & ~S_IFMT)) < 0)
|
||||
return -2;
|
||||
return 0;
|
||||
}
|
||||
|
4
setup.c
4
setup.c
@ -434,7 +434,7 @@ int git_config_perm(const char *var, const char *value)
|
||||
|
||||
/*
|
||||
* Treat values 0, 1 and 2 as compatibility cases, otherwise it is
|
||||
* a chmod value.
|
||||
* a chmod value to restrict to.
|
||||
*/
|
||||
switch (i) {
|
||||
case PERM_UMASK: /* 0 */
|
||||
@ -456,7 +456,7 @@ int git_config_perm(const char *var, const char *value)
|
||||
* Mask filemode value. Others can not get write permission.
|
||||
* x flags for directories are handled separately.
|
||||
*/
|
||||
return i & 0666;
|
||||
return -(i & 0666);
|
||||
}
|
||||
|
||||
int check_repository_format_version(const char *var, const char *value, void *cb)
|
||||
|
14
sha1_file.c
14
sha1_file.c
@ -2216,11 +2216,15 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the just written object into its final resting place
|
||||
* Move the just written object into its final resting place.
|
||||
* NEEDSWORK: this should be renamed to finalize_temp_file() as
|
||||
* "moving" is only a part of what it does, when no patch between
|
||||
* master to pu changes the call sites of this function.
|
||||
*/
|
||||
int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (link(tmpfile, filename))
|
||||
ret = errno;
|
||||
|
||||
@ -2232,12 +2236,12 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
*
|
||||
* The same holds for FAT formatted media.
|
||||
*
|
||||
* When this succeeds, we just return 0. We have nothing
|
||||
* When this succeeds, we just return. We have nothing
|
||||
* left to unlink.
|
||||
*/
|
||||
if (ret && ret != EEXIST) {
|
||||
if (!rename(tmpfile, filename))
|
||||
return 0;
|
||||
goto out;
|
||||
ret = errno;
|
||||
}
|
||||
unlink(tmpfile);
|
||||
@ -2248,6 +2252,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
/* FIXME!!! Collision check here ? */
|
||||
}
|
||||
|
||||
out:
|
||||
if (set_shared_perm(filename, (S_IFREG|0444)))
|
||||
return error("unable to set permission to '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2272,7 +2279,6 @@ static void close_sha1_file(int fd)
|
||||
{
|
||||
if (fsync_object_files)
|
||||
fsync_or_die(fd, "sha1 file");
|
||||
fchmod(fd, 0444);
|
||||
if (close(fd) != 0)
|
||||
die("error when closing sha1 file (%s)", strerror(errno));
|
||||
}
|
||||
|
@ -126,4 +126,41 @@ test_expect_success 'git reflog expire honors core.sharedRepository' '
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success 'forced modes' '
|
||||
mkdir -p templates/hooks &&
|
||||
echo update-server-info >templates/hooks/post-update &&
|
||||
chmod +x templates/hooks/post-update &&
|
||||
echo : >random-file &&
|
||||
mkdir new &&
|
||||
(
|
||||
cd new &&
|
||||
umask 002 &&
|
||||
git init --shared=0660 --template=../templates &&
|
||||
>frotz &&
|
||||
git add frotz &&
|
||||
git commit -a -m initial &&
|
||||
git repack
|
||||
) &&
|
||||
find new/.git -print |
|
||||
xargs ls -ld >actual &&
|
||||
|
||||
# Everything must be unaccessible to others
|
||||
test -z "$(sed -n -e "/^.......---/d" actual)" &&
|
||||
|
||||
# All directories must have either 2770 or 770
|
||||
test -z "$(sed -n -e "/^drwxrw[sx]---/d" -e "/^d/p" actual)" &&
|
||||
|
||||
# post-update hook must be 0770
|
||||
test -z "$(sed -n -e "/post-update/{
|
||||
/^-rwxrwx---/d
|
||||
p
|
||||
}" actual)" &&
|
||||
|
||||
# All files inside objects must be 0440
|
||||
test -z "$(sed -n -e "/objects\//{
|
||||
/^d/d
|
||||
/^-r--r-----/d
|
||||
}" actual)"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user