2017-08-05 96 views
0

我们的校园里有一台Solaris服务器,每个学生和工作人员都有一个帐户。我想要托管一个纯粹的Git仓库并让它只能被某些用户访问。致命:无法执行'挂钩/更新':使用Git时的权限被拒绝

现在,因为我不管理服务器,所以我不能搞乱组和用户帐户。我知道我可以使用Giotlite并为我的用户创建公钥,但似乎很愚蠢,因为他们已经在服务器上拥有自己的用户帐户。所以我正在做的是使用FACL来访问特定的用户。

这里是我做过什么来设置使用cs101帐户在其主目录回购(这是过程帐户):

  1. 我创建的回购目录:mkdir cs101.git
  2. 设置FACL用给我的用户帐户

    setfacl -m d:u::rwx,d:g::---,d:o:---,d:m:rwx cs101.git 
    setfacl -m d:u:cs101:rwx,u:cs101:rwx,d:u:welcomb:rwx,u:welcomb:rwx cs101.git 
    
  3. 后来终于初始化访问的Git

    权限
    cd cs101.git 
    git init --bare --shared 
    

的目录列表显示

total 88 
drwx--S---+ 7 cs101 cs101  4096 Aug 3 14:33 . 
drwx-----x 6 cs101 cs101  4096 Aug 5 15:02 .. 
drwxrws---+ 2 cs101 cs101  4096 Aug 3 14:33 branches 
-rw-rw----+ 1 cs101 cs101  126 Aug 3 14:33 config 
-rw-rw----+ 1 cs101 cs101  73 Aug 3 14:33 description 
-rw-rw----+ 1 cs101 cs101  23 Aug 3 14:33 HEAD 
drwxrws---+ 2 cs101 cs101  4096 Aug 3 14:33 hooks 
drwxrws---+ 2 cs101 cs101  4096 Aug 3 14:33 info 
drwxrws---+ 33 cs101 cs101  4096 Aug 5 15:10 objects 
drwxrws---+ 4 cs101 cs101  4096 Aug 3 14:33 refs 

权限的目录似乎是正确的

# file: hooks/ 
# owner: cs101 
# group: cs101 
user::rwx 
user:cs101:rwx    #effective:rwx 
user:welcomb:rwx    #effective:rwx 
group::rwx     #effective:rwx 
mask:rwx 
other:--- 
default:user::rwx 
default:user:cs101:rwx 
default:user:welcomb:rwx 
default:group::--- 
default:mask:rwx 
default:other:--- 

仍在使用过程帐户cs101,我把一些文件到回购。

现在,我退出过程帐户和登录使用我自己的用户帐户,我能够克隆回购[email protected]$ git clone ~cs101/cs101.git

到目前为止好,一切都显示正常。

现在的问题是,我无法用我自己的用户帐户推新提交回回购:

[email protected]$ GIT_TRACE=1 git push 
trace: built-in: git 'push' 
trace: run_command: 'git-receive-pack '\''/home/course/cs101'\''' 
trace: exec: '/bin/bash' '-c' 'git-receive-pack '\''/home/course/cs101'\''' 'git-receive-pack '\''/home/course/cs101'\''' 
trace: built-in: git 'receive-pack' '/home/course/cs101' 
trace: run_command: 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '-q' 
trace: exec: 'git' 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '-q' 
trace: built-in: git 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '-q' 
trace: run_command: 'unpack-objects' '--pack_header=2,3' '-q' 
remote: trace: exec: 'git' 'unpack-objects' '--pack_header=2,3' '-q' 
remote: trace: built-in: git 'unpack-objects' '--pack_header=2,3' '-q' 
trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' 
trace: exec: 'git' 'rev-list' '--objects' '--stdin' '--not' '--all' 
trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all' 
trace: run_command: 'hooks/update' 'refs/heads/master' '629b5b1f0122de95bd4e7b50a7968e64aaef6e65' 'b2072da84ee7d3fde6c6daf2cae61dbae6b0a5d9' 
fatal: cannot exec 'hooks/update': Permission denied 
remote: error: hook declined to update refs/heads/master 
trace: run_command: 'gc' '--auto' '--quiet' 
trace: exec: 'git' 'gc' '--auto' '--quiet' 
trace: built-in: git 'gc' '--auto' '--quiet' 
To /home/course/cs101 
! [remote rejected] master -> master (hook declined) 
error: failed to push some refs to '/home/course/cs101' 

现在看来,这是无法执行hooks/update

fatal: cannot exec 'hooks/update': Permission denied 

hooks/update EXEC位 甚至没有设置,这意味着Git的应该忽略运行它。

/home/course/cs101/cs101.git/hooks$ getfacl update   

# file: update            
# owner: cs101            
# group: cs101            
user::rw-              
user:cs101:rwx   #effective:rwx      
user:welcomb:rwx  #effective:rwx    
group::rw-    #effective:rw-      
mask:rwx              
other:---              

/home/course/cs101/cs101.git/hooks$ ls -al update   
-rw-rw---- 1 cs101 cs101  2910 Aug 4 10:50 update 

我可以访问这些文件的目录,甚至用我的帐户

/home/course/cs101/cs101.git/hooks$ ./update.sample 
Don't run this script from the command line. 
(if you want, you could supply GIT_DIR then run 
    ./update.sample <ref> <oldrev> <newrev>) 

所以我想不通为什么推送操作失败更新回购执行update.sample

+0

'getfacl'的输出表明它*对于'user:welcomb'是可执行的,所以Git会尝试执行它。目前尚不清楚为什么随后会失败(是否解释了?考虑到小文件的大小,我想是这样;如果是这样,解释者的权限是否被拒绝?)。 – torek

+0

'update'的umask不可执行,实际上我无法从终端执行它。你认为Git认为它可以从acl执行并尝试运行它吗?我该如何检查它是否被解释?我不太明白你的意思。 – welcomb

+0

Git调用'access(path,X_OK)',这取决于系统的'access'调用返回什么,但我期望它更喜欢ACL'stat'模式位。至于它是什么意思是解释文件,请参阅https://linux.die.net/man/2/execve – torek

回答

1

getfacl输出包括线:

user:cs101:rwx   #effective:rwx  
user:welcomb:rwx  #effective:rwx         

这意味着权利要求C库access(path, X_OK)功能很可能该文件可以被执行(通过execve系统呼叫或类似的运行),在至少对用户cs101welcomb。这是Git如何确定钩子是否可执行的。

(请注意,任何其他用户呼叫access将得到答案:没有,这个文件不是可执行这是什么使访问控制列表等等复杂的部分。)

当OS实际上是尝试执行它,但是,其他事情出错了。 出错,但execve系统调用失败,出现“权限被拒绝”错误,这并不完全清楚。然后Git决定该钩子失败,而不是钩子实际上不可执行(Git假定access将会说而不是对于这些情况)。

鉴于文件的小尺寸(2910字节,来自ls -al update输出),update钩子似乎不太可能是shell脚本以外的任何其他东西。如果它是的shell脚本,它需要一个正确的#!解释器行才能执行,并且该解释器行必须指向一个本身具有执行权限的文件。

如果您确实希望挂钩运行,则必须查找实际故障的来源。如果你不要想要运行钩子,并且不想让Git到认为挂钩应该应该运行,从ACL的各个元素中删除执行位,或者完全删除ACL(ACLs和“Unix风格”权限通常是底层系统中的独立实体,尽管ZFS在此处有所不同)。

相关问题