Skip to content

Commit

Permalink
Merge branch 'jc/shared-literally'
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
gitster committed Apr 6, 2009
2 parents ccc852c + 1b89eaa commit 03a39a9
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 38 deletions.
12 changes: 10 additions & 2 deletions builtin-init-db.c
Expand Up @@ -194,6 +194,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;

Expand Down Expand Up @@ -312,12 +314,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");
}
Expand Down Expand Up @@ -397,6 +402,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.
Expand Down
3 changes: 2 additions & 1 deletion cache.h
Expand Up @@ -623,7 +623,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);
Expand Down
3 changes: 0 additions & 3 deletions fast-import.c
Expand Up @@ -903,9 +903,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");
Expand Down
1 change: 0 additions & 1 deletion http-push.c
Expand Up @@ -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 &&
Expand Down
1 change: 0 additions & 1 deletion http-walker.c
Expand Up @@ -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) {
Expand Down
7 changes: 3 additions & 4 deletions index-pack.c
Expand Up @@ -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) {
Expand All @@ -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));
Expand Down
53 changes: 33 additions & 20 deletions path.c
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions setup.c
Expand Up @@ -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 */
Expand All @@ -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)
Expand Down
14 changes: 10 additions & 4 deletions sha1_file.c
Expand Up @@ -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;

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

Expand All @@ -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));
}
Expand Down
37 changes: 37 additions & 0 deletions t/t1301-shared-repo.sh
Expand Up @@ -126,4 +126,41 @@ test_expect_success POSIXPERM '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

0 comments on commit 03a39a9

Please sign in to comment.