setuid confusion

alex at crackpot.org alex at crackpot.org
Thu Nov 1 13:24:27 MST 2007


On re-reading, this question has gotten rather long.  I was trying to  
include all the information that might be relevant.  Sorry if I've  
included a bunch of stuff that isn't...

I'm setting up a website development environment for a group of  
developers.  We want a 'dev' area where everyone can work on things,  
and a 'live' area which is the Apache document root.  We want to  
ensure that any changes to the live site go through version control,  
for accountability, etc.  No one should be able to edit the live site  
directly, only the dev site.

Here's what I've set up:

  - /www/dev and /www/live are both working copies of the same SVN repository.
  - /www/dev is owned by me, and a group called wwwdev.  The directory  
and all files in it are group-writeable, so anyone in the wwwdev group  
can make changes and commit them.
  - /www/live is owned by a user wwwlive (also group wwwlive).  No one  
else is in this group, only this user.  Thus no other users can edit  
the files in this directory directly.
  - I've written a very simple C program that runs an 'svn update'  
command for the /www/live directory.  The binary version, called  
'live_svn_update' is owned by wwwlive, and is setuid and setgid.   
(chmod ug+s).  So, anyone can run this program to bring the /www/live  
tree up to the latest of what's in the repository (checked in from  
/www/dev), even though they can't edit anything in /www/live directly.

The problem is that while this works great on my workstation (where I  
first tried it out), I can't get it working correctly on the server  
where we'll actually do the development.  I'm really confused about  
why.  Debugging code I've added to the program shows that the  
effective UID and GID are being changed to wwwlive, but the 'svn  
update' command fails due to a permissions error.  Running the program  
while logged in as wwwlive works perfectly.

My workstation is Ubuntu, while the server is RHEL, but I can't find  
anything which would say that matters.

[alexd]$ pwd
/www
[alexd]$ ls -l
total 32
drwxrwxr-x  4 alexd   wwwdev          4096 Nov  1 10:13 dev
drwxr-xr-x  4 wwwlive wwwlive         4096 Nov  1 12:50 live
-rwsr-sr-x  1 wwwlive wwwlive         7660 Nov  1 12:44 live_svn_update
-rw-r--r--  1 wwwlive wwwlive          383 Nov  1 12:44 live_svn_update.c

[alexd]$ more live_svn_update.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
     printf("Real UID\t= %d\n", getuid());
     printf("Effective UID\t= %d\n", geteuid());
     printf("Real GID\t= %d\n", getgid());
     printf("Effective GID\t= %d\n", getegid());

     system( "/usr/local/bin/svn update /live_www/azc2008redesign/live/" );
     return EXIT_SUCCESS;
}

Compiled with : gcc -Wall live_svn_update.c -o live_svn_update

[alexd]$ egrep 'alexd|wwwlive' /etc/passwd
alexd:x:110115:20014:Alex Dean:/home/alexd:/bin/bash
wwwlive:x:100313:20023:Live WWW Owner:/home/livewww:/bin/bash

[alexd]$ egrep 'alexd|wwwlive' /etc/group
alexd:x:20014:alexd
wwwlive:x:20023:

When I log in as wwwlive and run the update, it's fine.
[wwwlive]$ ./live_svn_update
Real UID        = 100313
Effective UID   = 100313
Real GID        = 20023
Effective GID   = 20023
At revision 3.

When I run it as myself, you can see that the UID and GID are changing  
to those of wwwlive, but that doesn't need to give me the permissions  
I need to perform the update.
[alexd]$ ./live_svn_update
Real UID        = 110115
Effective UID   = 100313
Real GID        = 20014
Effective GID   = 20023
svn: Can't open file '/www/live/.svn/lock': Permission denied

So... I'm kinda stumped at the moment.  Anyone see anything I've  
missed, or something else I ought to try?

thanks,
alex


More information about the PLUG-discuss mailing list