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:
Junio C Hamano 2009-04-08 23:23:41 -07:00
commit bff82d0cda
10 changed files with 97 additions and 38 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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");

View 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 &&

View file

@ -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) {

View file

@ -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
View file

@ -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;
}

View file

@ -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)

View file

@ -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));
}

View file

@ -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