git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] shared repository settings enhancement.

From
Junio C Hamano <junkio@cox.net>
Date
Jun 10, 2006, 00:39 UTC
Message-ID
<7vver9lu8g.fsf_-_@assigned-by-dhcp.cox.net>
In-Reply-To
<7virnam435.fsf@assigned-by-dhcp.cox.net>
This lets you say:
	[core]
		sharedrepository = 075

to allow permission bits on files under $GIT_DIR for OTHER users (not just GROUP users) to be copied from the permission bits of the owner of the file. This is useful for publishing a shared repository over gitweb, when gitweb does not run as a member of the project group and some members have umask too strict for others to read what is created by default. The historical boolean sharedrepository maps to 070 (i.e. if the owner can read or write or execute it, group members can, too).

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * This patch is meant for discussion, not application, as you
   can see there is one big "NEEDSWORK" in builtin-init-db.c.
   Regardless of this enhancement to deal with S_I[RWX]OTH, I
   spotted a couple of places that lack permission adjustment in
   the existing code, which might be worth fixing first.
 builtin-init-db.c |   21 ++++++++++++++++++---
 config.c          |    2 +-
 lockfile.c        |   15 ++++++++++-----
 refs.c            |    5 +++++
 setup.c           |   25 +++++++++++++++++++++++--
 sha1_file.c       |    9 ++++++---
 6 files changed, 63 insertions(+), 14 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 88b39a4..4826c08 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -198,6 +198,11 @@ static void create_default_files(const c
 
 	git_config(git_default_config);
 
+	/* NEEDSWORK: we would have created the above under user's
+	 * umask -- under shared-repository settings, we would need
+	 * to fix them up by scanning under $GIT_DIR here.
+	 */
+
 	/*
 	 * Create the default symlink from ".git/HEAD" to the "master"
 	 * branch, if it does not exist yet.
@@ -248,7 +253,14 @@ int cmd_init_db(int argc, const char **a
 		if (!strncmp(arg, "--template=", 11))
 			template_dir = arg+11;
 		else if (!strcmp(arg, "--shared"))
-			shared_repository = 1;
+			shared_repository = 070; /* might want 075 */
+		else if (!strncmp(arg, "--shared=", 9)) {
+			char *end;
+			long val = strtol(arg+9, &end, 8);
+			if (*end || 077 < val)
+				die("bad option for --shared=");
+			shared_repository = val;
+		}
 		else
 			die(init_db_usage);
 	}
@@ -286,8 +298,11 @@ int cmd_init_db(int argc, const char **a
 	strcpy(path+len, "/info");
 	safe_create_dir(path, 1);
 
-	if (shared_repository)
-		git_config_set("core.sharedrepository", "true");
+	if (shared_repository) {
+		char buf[6];
+		sprintf(buf, "%o", shared_repository);
+		git_config_set("core.sharedrepository", buf);
+	}
 
 	return 0;
 }
diff --git a/config.c b/config.c
index 2ae6153..c474970 100644
--- a/config.c
+++ b/config.c
@@ -536,7 +536,7 @@ int git_config_set_multivar(const char* 
 	 * contents of .git/config will be written into it.
 	 */
 	fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
-	if (fd < 0) {
+	if (fd < 0 || adjust_shared_perm(lock_file)) {
 		fprintf(stderr, "could not lock config file\n");
 		free(store.key);
 		ret = -1;
diff --git a/lockfile.c b/lockfile.c
index 9bc6083..2346e0e 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -27,11 +27,16 @@ int hold_lock_file_for_update(struct loc
 	int fd;
 	sprintf(lk->filename, "%s.lock", path);
 	fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
-	if (fd >=0 && !lk->next) {
-		lk->next = lock_file_list;
-		lock_file_list = lk;
-		signal(SIGINT, remove_lock_file_on_signal);
-		atexit(remove_lock_file);
+	if (0 <= fd) {
+		if (!lk->next) {
+			lk->next = lock_file_list;
+			lock_file_list = lk;
+			signal(SIGINT, remove_lock_file_on_signal);
+			atexit(remove_lock_file);
+		}
+		if (adjust_shared_perm(lk->filename))
+			return error("cannot fix permission bits on %s",
+				     lk->filename);
 	}
 	return fd;
 }
diff --git a/refs.c b/refs.c
index f91b771..713ca46 100644
--- a/refs.c
+++ b/refs.c
@@ -104,6 +104,11 @@ #endif
 		error("Unable to create %s", git_HEAD);
 		return -3;
 	}
+	if (adjust_shared_perm(git_HEAD)) {
+		unlink(lockpath);
+		error("Unable to fix permissions on %s", lockpath);
+		return -4;
+	}
 	return 0;
 }
 
diff --git a/setup.c b/setup.c
index fe7f884..213c596 100644
--- a/setup.c
+++ b/setup.c
@@ -223,8 +223,29 @@ int check_repository_format_version(cons
 {
        if (strcmp(var, "core.repositoryformatversion") == 0)
                repository_format_version = git_config_int(var, value);
-	else if (strcmp(var, "core.sharedrepository") == 0)
-		shared_repository = git_config_bool(var, value);
+       else if (strcmp(var, "core.sharedrepository") == 0) {
+	       /* This is unfortunate, but historically this
+		* variable was bool, and it now takes the umask
+		* to say if we want to keep the same access bits for
+		* the user to group members and others.
+		*/
+	       if (!value)
+		       shared_repository = 070; /* "true" - perhaps 075? */
+	       else if (!*value)
+		       ; /* bool "false" */
+	       else if (!strcasecmp(value, "true"))
+		       shared_repository = 070; /* "true" - perhaps 075? */
+	       else if (!strcasecmp(value, "false"))
+		       ; /* bool "false" */
+	       else if (strchr("01234567", *value)) {
+		       char *end;
+		       long val = strtol(value, &end, 8);
+		       if (*end || 077 < val)
+			       die("bad config value '%s' for '%s'",
+				   value, var);
+		       shared_repository = val;
+	       }
+       }
        return 0;
 }
 
diff --git a/sha1_file.c b/sha1_file.c
index aea0f40..fa19835 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -61,11 +61,14 @@ int adjust_shared_perm(const char *path)
 		return -1;
 	mode = st.st_mode;
 	if (mode & S_IRUSR)
-		mode |= S_IRGRP;
+		mode |= ( ((shared_repository & 040) ? S_IRGRP : 0) |
+			  ((shared_repository & 004) ? S_IROTH : 0) );
 	if (mode & S_IWUSR)
-		mode |= S_IWGRP;
+		mode |= ( ((shared_repository & 020) ? S_IWGRP : 0) |
+			  ((shared_repository & 002) ? S_IWOTH : 0) );
 	if (mode & S_IXUSR)
-		mode |= S_IXGRP;
+		mode |= ( ((shared_repository & 010) ? S_IXGRP : 0) |
+			  ((shared_repository & 001) ? S_IXOTH : 0) );
 	if (S_ISDIR(mode))
 		mode |= S_ISGID;
 	if (chmod(path, mode) < 0)
-- 
1.4.0.rc2.g55be
Previous: Rene ScharfeNext: Linus Torvalds
Message 5 of 14 in “RE: Git-daemon messing up permissions for gitweb”
  1. Post, Mark KJun 9, 2006
  2. Junio C HamanoJun 9, 2006
  3. Retire SIMPLE_*** stuff.Junio C Hamano, Jun 10, 2006
  4. Built-in git-get-tar-commit-id (was: [PATCH/RFC] Retire SIMPLE_*** stuff.)Rene Scharfe, Jun 10, 2006
  5. shared repository settings enhancement.Junio C Hamano, Jun 10, 2006
  6. Linus TorvaldsJun 10, 2006
  7. Jakub NarebskiJun 10, 2006
  8. Junio C HamanoJun 10, 2006
  9. Linus TorvaldsJun 10, 2006
  10. Junio C HamanoJun 10, 2006
  11. Linus TorvaldsJun 10, 2006
  12. Alex RiesenJun 10, 2006
  13. Linus TorvaldsJun 10, 2006
  14. Alex RiesenJun 10, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.