5

I have a git repository that needs to run a post-receive hook as sudo. The binary that I compiled to test this looks like:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main() {
   int ret;
   ret = setuid(geteuid());
   if(!ret) {
      fprintf(stderr, "error setting uid %d \n", ret);
   }       
   system("[...command only sudo can access...]");

   return 0;
}

The geteuid() retrieves the owner id of post-receive, then tries to setuid. When running this with any user(including the super user) it runs the script correctly as root. However, when triggered by the git hook the systems fail to set the uid. I have tried running chmod u+s post-receive I also tried some other configurations, but I am running out of ideas. Any reason why it would work in all cases except when git triggers it?

btw, platform Ubuntu Server 9.04(2.6.28-15), git1.6.0.4, gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

Blake Chambers
  • 505
  • 1
  • 5
  • 14
  • One issue is that you print an error message but then continue to execute the system() call. You also ignore the result of the system() call and then exit with a success (0) status. – Jonathan Leffler Feb 06 '10 at 04:18
  • @Blake: The "-as the- with any user" bit is unclear - does the program run correctly when run as the user you're pushing as? I think the closest way to duplicate the environment it's run in by git would be: `ssh hostname 'cd /path/to/repo; .git/hooks/post-receive'` – Cascabel Apr 03 '10 at 16:53
  • Why not let the users run the command directly with sudo (configure it with visudo, specify 'NOPASSWD:')? Writing your own suid-root wrapper is risky. – Marius Gedminas Jul 14 '10 at 20:54
  • I think you have a setup problem if you want a hook to run with elevated privileges. You'd best reconsider the file ownerships and permissions. – Noufal Ibrahim Aug 29 '10 at 07:42

4 Answers4

1
  1. The file system where the git repo is stored may be mounted with the nosuid option
  2. If you are pushing over ssh the suid capability may be disabled for commands invoked with ssh (no CAP_SETUID)

In any case, what you are trying to do is very inadvisable.

Neil Mayhew
  • 14,206
  • 3
  • 33
  • 25
1
  1. Run your program as a daemon.
  2. Wait for input on a socket/named pipe/msgq.
  3. In the hook, send a message to your daemon with whatever info it needs to perform the operation.
  4. If needed, send a message back to the hook with status.

This will likely be easier to manage and secure properly.

bstpierre
  • 30,042
  • 15
  • 70
  • 103
0

try running your program from the command prompt

yan bellavance
  • 4,710
  • 20
  • 62
  • 93
0

Try writing a bootstrap script. ie

#/usr/bin/sh
./your_program

Then make make the script the hook.

dan_waterworth
  • 6,261
  • 1
  • 30
  • 41