{"thread":{"id":"22726","subject":"[PATCH 0/4] Allow Git repositories to be shared using POSIX ACLs","startedAt":"2010-02-19T16:33:23Z","lastAt":"2010-02-22T22:32:16Z","messageCount":18,"participants":["Matthieu Moy","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"135087","messageId":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":null,"subject":"[PATCH 0/4] Allow Git repositories to be shared using POSIX ACLs","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-19T16:33:23Z","receivedAt":"2010-02-19T16:33:23Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"I talked about the problem earlier:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/136720\n\nIn short: if a user wants to share a git repository using POSIX\nfilesystem ACLs, it seems everything works except pack file creation.\nThe problem is that we create the file with a mode 0600, i.e. no\npermission for group, but the semantics of ACL is that this group\npermission is used as ACL umask when the file has ACLs (don't ask me\nwhy, I never understood the rational, but that's how it works).\n\nInstead, if we let the umask do its job at the time of file creation,\nthen the pack file is created with the correct permission bits and\nACLs, and we don't need to chmod it after the fact. This is what this\npatch serie does.\n\nThe test-case is really weak: ideally, we should have a real test with\nseveral users interacting. But that's hardly scriptable in a portable\nway, so the only testcase I added relies on getfacl and \"ls -l\" to find\nout if the result is correct. However, I did some manual testing, and\nas far as I can say, Git works very well with ACLs with this patch.\n"},{"id":"135091","messageId":"1266597207-32036-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 1/4] Add a testcase for ACL with restrictive umask.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-19T16:33:24Z","receivedAt":"2010-02-19T16:33:24Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Right now, Git creates unreadable pack files on non-shared\nrepositories when the user has a umask of 077, even when the default\nACLs for the directory would give read/write access to a specific\nuser.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n t/t1304-default-acl.sh |   49 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 49 insertions(+), 0 deletions(-)\n create mode 100755 t/t1304-default-acl.sh\n\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nnew file mode 100755\nindex 0000000..4ee44a1\n--- /dev/null\n+++ b/t/t1304-default-acl.sh\n@@ -0,0 +1,49 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2010 Matthieu Moy\n+#\n+\n+test_description='Test repository with default ACL'\n+\n+. ./test-lib.sh\n+\n+# We need an arbitrary other user give permission to using ACLs. root\n+# is a good candidate: exists on all unices, and it has permission\n+# anyway, so we don't create a security hole running the testsuite.\n+\n+if ! setfacl -Rm u:root:rwx .; then\n+    say \"Skipping ACL tests: unable to use setfacl\"\n+    test_done\n+fi\n+\n+setfacl -Rm d:u:\"$LOGNAME\":rwx .\n+setfacl -Rm d:u:root:rwx .\n+\n+touch file.txt\n+git add file.txt\n+git commit -m \"init\"\n+\n+modebits () {\n+\tls -l \"$1\" | sed -e 's|^\\(..........\\).*|\\1|'\n+}\n+\n+test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n+\tumask 077 &&\n+\tgit gc &&\n+\tactual=$(modebits .git/objects/pack/*.pack) &&\n+\tcase \"$actual\" in\n+\t-r--r-----*)\n+\t\t: happy\n+\t\t;;\n+\t*)\n+\t\tfalse\n+\t\t;;\n+\tesac &&\n+\tgetfacl .git/objects/pack/*.pack > actual &&\n+\tgrep -q \"user:root:rwx\" actual &&\n+\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n+\tgrep -q \"mask::r--\" actual &&\n+\tgrep -q \"group::---\" actual\n+'\n+\n+test_done\n-- \n1.7.0.rc2.4.gc602c4\n"},{"id":"135090","messageId":"1266597207-32036-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 2/4] Move gitmkstemps to path.c","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-19T16:33:25Z","receivedAt":"2010-02-19T16:33:25Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This function used to be only a compatibility function, but we're\ngoing to extend it and actually use it, so make it part of Git.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Makefile          |    1 -\n compat/mkstemps.c |   70 -----------------------------------------------------\n path.c            |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 69 insertions(+), 71 deletions(-)\n delete mode 100644 compat/mkstemps.c\n\ndiff --git a/Makefile b/Makefile\nindex 7bf2fca..4387d42 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1200,7 +1200,6 @@ ifdef NO_MKDTEMP\n endif\n ifdef NO_MKSTEMPS\n \tCOMPAT_CFLAGS += -DNO_MKSTEMPS\n-\tCOMPAT_OBJS += compat/mkstemps.o\n endif\n ifdef NO_UNSETENV\n \tCOMPAT_CFLAGS += -DNO_UNSETENV\ndiff --git a/compat/mkstemps.c b/compat/mkstemps.c\ndeleted file mode 100644\nindex 14179c8..0000000\n--- a/compat/mkstemps.c\n+++ /dev/null\n@@ -1,70 +0,0 @@\n-#include \"../git-compat-util.h\"\n-\n-/* Adapted from libiberty's mkstemp.c. */\n-\n-#undef TMP_MAX\n-#define TMP_MAX 16384\n-\n-int gitmkstemps(char *pattern, int suffix_len)\n-{\n-\tstatic const char letters[] =\n-\t\t\"abcdefghijklmnopqrstuvwxyz\"\n-\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n-\t\t\"0123456789\";\n-\tstatic const int num_letters = 62;\n-\tuint64_t value;\n-\tstruct timeval tv;\n-\tchar *template;\n-\tsize_t len;\n-\tint fd, count;\n-\n-\tlen = strlen(pattern);\n-\n-\tif (len < 6 + suffix_len) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\t/*\n-\t * Replace pattern's XXXXXX characters with randomness.\n-\t * Try TMP_MAX different filenames.\n-\t */\n-\tgettimeofday(&tv, NULL);\n-\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n-\ttemplate = &pattern[len - 6 - suffix_len];\n-\tfor (count = 0; count < TMP_MAX; ++count) {\n-\t\tuint64_t v = value;\n-\t\t/* Fill in the random bits. */\n-\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n-\n-\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n-\t\tif (fd > 0)\n-\t\t\treturn fd;\n-\t\t/*\n-\t\t * Fatal error (EPERM, ENOSPC etc).\n-\t\t * It doesn't make sense to loop.\n-\t\t */\n-\t\tif (errno != EEXIST)\n-\t\t\tbreak;\n-\t\t/*\n-\t\t * This is a random value.  It is only necessary that\n-\t\t * the next TMP_MAX values generated by adding 7777 to\n-\t\t * VALUE are different with (module 2^32).\n-\t\t */\n-\t\tvalue += 7777;\n-\t}\n-\t/* We return the null string if we can't find a unique file name.  */\n-\tpattern[0] = '\\0';\n-\terrno = EINVAL;\n-\treturn -1;\n-}\ndiff --git a/path.c b/path.c\nindex d1fccbd..60f5b78 100644\n--- a/path.c\n+++ b/path.c\n@@ -157,6 +157,75 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n \treturn mkstemps(path, suffix_len);\n }\n \n+/* Adapted from libiberty's mkstemp.c. */\n+\n+#undef TMP_MAX\n+#define TMP_MAX 16384\n+\n+int gitmkstemps(char *pattern, int suffix_len)\n+{\n+\tstatic const char letters[] =\n+\t\t\"abcdefghijklmnopqrstuvwxyz\"\n+\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n+\t\t\"0123456789\";\n+\tstatic const int num_letters = 62;\n+\tuint64_t value;\n+\tstruct timeval tv;\n+\tchar *template;\n+\tsize_t len;\n+\tint fd, count;\n+\n+\tlen = strlen(pattern);\n+\n+\tif (len < 6 + suffix_len) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * Replace pattern's XXXXXX characters with randomness.\n+\t * Try TMP_MAX different filenames.\n+\t */\n+\tgettimeofday(&tv, NULL);\n+\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n+\ttemplate = &pattern[len - 6 - suffix_len];\n+\tfor (count = 0; count < TMP_MAX; ++count) {\n+\t\tuint64_t v = value;\n+\t\t/* Fill in the random bits. */\n+\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n+\n+\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n+\t\tif (fd > 0)\n+\t\t\treturn fd;\n+\t\t/*\n+\t\t * Fatal error (EPERM, ENOSPC etc).\n+\t\t * It doesn't make sense to loop.\n+\t\t */\n+\t\tif (errno != EEXIST)\n+\t\t\tbreak;\n+\t\t/*\n+\t\t * This is a random value.  It is only necessary that\n+\t\t * the next TMP_MAX values generated by adding 7777 to\n+\t\t * VALUE are different with (module 2^32).\n+\t\t */\n+\t\tvalue += 7777;\n+\t}\n+\t/* We return the null string if we can't find a unique file name.  */\n+\tpattern[0] = '\\0';\n+\terrno = EINVAL;\n+\treturn -1;\n+}\n+\n int validate_headref(const char *path)\n {\n \tstruct stat st;\n-- \n1.7.0.rc2.4.gc602c4\n"},{"id":"135089","messageId":"1266597207-32036-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 3/4] git_mkstemp_mode, xmkstemp_mode: variants of gitmkstemps with mode argument.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-19T16:33:26Z","receivedAt":"2010-02-19T16:33:26Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"gitmkstemps emulates the behavior of mkstemps, which is usually used\nto create files in a shared directory like /tmp/, hence, it creates\nfiles with permission 0600. But we use it also to create pack files,\nwhich do not need this protection.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n cache.h   |    4 ++++\n path.c    |   16 ++++++++++++++--\n wrapper.c |   10 ++++++++++\n 3 files changed, 28 insertions(+), 2 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex d478eff..0319637 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -641,6 +641,10 @@ int git_mkstemp(char *path, size_t n, const char *template);\n \n int git_mkstemps(char *path, size_t n, const char *template, int suffix_len);\n \n+/* set default permissions by passing mode arguments to open(2) */\n+int git_mkstemps_mode(char *pattern, int suffix_len, int mode);\n+int git_mkstemp_mode(char *pattern, int mode);\n+\n /*\n  * NOTE NOTE NOTE!!\n  *\ndiff --git a/path.c b/path.c\nindex 60f5b78..005b836 100644\n--- a/path.c\n+++ b/path.c\n@@ -162,7 +162,7 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n #undef TMP_MAX\n #define TMP_MAX 16384\n \n-int gitmkstemps(char *pattern, int suffix_len)\n+int git_mkstemps_mode(char *pattern, int suffix_len, int mode)\n {\n \tstatic const char letters[] =\n \t\t\"abcdefghijklmnopqrstuvwxyz\"\n@@ -204,7 +204,7 @@ int gitmkstemps(char *pattern, int suffix_len)\n \t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n \t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n \n-\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n+\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);\n \t\tif (fd > 0)\n \t\t\treturn fd;\n \t\t/*\n@@ -226,6 +226,17 @@ int gitmkstemps(char *pattern, int suffix_len)\n \treturn -1;\n }\n \n+int git_mkstemp_mode(char *pattern, int mode)\n+{\n+\t/* mkstemp is just mkstemps with no suffix */\n+\treturn git_mkstemps_mode(pattern, 0, mode);\n+}\n+\n+int gitmkstemps(char *pattern, int suffix_len)\n+{\n+\treturn git_mkstemps_mode(pattern, suffix_len, 0600);\n+}\n+\n int validate_headref(const char *path)\n {\n \tstruct stat st;\n@@ -718,3 +729,4 @@ int daemon_avoid_alias(const char *p)\n \t\t}\n \t}\n }\n+\ndiff --git a/wrapper.c b/wrapper.c\nindex 0e3e20a..673762f 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -204,6 +204,16 @@ int xmkstemp(char *template)\n \treturn fd;\n }\n \n+int xmkstemp_mode(char *template, int mode)\n+{\n+\tint fd;\n+\n+\tfd = git_mkstemp_mode(template, mode);\n+\tif (fd < 0)\n+\t\tdie_errno(\"Unable to create temporary file\");\n+\treturn fd;\n+}\n+\n /*\n  * zlib wrappers to make sure we don't silently miss errors\n  * at init time.\n-- \n1.7.0.rc2.4.gc602c4\n"},{"id":"135092","messageId":"1266597207-32036-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-19T16:33:27Z","receivedAt":"2010-02-19T16:33:27Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"We used to create 0600 files, and then use chmod to set the group and\nother permission bits to the umask. This usually has the same effect\nas a normal file creation with a umask.\n\nBut in the presence of ACLs, the group permission plays the role of\nthe ACL mask: the \"g\" bits of newly created files are chosen according\nto default ACL mask of the directory, not according to the umask, and\ndoing a chmod() on these \"g\" bits affect the ACL's mask instead of\nactual group permission.\n\nIn other words, creating files with 0600 and then doing a chmod to the\numask creates files which are unreadable by users allowed in the\ndefault ACL. To create the files without breaking ACLs, we let the\numask do it's job at the file's creation time, and get rid of the\nlater chmod.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n builtin-pack-objects.c |   18 ++----------------\n t/t1304-default-acl.sh |    2 +-\n wrapper.c              |   10 +++++++---\n 3 files changed, 10 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex e1d3adf..539e75d 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -464,9 +464,6 @@ static int write_one(struct sha1file *f,\n \treturn 1;\n }\n \n-/* forward declaration for write_pack_file */\n-static int adjust_perm(const char *path, mode_t mode);\n-\n static void write_pack_file(void)\n {\n \tuint32_t i = 0, j;\n@@ -523,21 +520,17 @@ static void write_pack_file(void)\n \t\t}\n \n \t\tif (!pack_to_stdout) {\n-\t\t\tmode_t mode = umask(0);\n \t\t\tstruct stat st;\n \t\t\tconst char *idx_tmp_name;\n \t\t\tchar tmpname[PATH_MAX];\n \n-\t\t\tumask(mode);\n-\t\t\tmode = 0444 & ~mode;\n-\n \t\t\tidx_tmp_name = write_idx_file(NULL, written_list,\n \t\t\t\t\t\t      nr_written, sha1);\n \n \t\t\tsnprintf(tmpname, sizeof(tmpname), \"%s-%s.pack\",\n \t\t\t\t base_name, sha1_to_hex(sha1));\n \t\t\tfree_pack_by_name(tmpname);\n-\t\t\tif (adjust_perm(pack_tmp_name, mode))\n+\t\t\tif (adjust_shared_perm(pack_tmp_name))\n \t\t\t\tdie_errno(\"unable to make temporary pack file readable\");\n \t\t\tif (rename(pack_tmp_name, tmpname))\n \t\t\t\tdie_errno(\"unable to rename temporary pack file\");\n@@ -565,7 +558,7 @@ static void write_pack_file(void)\n \n \t\t\tsnprintf(tmpname, sizeof(tmpname), \"%s-%s.idx\",\n \t\t\t\t base_name, sha1_to_hex(sha1));\n-\t\t\tif (adjust_perm(idx_tmp_name, mode))\n+\t\t\tif (adjust_shared_perm(idx_tmp_name))\n \t\t\t\tdie_errno(\"unable to make temporary index file readable\");\n \t\t\tif (rename(idx_tmp_name, tmpname))\n \t\t\t\tdie_errno(\"unable to rename temporary index file\");\n@@ -2125,13 +2118,6 @@ static void get_object_list(int ac, const char **av)\n \t\tloosen_unused_packed_objects(&revs);\n }\n \n-static int adjust_perm(const char *path, mode_t mode)\n-{\n-\tif (chmod(path, mode))\n-\t\treturn -1;\n-\treturn adjust_shared_perm(path);\n-}\n-\n int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n {\n \tint use_internal_rev_list = 0;\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex 4ee44a1..b8e9c34 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -27,7 +27,7 @@ modebits () {\n \tls -l \"$1\" | sed -e 's|^\\(..........\\).*|\\1|'\n }\n \n-test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n+test_expect_success 'git gc does not break ACLs with restrictive umask' '\n \tumask 077 &&\n \tgit gc &&\n \tactual=$(modebits .git/objects/pack/*.pack) &&\ndiff --git a/wrapper.c b/wrapper.c\nindex 673762f..b2c784d 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -277,10 +277,14 @@ int git_inflate(z_streamp strm, int flush)\n int odb_mkstemp(char *template, size_t limit, const char *pattern)\n {\n \tint fd;\n-\n+\t/*\n+\t * we let the umask do it's job, don't try to be more\n+\t * restrictive.\n+\t */\n+\tint mode = 0666;\n \tsnprintf(template, limit, \"%s/%s\",\n \t\t get_object_directory(), pattern);\n-\tfd = mkstemp(template);\n+\tfd = git_mkstemp_mode(template, mode);\n \tif (0 <= fd)\n \t\treturn fd;\n \n@@ -289,7 +293,7 @@ int odb_mkstemp(char *template, size_t limit, const char *pattern)\n \tsnprintf(template, limit, \"%s/%s\",\n \t\t get_object_directory(), pattern);\n \tsafe_create_leading_directories(template);\n-\treturn xmkstemp(template);\n+\treturn xmkstemp_mode(template, mode);\n }\n \n int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)\n-- \n1.7.0.rc2.4.gc602c4\n"},{"id":"135102","messageId":"7vsk8xjep1.fsf@alter.siamese.dyndns.org","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH 0/4] Allow Git repositories to be shared using POSIX ACLs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-19T17:52:26Z","receivedAt":"2010-02-19T17:52:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> In short: if a user wants to share a git repository using POSIX\n> filesystem ACLs, it seems everything works except pack file creation.\n> The problem is that we create the file with a mode 0600, i.e. no\n> permission for group,...\n\nModulo that it is more like \"we let mkstemp() to choose whatever file\nmode\", this is a good analysis.\n\nI think some versions of glibc used to have mkstemp() that creates 0644 or\n0664, meaning that the modes left by various implementations of mkstemp()\nare different from each other, and also different from what we want.  With\naef5aed (pack-objects: quickfix for permission modes., 2007-04-22) and\nb6b32cc (Fix 'quickfix' on pack-objects., 2007-04-22), were attempts to\nwork around that issue.\n\nBy not using mkstemp() from the platform but having our own would allow us\nto not even worry about this issue (this can be seen by the removal of a\ncall to umask() in [PATCH 4/4]).  I see your patches as a \"bite-the-bullet\nand do the right thing\" solution.\n\n> The test-case is really weak: ideally, we should have a real test with\n> several users interacting. But that's hardly scriptable in a portable\n> way, so the only testcase I added relies on getfacl and \"ls -l\" to find\n> out if the result is correct. However, I did some manual testing, and\n> as far as I can say, Git works very well with ACLs with this patch.\n\nThanks.\n"},{"id":"135183","messageId":"7vy6inekxq.fsf@alter.siamese.dyndns.org","threadId":"22726","inReplyTo":"1266597207-32036-5-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-20T20:01:05Z","receivedAt":"2010-02-20T20:01:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\n> index 4ee44a1..b8e9c34 100755\n> --- a/t/t1304-default-acl.sh\n> +++ b/t/t1304-default-acl.sh\n> @@ -27,7 +27,7 @@ modebits () {\n>  \tls -l \"$1\" | sed -e 's|^\\(..........\\).*|\\1|'\n>  }\n>  \n> -test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n> +test_expect_success 'git gc does not break ACLs with restrictive umask' '\n>  \tumask 077 &&\n>  \tgit gc &&\n>  \tactual=$(modebits .git/objects/pack/*.pack) &&\n\nThis does not seem to pass for me; I get 0444 instead of 0440 as you expect.\n"},{"id":"135273","messageId":"vpqfx4tln64.fsf@bauges.imag.fr","threadId":"22726","inReplyTo":"7vy6inekxq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-02-22T07:55:31Z","receivedAt":"2010-02-22T07:55:31Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>\n>> diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\n>> index 4ee44a1..b8e9c34 100755\n>> --- a/t/t1304-default-acl.sh\n>> +++ b/t/t1304-default-acl.sh\n>> @@ -27,7 +27,7 @@ modebits () {\n>>  \tls -l \"$1\" | sed -e 's|^\\(..........\\).*|\\1|'\n>>  }\n>>  \n>> -test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n>> +test_expect_success 'git gc does not break ACLs with restrictive umask' '\n>>  \tumask 077 &&\n>>  \tgit gc &&\n>>  \tactual=$(modebits .git/objects/pack/*.pack) &&\n>\n> This does not seem to pass for me; I get 0444 instead of 0440 as you expect.\n\nThat is strange, it does pass (or it's skipped if I don't have\nsetfacl) for me.\n\nWhat system are you using? Do you have ACLs enabled on the filesystem\nwhere you run the tests? What permission do you get for packs with\nGit-without-my-patch (I used to get 0400)?\n\nThanks,\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"135338","messageId":"7veikdau4i.fsf@alter.siamese.dyndns.org","threadId":"22726","inReplyTo":"vpqfx4tln64.fsf@bauges.imag.fr","subject":"Re: [PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-22T20:33:01Z","receivedAt":"2010-02-22T20:33:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> That is strange, it does pass (or it's skipped if I don't have\n> setfacl) for me.\n>\n> What system are you using? Do you have ACLs enabled on the filesystem\n> where you run the tests? What permission do you get for packs with\n> Git-without-my-patch (I used to get 0400)?\n\nOn my primary box (happens to be Debian 5 but that does not matter) I do\nnot even have setfacl and the tests are properly skipped.\n\nOn another box with FC11 (git.git directory is on an ext4 partition), here\nis what \"sh -x t1304-default.acl.sh -i -v\" gives me when run in 'pu'.\n\n\n\n+ test_description='Test repository with default ACL'\n+ . ./test-lib.sh\n++ case \"$GIT_TEST_TEE_STARTED, $* \" in\n++ ORIGINAL_TERM=screen\n++ LANG=C\n++ LC_ALL=C\n++ PAGER=cat\n++ TZ=UTC\n++ TERM=dumb\n++ export LANG LC_ALL PAGER TERM TZ\n++ EDITOR=:\n++ unset VISUAL\n++ unset GIT_EDITOR\n++ unset AUTHOR_DATE\n++ unset AUTHOR_EMAIL\n++ unset AUTHOR_NAME\n++ unset COMMIT_AUTHOR_EMAIL\n++ unset COMMIT_AUTHOR_NAME\n++ unset EMAIL\n++ unset GIT_ALTERNATE_OBJECT_DIRECTORIES\n++ unset GIT_AUTHOR_DATE\n++ GIT_AUTHOR_EMAIL=author@example.com\n++ GIT_AUTHOR_NAME='A U Thor'\n++ unset GIT_COMMITTER_DATE\n++ GIT_COMMITTER_EMAIL=committer@example.com\n++ GIT_COMMITTER_NAME='C O Mitter'\n++ unset GIT_DIFF_OPTS\n++ unset GIT_DIR\n++ unset GIT_WORK_TREE\n++ unset GIT_EXTERNAL_DIFF\n++ unset GIT_INDEX_FILE\n++ unset GIT_OBJECT_DIRECTORY\n++ unset GIT_CEILING_DIRECTORIES\n++ unset SHA1_FILE_DIRECTORIES\n++ unset SHA1_FILE_DIRECTORY\n++ GIT_MERGE_VERBOSITY=5\n++ export GIT_MERGE_VERBOSITY\n++ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME\n++ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME\n++ export EDITOR\n++ GIT_TEST_CMP='diff -u'\n++ unset CDPATH\n++ case $(echo $GIT_TRACE |tr \"[A-Z]\" \"[a-z]\") in\n+++ echo\n+++ tr '[A-Z]' '[a-z]'\n++ _x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n++ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n++ '[' xscreen '!=' xdumb ']'\n++ TERM=screen\n++ export TERM\n++ '[' -t 1 ']'\n++ test 2 -ne 0\n++ case \"$1\" in\n++ immediate=t\n++ shift\n++ test 1 -ne 0\n++ case \"$1\" in\n++ verbose=t\n++ shift\n++ test 0 -ne 0\n++ test -n ''\n++ test 'Test repository with default ACL' '!=' ''\n++ test '' = t\n++ exec\n++ test t = t\n++ exec\n++ test_failure=0\n++ test_count=0\n++ test_fixed=0\n++ test_broken=0\n++ test_success=0\n++ GIT_EXIT_OK=\n++ trap die EXIT\n++ satisfied=' '\n+++ pwd\n++ TEST_DIRECTORY=/scratch/buildfarm/pu/t\n++ test -n ''\n++ test -n ''\n++ git_bin_dir=/scratch/buildfarm/pu/t/../bin-wrappers\n++ test -x /scratch/buildfarm/pu/t/../bin-wrappers/git\n++ PATH=/scratch/buildfarm/pu/t/../bin-wrappers:/home/junio/g/Fedora-11-i686/git-active/bin:/home/junio/bin/common:/sbin:/usr/sbin:/usr/kerberos/bin:/usr/bin:/bin:/usr/local/sbin\n++ GIT_EXEC_PATH=/scratch/buildfarm/pu/t/..\n++ test -n ''\n+++ pwd\n++ GIT_TEMPLATE_DIR=/scratch/buildfarm/pu/t/../templates/blt\n++ unset GIT_CONFIG\n++ GIT_CONFIG_NOSYSTEM=1\n++ GIT_CONFIG_NOGLOBAL=1\n++ export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL\n++ . ../GIT-BUILD-OPTIONS\n+++ SHELL_PATH=/bin/sh\n+++ PERL_PATH=/usr/bin/perl\n+++ TAR=tar\n+++ NO_CURL=\n+++ NO_PERL=\n+++ NO_PYTHON=\n+++ pwd\n+++ pwd\n++ GITPERLLIB=/scratch/buildfarm/pu/t/../perl/blib/lib:/scratch/buildfarm/pu/t/../perl/blib/arch/auto/Git\n++ export GITPERLLIB\n++ test -d ../templates/blt\n++ test -z ''\n++ test -z ''\n+++ pwd\n++ GITPYTHONLIB=/scratch/buildfarm/pu/t/../git_remote_helpers/build/lib\n++ export GITPYTHONLIB\n++ test -d ../git_remote_helpers/build\n++ test -x ../test-chmtime\n+++ basename t1304-default-acl.sh .sh\n++ test='trash directory.t1304-default-acl'\n++ test -n ''\n++ case \"$test\" in\n++ TRASH_DIRECTORY='/scratch/buildfarm/pu/t/trash directory.t1304-default-acl'\n++ test '!' -z ''\n++ remove_trash='/scratch/buildfarm/pu/t/trash directory.t1304-default-acl'\n++ rm -fr 'trash directory.t1304-default-acl'\n++ test_create_repo 'trash directory.t1304-default-acl'\n++ test 1 = 1\n+++ pwd\n++ owd=/scratch/buildfarm/pu/t\n++ repo='trash directory.t1304-default-acl'\n++ mkdir -p 'trash directory.t1304-default-acl'\n++ cd 'trash directory.t1304-default-acl'\n++ /scratch/buildfarm/pu/t/../git-init --template=/scratch/buildfarm/pu/t/../templates/blt/\nInitialized empty Git repository in /scratch/buildfarm/pu/t/trash directory.t1304-default-acl/.git/\n++ mv .git/hooks .git/hooks-disabled\n++ cd /scratch/buildfarm/pu/t\n++ cd -P 'trash directory.t1304-default-acl'\n++ this_test=t1304-default-acl.sh\n++ this_test=t1304\n++ case $(uname -s) in\n+++ uname -s\n++ test_set_prereq POSIXPERM\n++ satisfied=' POSIXPERM '\n++ test_set_prereq BSLASHPSPEC\n++ satisfied=' POSIXPERM BSLASHPSPEC '\n++ test_set_prereq EXECKEEPSPID\n++ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID '\n++ test -z ''\n++ test_set_prereq PERL\n++ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL '\n++ test -z ''\n++ test_set_prereq PYTHON\n++ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL PYTHON '\n++ ln -s x y\n++ test -h y\n++ test_set_prereq SYMLINKS\n++ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL PYTHON SYMLINKS '\n++ rm -f y\n+ setfacl -Rm u:root:rwx .\n+ setfacl -Rm d:u:junio:rwx .\n+ setfacl -Rm d:u:root:rwx .\n+ touch file.txt\n+ git add file.txt\n+ git commit -m init\n[master (root-commit) 956f7d1] init\n Author: A U Thor <author@example.com>\n 0 files changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 file.txt\n+ test_expect_success 'git gc does not break ACLs with restrictive umask' '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ test 2 = 3\n+ prereq=\n+ test 2 = 2\n+ test_skip 'git gc does not break ACLs with restrictive umask' '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ test_count=1\n+ to_skip=\n+ test -z ''\n+ test -n ''\n+ case \"$to_skip\" in\n+ false\n+ say 'expecting success: \n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ say_color info 'expecting success: \n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ test -z info\n+ shift\n+ echo '* expecting success: \n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n* expecting success: \n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n\n+ test_run_ '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ eval '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n++ umask 077\n++ git gc\n+++ modebits .git/objects/pack/pack-9a3c3444a7e8660480c6ea70aa526e8299f7cfd6.pack\n+++ ls -l .git/objects/pack/pack-9a3c3444a7e8660480c6ea70aa526e8299f7cfd6.pack\n+++ sed -e 's|^\\(..........\\).*|\\1|'\n++ actual=-r--r--r--\n++ case \"$actual\" in\n++ echo 'expected 440, got -r--r--r--'\nexpected 440, got -r--r--r--\n++ false\n+ eval_ret=1\n+ return 0\n+ '[' 0 = 0 -a 1 = 0 ']'\n+ test_failure_ 'git gc does not break ACLs with restrictive umask' '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ test_failure=1\n+ say_color error 'FAIL 1: git gc does not break ACLs with restrictive umask'\n+ test -z error\n+ shift\n+ echo '* FAIL 1: git gc does not break ACLs with restrictive umask'\n* FAIL 1: git gc does not break ACLs with restrictive umask\n+ shift\n+ echo '\n\tumask 077 &&\n\tgit gc &&\n\tactual=$(modebits .git/objects/pack/*.pack) &&\n\tcase \"$actual\" in\n\t-r--r-----*)\n\t\t: happy\n\t\t;;\n\t*)\n\t\techo \"expected 440, got $actual\"; false\n\t\t;;\n\tesac &&\n\tgetfacl .git/objects/pack/*.pack > actual &&\n\tgrep -q \"user:root:rwx\" actual &&\n\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\tgrep -q \"mask::r--\" actual &&\n\tgrep -q \"group::---\" actual\n'\n+ sed -e 's/^/\t/'\n\t\n\t\tumask 077 &&\n\t\tgit gc &&\n\t\tactual=$(modebits .git/objects/pack/*.pack) &&\n\t\tcase \"$actual\" in\n\t\t-r--r-----*)\n\t\t\t: happy\n\t\t\t;;\n\t\t*)\n\t\t\techo \"expected 440, got $actual\"; false\n\t\t\t;;\n\t\tesac &&\n\t\tgetfacl .git/objects/pack/*.pack > actual &&\n\t\tgrep -q \"user:root:rwx\" actual &&\n\t\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n\t\tgrep -q \"mask::r--\" actual &&\n\t\tgrep -q \"group::---\" actual\n\t\n+ test t = ''\n+ GIT_EXIT_OK=t\n+ exit 1\n+ die\n+ code=1\n+ test -n t\n+ exit 1\n"},{"id":"135339","messageId":"7vsk8t9feq.fsf@alter.siamese.dyndns.org","threadId":"22726","inReplyTo":"7veikdau4i.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-22T20:36:13Z","receivedAt":"2010-02-22T20:36:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"By the way, here is what the same command gets when run on FreeBSD 8.0\n\n\n\n+ test_description='Test repository with default ACL'\n+ . ./test-lib.sh\n+ ORIGINAL_TERM=screen\n+ LANG=C\n+ LC_ALL=C\n+ PAGER=cat\n+ TZ=UTC\n+ TERM=dumb\n+ export LANG LC_ALL PAGER TERM TZ\n+ EDITOR=:\n+ unset VISUAL\n+ unset GIT_EDITOR\n+ unset AUTHOR_DATE\n+ unset AUTHOR_EMAIL\n+ unset AUTHOR_NAME\n+ unset COMMIT_AUTHOR_EMAIL\n+ unset COMMIT_AUTHOR_NAME\n+ unset EMAIL\n+ unset GIT_ALTERNATE_OBJECT_DIRECTORIES\n+ unset GIT_AUTHOR_DATE\n+ GIT_AUTHOR_EMAIL=author@example.com\n+ GIT_AUTHOR_NAME='A U Thor'\n+ unset GIT_COMMITTER_DATE\n+ GIT_COMMITTER_EMAIL=committer@example.com\n+ GIT_COMMITTER_NAME='C O Mitter'\n+ unset GIT_DIFF_OPTS\n+ unset GIT_DIR\n+ unset GIT_WORK_TREE\n+ unset GIT_EXTERNAL_DIFF\n+ unset GIT_INDEX_FILE\n+ unset GIT_OBJECT_DIRECTORY\n+ unset GIT_CEILING_DIRECTORIES\n+ unset SHA1_FILE_DIRECTORIES\n+ unset SHA1_FILE_DIRECTORY\n+ GIT_MERGE_VERBOSITY=5\n+ export GIT_MERGE_VERBOSITY\n+ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME\n+ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME\n+ export EDITOR\n+ GIT_TEST_CMP='diff -u'\n+ unset CDPATH\n+ echo\n+ tr '[A-Z]' '[a-z]'\n+ _x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n+ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n+ [ xscreen != xdumb ]\n+ TERM=screen\n+ export TERM\n+ [ -t 1 ]\n+ test 2 -ne 0\n+ immediate=t\n+ shift\n+ test 1 -ne 0\n+ verbose=t\n+ shift\n+ test 0 -ne 0\n+ test -n ''\n+ test 'Test repository with default ACL' != ''\n+ test '' = t\n+ exec\n+ test t = t\n+ exec\n+ test_failure=0\n+ test_count=0\n+ test_fixed=0\n+ test_broken=0\n+ test_success=0\n+ GIT_EXIT_OK=''\n+ trap die EXIT\n+ satisfied=' '\n+ pwd\n+ TEST_DIRECTORY=/usr/home/junio/buildfarm/pu/t\n+ test -n ''\n+ test -n ''\n+ git_bin_dir=/usr/home/junio/buildfarm/pu/t/../bin-wrappers\n+ test -x /usr/home/junio/buildfarm/pu/t/../bin-wrappers/git\n+ PATH=/usr/home/junio/buildfarm/pu/t/../bin-wrappers:/home/junio/g/FreeBSD-8.0-RELEASE-i386/git-active/bin:/home/junio/bin/common:/usr/local/bin:/sbin:/usr/sbin:/usr/bin:/bin\n+ GIT_EXEC_PATH=/usr/home/junio/buildfarm/pu/t/..\n+ test -n ''\n+ pwd\n+ GIT_TEMPLATE_DIR=/usr/home/junio/buildfarm/pu/t/../templates/blt\n+ unset GIT_CONFIG\n+ GIT_CONFIG_NOSYSTEM=1\n+ GIT_CONFIG_NOGLOBAL=1\n+ export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL\n+ . ../GIT-BUILD-OPTIONS\n+ SHELL_PATH=/bin/sh\n+ PERL_PATH=/usr/bin/perl\n+ TAR=tar\n+ NO_CURL=''\n+ NO_PERL=''\n+ NO_PYTHON=''\n+ pwd\n+ pwd\n+ GITPERLLIB=/usr/home/junio/buildfarm/pu/t/../perl/blib/lib:/usr/home/junio/buildfarm/pu/t/../perl/blib/arch/auto/Git\n+ export GITPERLLIB\n+ test -d ../templates/blt\n+ test -z ''\n+ test -z ''\n+ pwd\n+ GITPYTHONLIB=/usr/home/junio/buildfarm/pu/t/../git_remote_helpers/build/lib\n+ export GITPYTHONLIB\n+ test -d ../git_remote_helpers/build\n+ test -x ../test-chmtime\n+ basename t1304-default-acl.sh .sh\n+ test='trash directory.t1304-default-acl'\n+ test -n ''\n+ TRASH_DIRECTORY='/usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl'\n+ test ! -z ''\n+ remove_trash='/usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl'\n+ rm -fr 'trash directory.t1304-default-acl'\n+ test_create_repo 'trash directory.t1304-default-acl'\n+ test 1 = 1\n+ pwd\n+ owd=/usr/home/junio/buildfarm/pu/t\n+ repo='trash directory.t1304-default-acl'\n+ mkdir -p 'trash directory.t1304-default-acl'\n+ cd 'trash directory.t1304-default-acl'\n+ /usr/home/junio/buildfarm/pu/t/../git-init --template=/usr/home/junio/buildfarm/pu/t/../templates/blt/\nInitialized empty Git repository in /usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl/.git/\n+ mv .git/hooks .git/hooks-disabled\n+ cd /usr/home/junio/buildfarm/pu/t\n+ cd -P 'trash directory.t1304-default-acl'\n+ this_test=t1304-default-acl.sh\n+ this_test=t1304\n+ uname -s\n+ test_set_prereq POSIXPERM\n+ satisfied=' POSIXPERM '\n+ test_set_prereq BSLASHPSPEC\n+ satisfied=' POSIXPERM BSLASHPSPEC '\n+ test_set_prereq EXECKEEPSPID\n+ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID '\n+ test -z ''\n+ test_set_prereq PERL\n+ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL '\n+ test -z ''\n+ test_set_prereq PYTHON\n+ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL PYTHON '\n+ ln -s x y\n+ test -h y\n+ test_set_prereq SYMLINKS\n+ satisfied=' POSIXPERM BSLASHPSPEC EXECKEEPSPID PERL PYTHON SYMLINKS '\n+ rm -f y\n+ setfacl -Rm u:root:rwx .\nsetfacl: illegal option -- R\nusage: setfacl [-bdhkn] [-m entries] [-M file] [-x entries] [-X file] [file ...]\n+ say 'Skipping ACL tests: unable to use setfacl'\n+ say_color info 'Skipping ACL tests: unable to use setfacl'\n+ test -z info\n+ shift\n+ echo '* Skipping ACL tests: unable to use setfacl'\n* Skipping ACL tests: unable to use setfacl\n+ test_done\n+ GIT_EXIT_OK=t\n+ test_results_dir=/usr/home/junio/buildfarm/pu/t/test-results\n+ mkdir -p /usr/home/junio/buildfarm/pu/t/test-results\n+ test_results_path=/usr/home/junio/buildfarm/pu/t/test-results/t1304-default-acl-56364\n+ echo 'total 0'\n+ echo 'success 0'\n+ echo 'fixed 0'\n+ echo 'broken 0'\n+ echo 'failed 0'\n+ echo ''\n+ test 0 != 0\n+ test 0 != 0\n+ msg='0 test(s)'\n+ say_color pass 'passed all 0 test(s)'\n+ test -z pass\n+ shift\n+ echo '* passed all 0 test(s)'\n* passed all 0 test(s)\n+ test -d '/usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl'\n+ dirname '/usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl'\n+ cd /usr/home/junio/buildfarm/pu/t\n+ basename '/usr/home/junio/buildfarm/pu/t/trash directory.t1304-default-acl'\n+ rm -rf 'trash directory.t1304-default-acl'\n+ exit 0\n+ die\n+ code=0\n+ test -n t\n+ exit 0\n"},{"id":"135345","messageId":"vpqaav0or98.fsf@bauges.imag.fr","threadId":"22726","inReplyTo":"7veikdau4i.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 4/4] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-02-22T22:11:15Z","receivedAt":"2010-02-22T22:11:15Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> On another box with FC11 (git.git directory is on an ext4 partition), here\n> is what \"sh -x t1304-default.acl.sh -i -v\" gives me when run in\n> 'pu'.\n\nActually, it wasn't such a subtle configuration. You have umask=022 on\nyour machine, and I had umask=077 on the one I did the test. My test\nscript was setting umask after . test-lib.sh, it should have done it\nbefore (so that the created repository is created with restrictive\numask right away).\n\nWhile I was there, I also added a testcase for object files.\n\n> By the way, here is what the same command gets when run on FreeBSD 8.0\n> [...]\n> + setfacl -Rm u:root:rwx .\n> setfacl: illegal option -- R\n\nThanks. I fixed the script not to use -R. But that's without any\nwarranty, I don't have a FreeBSD machine for testing ...\n\nNew serie comming soon, which should adress all your comments.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"135357","messageId":"1266877936-13537-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 0/6 v3] Allow Git repositories to be shared using POSIX ACLs","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:10Z","receivedAt":"2010-02-22T22:32:10Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This version should include fixes for all of Junio's comment:\n\n[PATCH 1/6] Add a testcase for ACL with restrictive umask.\n=> This should pass with any umask, and includes a fix for FreeBSD\n(but I'm not sure it's sufficient)\n\n[PATCH 3/6] git_mkstemp_mode, xmkstemp_mode: variants of gitmkstemps with mode argument.\n=> better log message suggested by Junio.\n\n[PATCH 5/6] git_mkstemps_mode: don't set errno to EINVAL on exit.\n=> I actually got rid of this return EINVAL.\n"},{"id":"135352","messageId":"1266877936-13537-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 1/6] Add a testcase for ACL with restrictive umask.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:11Z","receivedAt":"2010-02-22T22:32:11Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Right now, Git creates unreadable pack files on non-shared\nrepositories when the user has a umask of 077, even when the default\nACLs for the directory would give read/write access to a specific\nuser.\n\nLoose object files are created world-readable, which doesn't break ACLs,\nbut isn't necessarily desirable.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n t/t1304-default-acl.sh |   67 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 67 insertions(+), 0 deletions(-)\n create mode 100755 t/t1304-default-acl.sh\n\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nnew file mode 100755\nindex 0000000..07dd6af\n--- /dev/null\n+++ b/t/t1304-default-acl.sh\n@@ -0,0 +1,67 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2010 Matthieu Moy\n+#\n+\n+test_description='Test repository with default ACL'\n+\n+# Create the test repo with restrictive umask\n+# => this must come before . ./test-lib.sh\n+umask 077\n+\n+. ./test-lib.sh\n+\n+# We need an arbitrary other user give permission to using ACLs. root\n+# is a good candidate: exists on all unices, and it has permission\n+# anyway, so we don't create a security hole running the testsuite.\n+\n+if ! setfacl -m u:root:rwx .; then\n+    say \"Skipping ACL tests: unable to use setfacl\"\n+    test_done\n+fi\n+\n+modebits () {\n+\tls -l \"$1\" | sed -e 's|^\\(..........\\).*|\\1|'\n+}\n+\n+check_perms_and_acl () {\n+\tactual=$(modebits \"$1\") &&\n+\tcase \"$actual\" in\n+\t-r--r-----*)\n+\t\t: happy\n+\t\t;;\n+\t*)\n+\t\techo \"Got permission '$actual', expected '-r--r-----'\"\n+\t\tfalse\n+\t\t;;\n+\tesac &&\n+\tgetfacl \"$1\" > actual &&\n+\tgrep -q \"user:root:rwx\" actual &&\n+\tgrep -q \"user:${LOGNAME}:rwx\" actual &&\n+\tgrep -q \"mask::r--\" actual &&\n+\tgrep -q \"group::---\" actual || false\n+}\n+\n+dirs_to_set=\"./ .git/ .git/objects/ .git/objects/pack/\"\n+\n+test_expect_success 'Setup test repo' '\n+\tsetfacl -m u:root:rwx          $dirs_to_set &&\n+\tsetfacl -d -m u:\"$LOGNAME\":rwx $dirs_to_set &&\n+\tsetfacl -d -m u:root:rwx       $dirs_to_set &&\n+\n+\ttouch file.txt &&\n+\tgit add file.txt &&\n+\tgit commit -m \"init\"\n+'\n+\n+test_expect_failure 'Objects creation does not break ACLs with restrictive umask' '\n+\t# SHA1 for empty blob\n+\tcheck_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391\n+'\n+\n+test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n+\tgit gc &&\n+\tcheck_perms_and_acl .git/objects/pack/*.pack\n+'\n+\n+test_done\n-- \n1.7.0.54.gb6a04.dirty\n"},{"id":"135361","messageId":"1266877936-13537-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 2/6] Move gitmkstemps to path.c","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:12Z","receivedAt":"2010-02-22T22:32:12Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This function used to be only a compatibility function, but we're\ngoing to extend it and actually use it, so make it part of Git.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Makefile          |    1 -\n compat/mkstemps.c |   70 -----------------------------------------------------\n path.c            |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 69 insertions(+), 71 deletions(-)\n delete mode 100644 compat/mkstemps.c\n\ndiff --git a/Makefile b/Makefile\nindex 7bf2fca..4387d42 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1200,7 +1200,6 @@ ifdef NO_MKDTEMP\n endif\n ifdef NO_MKSTEMPS\n \tCOMPAT_CFLAGS += -DNO_MKSTEMPS\n-\tCOMPAT_OBJS += compat/mkstemps.o\n endif\n ifdef NO_UNSETENV\n \tCOMPAT_CFLAGS += -DNO_UNSETENV\ndiff --git a/compat/mkstemps.c b/compat/mkstemps.c\ndeleted file mode 100644\nindex 14179c8..0000000\n--- a/compat/mkstemps.c\n+++ /dev/null\n@@ -1,70 +0,0 @@\n-#include \"../git-compat-util.h\"\n-\n-/* Adapted from libiberty's mkstemp.c. */\n-\n-#undef TMP_MAX\n-#define TMP_MAX 16384\n-\n-int gitmkstemps(char *pattern, int suffix_len)\n-{\n-\tstatic const char letters[] =\n-\t\t\"abcdefghijklmnopqrstuvwxyz\"\n-\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n-\t\t\"0123456789\";\n-\tstatic const int num_letters = 62;\n-\tuint64_t value;\n-\tstruct timeval tv;\n-\tchar *template;\n-\tsize_t len;\n-\tint fd, count;\n-\n-\tlen = strlen(pattern);\n-\n-\tif (len < 6 + suffix_len) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\t/*\n-\t * Replace pattern's XXXXXX characters with randomness.\n-\t * Try TMP_MAX different filenames.\n-\t */\n-\tgettimeofday(&tv, NULL);\n-\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n-\ttemplate = &pattern[len - 6 - suffix_len];\n-\tfor (count = 0; count < TMP_MAX; ++count) {\n-\t\tuint64_t v = value;\n-\t\t/* Fill in the random bits. */\n-\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n-\n-\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n-\t\tif (fd > 0)\n-\t\t\treturn fd;\n-\t\t/*\n-\t\t * Fatal error (EPERM, ENOSPC etc).\n-\t\t * It doesn't make sense to loop.\n-\t\t */\n-\t\tif (errno != EEXIST)\n-\t\t\tbreak;\n-\t\t/*\n-\t\t * This is a random value.  It is only necessary that\n-\t\t * the next TMP_MAX values generated by adding 7777 to\n-\t\t * VALUE are different with (module 2^32).\n-\t\t */\n-\t\tvalue += 7777;\n-\t}\n-\t/* We return the null string if we can't find a unique file name.  */\n-\tpattern[0] = '\\0';\n-\terrno = EINVAL;\n-\treturn -1;\n-}\ndiff --git a/path.c b/path.c\nindex 79aa104..ab2e368 100644\n--- a/path.c\n+++ b/path.c\n@@ -157,6 +157,75 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n \treturn mkstemps(path, suffix_len);\n }\n \n+/* Adapted from libiberty's mkstemp.c. */\n+\n+#undef TMP_MAX\n+#define TMP_MAX 16384\n+\n+int gitmkstemps(char *pattern, int suffix_len)\n+{\n+\tstatic const char letters[] =\n+\t\t\"abcdefghijklmnopqrstuvwxyz\"\n+\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n+\t\t\"0123456789\";\n+\tstatic const int num_letters = 62;\n+\tuint64_t value;\n+\tstruct timeval tv;\n+\tchar *template;\n+\tsize_t len;\n+\tint fd, count;\n+\n+\tlen = strlen(pattern);\n+\n+\tif (len < 6 + suffix_len) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * Replace pattern's XXXXXX characters with randomness.\n+\t * Try TMP_MAX different filenames.\n+\t */\n+\tgettimeofday(&tv, NULL);\n+\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n+\ttemplate = &pattern[len - 6 - suffix_len];\n+\tfor (count = 0; count < TMP_MAX; ++count) {\n+\t\tuint64_t v = value;\n+\t\t/* Fill in the random bits. */\n+\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n+\n+\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n+\t\tif (fd > 0)\n+\t\t\treturn fd;\n+\t\t/*\n+\t\t * Fatal error (EPERM, ENOSPC etc).\n+\t\t * It doesn't make sense to loop.\n+\t\t */\n+\t\tif (errno != EEXIST)\n+\t\t\tbreak;\n+\t\t/*\n+\t\t * This is a random value.  It is only necessary that\n+\t\t * the next TMP_MAX values generated by adding 7777 to\n+\t\t * VALUE are different with (module 2^32).\n+\t\t */\n+\t\tvalue += 7777;\n+\t}\n+\t/* We return the null string if we can't find a unique file name.  */\n+\tpattern[0] = '\\0';\n+\terrno = EINVAL;\n+\treturn -1;\n+}\n+\n int validate_headref(const char *path)\n {\n \tstruct stat st;\n-- \n1.7.0.54.gb6a04.dirty\n"},{"id":"135359","messageId":"1266877936-13537-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 3/6] git_mkstemp_mode, xmkstemp_mode: variants of gitmkstemps with mode argument.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:13Z","receivedAt":"2010-02-22T22:32:13Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"gitmkstemps emulates the behavior of mkstemps, which is usually used\nto create files in a shared directory like /tmp/, hence, it creates\nfiles with permission 0600.\n\nAdd git_mkstemps_mode() that allows us to specify the desired mode, and\nmake git_mkstemps() a wrapper that always uses 0600 to call it. Later we\nwill use git_mkstemps_mode() when creating pack files.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n cache.h   |    4 ++++\n path.c    |   16 ++++++++++++++--\n wrapper.c |   10 ++++++++++\n 3 files changed, 28 insertions(+), 2 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex d478eff..0319637 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -641,6 +641,10 @@ int git_mkstemp(char *path, size_t n, const char *template);\n \n int git_mkstemps(char *path, size_t n, const char *template, int suffix_len);\n \n+/* set default permissions by passing mode arguments to open(2) */\n+int git_mkstemps_mode(char *pattern, int suffix_len, int mode);\n+int git_mkstemp_mode(char *pattern, int mode);\n+\n /*\n  * NOTE NOTE NOTE!!\n  *\ndiff --git a/path.c b/path.c\nindex ab2e368..925039a 100644\n--- a/path.c\n+++ b/path.c\n@@ -162,7 +162,7 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n #undef TMP_MAX\n #define TMP_MAX 16384\n \n-int gitmkstemps(char *pattern, int suffix_len)\n+int git_mkstemps_mode(char *pattern, int suffix_len, int mode)\n {\n \tstatic const char letters[] =\n \t\t\"abcdefghijklmnopqrstuvwxyz\"\n@@ -204,7 +204,7 @@ int gitmkstemps(char *pattern, int suffix_len)\n \t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n \t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n \n-\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);\n+\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);\n \t\tif (fd > 0)\n \t\t\treturn fd;\n \t\t/*\n@@ -226,6 +226,17 @@ int gitmkstemps(char *pattern, int suffix_len)\n \treturn -1;\n }\n \n+int git_mkstemp_mode(char *pattern, int mode)\n+{\n+\t/* mkstemp is just mkstemps with no suffix */\n+\treturn git_mkstemps_mode(pattern, 0, mode);\n+}\n+\n+int gitmkstemps(char *pattern, int suffix_len)\n+{\n+\treturn git_mkstemps_mode(pattern, suffix_len, 0600);\n+}\n+\n int validate_headref(const char *path)\n {\n \tstruct stat st;\n@@ -718,3 +729,4 @@ int daemon_avoid_alias(const char *p)\n \t\t}\n \t}\n }\n+\ndiff --git a/wrapper.c b/wrapper.c\nindex 0e3e20a..673762f 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -204,6 +204,16 @@ int xmkstemp(char *template)\n \treturn fd;\n }\n \n+int xmkstemp_mode(char *template, int mode)\n+{\n+\tint fd;\n+\n+\tfd = git_mkstemp_mode(template, mode);\n+\tif (fd < 0)\n+\t\tdie_errno(\"Unable to create temporary file\");\n+\treturn fd;\n+}\n+\n /*\n  * zlib wrappers to make sure we don't silently miss errors\n  * at init time.\n-- \n1.7.0.54.gb6a04.dirty\n"},{"id":"135356","messageId":"1266877936-13537-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 4/6] Use git_mkstemp_mode and xmkstemp_mode in odb_mkstemp, not chmod later.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:14Z","receivedAt":"2010-02-22T22:32:14Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"We used to create 0600 files, and then use chmod to set the group and\nother permission bits to the umask. This usually has the same effect\nas a normal file creation with a umask.\n\nBut in the presence of ACLs, the group permission plays the role of\nthe ACL mask: the \"g\" bits of newly created files are chosen according\nto default ACL mask of the directory, not according to the umask, and\ndoing a chmod() on these \"g\" bits affect the ACL's mask instead of\nactual group permission.\n\nIn other words, creating files with 0600 and then doing a chmod to the\numask creates files which are unreadable by users allowed in the\ndefault ACL. To create the files without breaking ACLs, we let the\numask do it's job at the file's creation time, and get rid of the\nlater chmod.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n builtin-pack-objects.c |   18 ++----------------\n t/t1304-default-acl.sh |    2 +-\n wrapper.c              |   10 +++++++---\n 3 files changed, 10 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex e1d3adf..539e75d 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -464,9 +464,6 @@ static int write_one(struct sha1file *f,\n \treturn 1;\n }\n \n-/* forward declaration for write_pack_file */\n-static int adjust_perm(const char *path, mode_t mode);\n-\n static void write_pack_file(void)\n {\n \tuint32_t i = 0, j;\n@@ -523,21 +520,17 @@ static void write_pack_file(void)\n \t\t}\n \n \t\tif (!pack_to_stdout) {\n-\t\t\tmode_t mode = umask(0);\n \t\t\tstruct stat st;\n \t\t\tconst char *idx_tmp_name;\n \t\t\tchar tmpname[PATH_MAX];\n \n-\t\t\tumask(mode);\n-\t\t\tmode = 0444 & ~mode;\n-\n \t\t\tidx_tmp_name = write_idx_file(NULL, written_list,\n \t\t\t\t\t\t      nr_written, sha1);\n \n \t\t\tsnprintf(tmpname, sizeof(tmpname), \"%s-%s.pack\",\n \t\t\t\t base_name, sha1_to_hex(sha1));\n \t\t\tfree_pack_by_name(tmpname);\n-\t\t\tif (adjust_perm(pack_tmp_name, mode))\n+\t\t\tif (adjust_shared_perm(pack_tmp_name))\n \t\t\t\tdie_errno(\"unable to make temporary pack file readable\");\n \t\t\tif (rename(pack_tmp_name, tmpname))\n \t\t\t\tdie_errno(\"unable to rename temporary pack file\");\n@@ -565,7 +558,7 @@ static void write_pack_file(void)\n \n \t\t\tsnprintf(tmpname, sizeof(tmpname), \"%s-%s.idx\",\n \t\t\t\t base_name, sha1_to_hex(sha1));\n-\t\t\tif (adjust_perm(idx_tmp_name, mode))\n+\t\t\tif (adjust_shared_perm(idx_tmp_name))\n \t\t\t\tdie_errno(\"unable to make temporary index file readable\");\n \t\t\tif (rename(idx_tmp_name, tmpname))\n \t\t\t\tdie_errno(\"unable to rename temporary index file\");\n@@ -2125,13 +2118,6 @@ static void get_object_list(int ac, const char **av)\n \t\tloosen_unused_packed_objects(&revs);\n }\n \n-static int adjust_perm(const char *path, mode_t mode)\n-{\n-\tif (chmod(path, mode))\n-\t\treturn -1;\n-\treturn adjust_shared_perm(path);\n-}\n-\n int cmd_pack_objects(int argc, const char **argv, const char *prefix)\n {\n \tint use_internal_rev_list = 0;\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex 07dd6af..8472dbb 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -59,7 +59,7 @@ test_expect_failure 'Objects creation does not break ACLs with restrictive umask\n \tcheck_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391\n '\n \n-test_expect_failure 'git gc does not break ACLs with restrictive umask' '\n+test_expect_success 'git gc does not break ACLs with restrictive umask' '\n \tgit gc &&\n \tcheck_perms_and_acl .git/objects/pack/*.pack\n '\ndiff --git a/wrapper.c b/wrapper.c\nindex 673762f..9c71b21 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -277,10 +277,14 @@ int git_inflate(z_streamp strm, int flush)\n int odb_mkstemp(char *template, size_t limit, const char *pattern)\n {\n \tint fd;\n-\n+\t/*\n+\t * we let the umask do its job, don't try to be more\n+\t * restrictive except to remove write permission.\n+\t */\n+\tint mode = 0444;\n \tsnprintf(template, limit, \"%s/%s\",\n \t\t get_object_directory(), pattern);\n-\tfd = mkstemp(template);\n+\tfd = git_mkstemp_mode(template, mode);\n \tif (0 <= fd)\n \t\treturn fd;\n \n@@ -289,7 +293,7 @@ int odb_mkstemp(char *template, size_t limit, const char *pattern)\n \tsnprintf(template, limit, \"%s/%s\",\n \t\t get_object_directory(), pattern);\n \tsafe_create_leading_directories(template);\n-\treturn xmkstemp(template);\n+\treturn xmkstemp_mode(template, mode);\n }\n \n int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)\n-- \n1.7.0.54.gb6a04.dirty\n"},{"id":"135353","messageId":"1266877936-13537-6-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 5/6] git_mkstemps_mode: don't set errno to EINVAL on exit.","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:15Z","receivedAt":"2010-02-22T22:32:15Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"When reaching the end of git_mkstemps_mode, at least one call to open()\nhas been done, and errno has been set accordingly. Setting errno is\ntherefore not necessary, and actually harmfull since callers can't\ndistinguish e.g. permanent failure from ENOENT, which can just mean that\nwe need to create the containing directory.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n path.c |    1 -\n 1 files changed, 0 insertions(+), 1 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 925039a..6f44921 100644\n--- a/path.c\n+++ b/path.c\n@@ -222,7 +222,6 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)\n \t}\n \t/* We return the null string if we can't find a unique file name.  */\n \tpattern[0] = '\\0';\n-\terrno = EINVAL;\n \treturn -1;\n }\n \n-- \n1.7.0.54.gb6a04.dirty\n"},{"id":"135354","messageId":"1266877936-13537-7-git-send-email-Matthieu.Moy@imag.fr","threadId":"22726","inReplyTo":"1266597207-32036-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH 6/6] Use git_mkstemp_mode instead of plain mkstemp to create object files","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2010-02-22T22:32:16Z","receivedAt":"2010-02-22T22:32:16Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"We used to unnecessarily give the read permission to group and others,\nregardless of the umask, which isn't serious because the objects are\nstill protected by their containing directory, but isn't necessary\neither.\n\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n sha1_file.c            |    6 +++---\n t/t1304-default-acl.sh |    2 +-\n 2 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 657825e..3316f28 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2206,7 +2206,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)\n \t}\n \n out:\n-\tif (set_shared_perm(filename, (S_IFREG|0444)))\n+\tif (adjust_shared_perm(filename))\n \t\treturn error(\"unable to set permission to '%s'\", filename);\n \treturn 0;\n }\n@@ -2262,7 +2262,7 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)\n \t}\n \tmemcpy(buffer, filename, dirlen);\n \tstrcpy(buffer + dirlen, \"tmp_obj_XXXXXX\");\n-\tfd = mkstemp(buffer);\n+\tfd = git_mkstemp_mode(buffer, 0444);\n \tif (fd < 0 && dirlen && errno == ENOENT) {\n \t\t/* Make sure the directory exists */\n \t\tmemcpy(buffer, filename, dirlen);\n@@ -2272,7 +2272,7 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)\n \n \t\t/* Try again */\n \t\tstrcpy(buffer + dirlen - 1, \"/tmp_obj_XXXXXX\");\n-\t\tfd = mkstemp(buffer);\n+\t\tfd = git_mkstemp_mode(buffer, 0444);\n \t}\n \treturn fd;\n }\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex 8472dbb..cc30be4 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -54,7 +54,7 @@ test_expect_success 'Setup test repo' '\n \tgit commit -m \"init\"\n '\n \n-test_expect_failure 'Objects creation does not break ACLs with restrictive umask' '\n+test_expect_success 'Objects creation does not break ACLs with restrictive umask' '\n \t# SHA1 for empty blob\n \tcheck_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391\n '\n-- \n1.7.0.54.gb6a04.dirty\n"}]}