fatal: no se puede ejecutar 'hooks / update': Permiso denegado al usar Git

Tenemos un server Solaris en nuestro campus, en el que cada alumno y personal tiene una count. Quiero alojar un repository simple de Git y tenerlo solo accesible para ciertos usuarios.

Ahora, debido a que no administro el server, no puedo perder el time con los grupos y las counts de usuario. Sé que puedo usar Giotlite y crear keys públicas para mis usuarios, pero parece una tontería ya que ya tienen sus propias counts de usuario en el server. Entonces, lo que estoy haciendo es usar FACL para dar acceso a usuarios específicos.

Esto es lo que hice para configurar el repository usando la count cs101 en su directory principal (es la count del curso):

  1. mkdir cs101.git un directory para el repository: mkdir cs101.git
  2. Establecer los permissions de FACL usando para dar acceso a mi count de usuario

     setfacl -md:u::rwx,d:g::---,d:o:---,d:m:rwx cs101.git setfacl -md:u:cs101:rwx,u:cs101:rwx,d:u:welcomb:rwx,u:welcomb:rwx cs101.git 
  3. Entonces, finalmente, inicializa Git

     cd cs101.git git init --bare --shanetworking 

La list del directory muestra

 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 

Permiso para los directorys parece correcto

 # 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:--- 

Todavía usando la count del curso cs101 , cs101 algunos files al repository.

Ahora, cierro la session de la count del curso e inicio de session usando mi propia count de usuario y puedo clonar el repository welcomb@solaris$ git clone ~cs101/cs101.git

Hasta ahora todo bien, todo parece estar bien.

Ahora el problema es que no puedo enviar nuevos commits al repository usando mi propia count de usuario:

 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' 

Parece que no puede ejecutar hooks/update .

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

Pero hooks/update exec bit ni siquiera está configurado, lo que significa que Git debería ignorar su ejecución.

 /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 

Puedo acceder a los files en los directorys e incluso ejecutar update.sample usando mi count

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

Entonces no puedo entender por qué Git Push no actualiza el repository.

El resultado de getfacl incluye las líneas:

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

lo que significa que es probable que la function de access(path, X_OK) biblioteca C access(path, X_OK) afirme que el file se puede ejecutar (ejecutar a través de una llamada al sistema execve o similar), al less para los usuarios cs101 y welcomb . Así es como Git determina si un gancho es ejecutable.

(Tenga en count que cualquier otro usuario que llame tendrá la respuesta: no, este file no es ejecutable . Esto es parte de lo que hace que las ACL sean tan complicadas).

Sin embargo, cuando el sistema operativo realmente intenta ejecutarlo, algo más sale mal. No está del todo claro qué ocurre exactamente, pero la llamada al sistema execve falla con un error de "permiso denegado". Git decide que el gancho falló, en lugar de que el gancho no fuera realmente ejecutable (Git supone que el access dirá no en lugar de en estos casos).

Dado el pequeño tamaño del file (2910 bytes, desde la salida de ls -al update ) parece poco probable que el enlace de update sea ​​otra cosa que un script de shell. Si es un script de shell, ¡necesita un #! correcto #! la línea del intérprete debe ser ejecutable, y esa línea del intérprete debe apuntar a un file que tenga permissions de ejecución.

Si desea que se ejecute el gancho, deberá rastrear el origen de la falla real. Si no desea que se ejecute el gancho, y no quiere que Git piense que se debe ejecutar el gancho, elimine los bits de ejecución de los diversos elementos de la ACL o elimine completamente la ACL (los permissions ACL y "estilo Unix" son suelen ser entidades separadas en el sistema subyacente, aunque ZFS es diferente aquí).