在samba共享上调试git repo权限


1

我已经使用samba共享克隆了git仓库大约一年了,除了设置方面的一些问题外,没有任何问题。最近,我尝试将一些文件添加到现有存储库中,并惊讶地看到“权限被拒绝”错误。

现在我可以初始化空仓库,但是当我尝试运行时strace git add test,我得到:

    open(".git/objects/info/alternates", O_RDONLY|O_NOATIME) = -1 ENOENT (No such file or directory)
    access(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", F_OK) = -1 ENOENT (No such file or directory)
    open(".git/objects/e6/tmp_obj_GvIyn7", O_RDWR|O_CREAT|O_EXCL, 0444) = -1 EACCES (Permission denied)
    write(2, "error: insufficient permission f"..., 88error: insufficient permission for adding an object to repository database .git/objects
    ) = 88
    close(4)                                = 0
    write(2, "error: test: failed to insert in"..., 44error: test: failed to insert into database
    ) = 44
    write(2, "error: unable to index file test"..., 33error: unable to index file test
    ) = 33

我在64位Archlinux(内核版本:3.12.1)上使用git 1.8.4.2,samba 4.1.1。自古以来,我从未在git和samba配置中进行任何更改。

使用/ etc / fstab中的systemd automount挂载共享:

//SERVER/DATA  /media/smb  cifs user,noauto,credentials=/etc/samba/creds,\
workgroup=PRV,uid=1000,gid=users,_netdev,comment=systemd.automount 0 0

安装显示为:

//SERVER/DATA on /media/smb type cifs (rw,nosuid,nodev,noexec,relatime,vers=1.0,
cache=strict,domain=PRV,uid=1000,forceuid,gid=100,forcegid,addr=10.1.1.5,
file_mode=0755,dir_mode=0755,nounix,serverino,rsize=61440,wsize=65536,actimeo=1)

权限:

    $ ls -lan .git/objects
    total 0
    drwxr-xr-x 2 1000 100 0 11-27 09:04 .
    drwxr-xr-x 2 1000 100 0 2013-11-27  ..
    drwxr-xr-x 2 1000 100 0 11-27 09:39 e6
    drwxr-xr-x 2 1000 100 0 11-27 09:04 info
    drwxr-xr-x 2 1000 100 0 11-27 09:04 pack

    $ ls -lan .git/objects/pack
    total 0
    drwxr-xr-x 2 1000 100 0 11-27 09:04 .
    drwxr-xr-x 2 1000 100 0 11-27 09:04 ..

我已经尝试过:

  • 为共享设置不同的权限-相同的结果
  • 手动安装-相同
  • 将samba和git降级到早期版本-没什么区别
  • sudo-这可行,但除非绝对必要,否则我不想使用它
  • 出于好奇(出于好奇)-克隆git repo失败,将hg repos克隆出来没有任何问题
  • 在使用sudo之后更改所有者和组-发出命令之前和之后它们似乎保持不变

我还有什么可以做调试的吗?我很愿意留下git,但是我不知道权限有什么问题。

关于sudo:

$ touch test
$ sudo strace git add test
open(".git/objects/info/alternates", O_RDONLY|O_NOATIME) = -1 ENOENT (No such file or directory)
access(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".git/objects/pack", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
getdents(5, /* 2 entries */, 32768)     = 48
getdents(5, /* 0 entries */, 32768)     = 0
close(5)                                = 0
open(".git/objects/e6/tmp_obj_i4e0C8", O_RDWR|O_CREAT|O_EXCL, 0444) = 5
brk(0xd5a000)                           = 0xd5a000
write(5, "x\1K\312\311OR0`\0\0\t\260\1\360", 15) = 15
brk(0xd4a000)                           = 0xd4a000
brk(0xd3a000)                           = 0xd3a000
close(5)                                = 0
link(".git/objects/e6/tmp_obj_i4e0C8", ".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391") = 0
unlink(".git/objects/e6/tmp_obj_i4e0C8") = 0
lstat(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", {st_mode=S_IFREG|0755, st_size=15, ...}) = 0
close(4)   

$ ls -lan .git/objects/e6
total 1
drwxr-xr-x 2 1000 100  0 11-28 10:11 .
drwxr-xr-x 2 1000 100  0 11-28 10:10 ..
-rwxr-xr-x 1 1000 100 15 11-28 10:11 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
-r-xr-xr-x 1 1000 100  0 11-28 10:11 tmp_obj_9Z8UgU
-r-xr-xr-x 1 1000 100  0 11-28 10:10 tmp_obj_d0yhDJ

它创建具有0755权限的对象。如果没有sudo临时对象文件,则保留0555。看起来问题出在0444以普通用户身份创建文件时,该文件似乎具有对整个存储库的写入权限。

Answers:



1

我正在运行的内核版本中存在一个错误。我将内核降级到3.11.6,并且git add/commit随着用户再次开始工作。


0

最有可能的是,您可能是在使用root时更改了该存储库的root权限,sudo现在其中的某些文件.git是root拥有的。执行a chown将文件所有权重置为您通常使用的用户。


我一直尝试以常规用户的身份初始化几个空的存储库。我曾经使用过sudo git addsudo git commit仅使用了其中一部分-当我恢复工作时,将尝试将它们穿上。除此之外,我怀疑未发行的回购协议sudo git是否将被根拥有。
2013年

不幸的是,chown它没有任何改变。在操作之前和之后,所有文件和目录仍显示为1000:100拥有。我将更新问题。
13年

0

Linux将您的smb文件夹视为“其他”组中的文件夹。因此,如果您希望所有组均可写www,则您的权限应类似于xx7,例如777。

问题,每次git创建一个新的文件夹,文件或其他内容时,它将使用自己的权限创建它。解决方案是使用umask,因此以当前用户名创建的所有内容都将使用指定的权限。在这种情况下,Windows共享文件夹将需要:

umask 000

这样任何人都可以写入任何新文件,包括“ others”组也就是您共享的Windows文件夹。

在您的.bashrc中添加此umask,即可解决问题。


我也尝试过umask。它没有帮助。内核的bugzilla上打开了一个错误报告,其他人也受到了升级的影响。
bjauy

这个错误会影响git,linux或win $吗?
亚历杭德罗·莫雷诺

我不记得这里任何地方都提到Windows。接受的答案将准确说明该错误会造成什么影响。
13年

0

在我这方面,由于与Samba结合使用的内核中的文件系统驱动程序违反了POSIX,我遇到了上述问题。由于我既不能使用sudo也不能更改内核,也不能更改Samba版本,因此我需要另一个解决方案。

我没有尝试使用本地编译的方法来解决此问题git,相反,我的解决方案是通过动态方式LD_PRELOAD对其进行修复。

您可以在https://github.com/hilbix/misc/tree/master/git_push_samba中找到完整的解决方法

有问题的部分是git创建用于以只读模式写入的文件。这是正确的,但是由于错误的FS驱动程序的某种组合,这导致syscall失败,如下所示:

open("./objects/98/tmp_obj_vVR5gb", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0444) = -1 EACCES (Permission denied)

这使git放弃。但是,如果更改0644此syscall的模式,则将成功返回。以下骇客会这样做:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define open    ignorethisopen
#define open64  ignorethisopen64
#include <fcntl.h>
#undef open
#undef open64
#include <dlfcn.h>

static int (*___open)(const char *, int, mode_t);
static int (*___open64)(const char *, int, mode_t);

static void *
dlwrap(const char *fn)
{
  const char *err;

  void *p = dlsym(RTLD_NEXT, fn);
  if ((err=dlerror())!=0)
    fprintf(stderr, "dlsym(RTLD_NEXT,'%s'): %s\r\n", fn, err);
  return p;
}

void
_init(void)
{
  DP(("open wrappe"));

  ___open       = dlwrap("open");
  ___open64     = dlwrap("open64");
}

int
open64(const char *file, int flags, mode_t mode)
{
  if (flags && O_CREAT)
    return ___open64(file, flags, mode|0200);
  return ___open64(file, flags, mode);
}

int
open(const char *file, int flags, mode_t mode)
{
  if (flags && O_CREAT)
    return ___open(file, flags, mode|0200);
  return ___open(file, flags, mode);
}

它需要编译如下:

cc -Wall -O3 -D_GNU_SOURCE -fPIC -c -o git_push_samba.o git_push_samba.c
gcc -o git_push_samba.so -nostartfiles -shared git_push_samba.o -ldl

之后git可以如下调用:

LD_PRELOAD=path/to/git_push_samba.so git ...

笔记:

  • 我将其称为“ git_push_samba”是因为我想推送到git驻留在本地安装到路径的Samba共享上的“裸”存储库。但是,这甚至适用于您git在此类文件系统上正常使用的情况(例如git add发生故障)。

  • 可能还有其他一些看起来相同的问题。因此,这并不能解决该问题的所有变体,仅解决一个由错误的(违反POSIX的)文件系统驱动程序引起的变体。

如何确定问题的存在,可以通过以下方式解决:

git init testdir
cd testdir
date > README
git add README

如果git add失败并显示“添加对象权限不足”,则此处应解决此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.