5
votes

I created a setuid program in C. The executable looks like this:

-r-s-r-s--- 1 root users 13073 Jun 15 21:56 server

I execute the program as userA/users and try to set the uid/gid to userB/otherUsers. setgid() fails with Operation not permitted. userA is not part of otherUsers How can I change the effective gid?


[EDIT] Here is a small summary of what I did. My C program, executed as userA, sets uid and gid to userB and creates a file. Not as expected, the file belongs to the group root, because setgid() fails.

[userA@node uid]$ id
uid=11945(userA) gid=544(users) groups=544(users)
[userA@node uid]$ id userB
uid=11946(userB) gid=10792(otherUsers) groups=10792(otherUsers)
[userA@node uid]$ cat uid.c 
#include <stdio.h>
#include <unistd.h>

int main() {
  setuid(11946);
  setgid(10792);

FILE *f = fopen("userB_file", "w");
fclose(f);

return 0;
}
[userA@node uid]$ ls -l uid
-r-sr-sr-x 1 root root 7130 Jun 17 14:16 uid
[userA@node uid]$ ./uid 
[userA@node uid]$ ls -l userB_file 
-rw-r--r-- 1 userB root 0 Jun 17 14:19 userB_file
1
Are you sure setgid() is running with the permissions of a user in the users group? That would cause it to fail with "Operation not permitted" because the read and exec/setuid privs don't extend to world/other. - user1452106
I don't get that. Do I have to run my program as root? I thought setting the owner to root would be enough to change uid/gid. I won't be able to run the program as root. - multiholle
Unix permissions are owner / group / {world,other}. You have read and exec+setuid for owner (root) and group (users). You don't have your code posted, but if whatever is calling setgid() isn't either root or in the group users, that would give the error you're reporting. - user1452106
I'm just calling setuid() and setgid() with the id's for userB/otherUsers. The program itself is executed by userA. Should I add some example code? - multiholle

1 Answers

20
votes

I suspect you're calling setuid before setgid. As soon as you call setuid to change the uid to something other than root, you've forfeited your permission to change the gid to an arbitrary value. You must call setgid first, then setuid.