致命:不能执行'hooks / update':使用Git

时间:2017-08-05 07:58:38

标签: git solaris acl

我们校园里有一台Solaris服务器,每个学生和员工都有一个帐户。我想主持一个简单的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
    
  4. 目录列表显示

    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,我将一些文件推送到回购邮件中。

    现在,我退出课程帐户并使用我自己的用户帐户登录,我能够克隆回购welcomb@solaris$ git clone ~cs101/cs101.git

    到目前为止,一切都很好。

    现在问题是我无法使用我自己的用户帐户将新提交推回到repo:

    welcomb@solaris$ 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
    

    我可以访问目录中的文件,甚至可以使用我的帐户执行update.sample

    /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>)
    

    所以我无法弄清楚为什么Git push无法更新回购。

1 个答案:

答案 0 :(得分:1)

getfacl输出包括以下行:

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

这意味着C库access(path, X_OK)函数可能声称文件可以执行(通过execve系统调用或类似操作),至少对于用户cs101welcomb。这就是Git确定钩子是否可执行的方式。

(请注意,任何其他用户调用access都会得到答案:不,此文件不可执行。这是使ACL成为现实的一部分复杂。)

然而,当操作系统实际尝试执行它时,出现了其他问题。并不完全清楚 出错了什么,但execve系统调用失败并出现“权限被拒绝”错误。然后Git决定挂钩失败,而不是挂钩实际上不可执行(Git假定access会说没有而不是这些情况)

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

如果您确实希望挂钩运行,则必须追踪实际故障的来源。如果希望挂钩运行,并且不希望Git 认为挂钩应该运行,请从中删除执行位ACL的各种元素,或者完全删除ACL(ACL和“Unix风格”权限通常是底层系统中的独立实体,尽管ZFS在这里是不同的。)