What is SetUserId bit and when should it be set?
In unix for every running process, the resources(say a file for example) which it can access is determined by the effective user id and effective group id.
In addition to this there is also a real user id and real group id for every process. The values of the real user id and real group id are the user id and group id of the user who started the process. So what would be the values for effective user id and effective group id??
For normal programs, the effective user/group id's would be the same as real user/group id's. But if the seuid is set for the program, then the effective user/group id of the process would be the user/group id of the program.
Take a look at the below program. When the program is run, it prints the real and effective id's.
/*printID.C
*
*Outputs the real/effective user id and real/effective group id.
*
*/
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char** argv)
{
printf("\nReal UserID:%d", getuid());
printf("\nEffective UserID:%d", geteuid());
printf("\nReal GroupID:%d", getgid());
printf("\nEffective GroupID:%d", getegid());
}
As root user, if the program is run we would get the following ouput.
root@bala-VirtualBox:/home/bala/MyTrials/permissions# whoami
root
root@bala-VirtualBox:/home/bala/MyTrials/permissions# gcc -o printId printID.c
root@bala-VirtualBox:/home/bala/MyTrials/permissions# ./printId
Real UserID:0
Effective UserID:0
Real GroupID:0
Effective GroupID:0
root@bala-VirtualBox:/home/bala/MyTrials/permissions# ls -lrt
total 12
-rw-r--r-- 1 root root 271 2012-05-06 14:47 printID.c
-rwxr-xr-x 1 root root 7317 2012-05-06 14:47 printID
As the setuid bit is not set for printID program, the real and effective id's of the process was same as the user id and group id of the user who started the program, which was 'root' in the above case.
Below is the output when the program was run as user 'bala' (UserId:1000, GroupId:1000).
root@bala-VirtualBox:~/MyTrials/permissions$ sudo -u bala ./printID
Real UserID:1000
Effective UserID:1000
Real GroupID:1000
Effective GroupID:1000
The output is smilar to the one we got when we ran the program as 'root' user. Both the real and effective id's are 1000 which is the user id and group id of the user 'bala'
If the setuid bit and setgid bit is set for printID and it is run as user 'bala', the output would be slightly different.
root@bala-VirtualBox:/home/bala/MyTrials/permissions# chmod u+s printID
root@bala-VirtualBox:/home/bala/MyTrials/permissions# chmod g+s printID
root@bala-VirtualBox:/home/bala/MyTrials/permissions# sudo -u bala ./printID
Real UserID:1000
Effective UserID:0
Real GroupID:1000
Effective GroupID:0
Real user id and real group id would equal the user id and group id of the user(bala) who started the program.
Effective user id and real group id would equal the user id and group id of the owner(root) of the program.
When should SetUserIdBit should be set?
The best way to understand the usage of setuserid bit is to look at the 'passwd' program. It allows users to update their passwords in the '/etc/passwd' file. Take a look at the permission of the 'passwd' file.
root@bala-VirtualBox:/home/bala# ls -l /etc/passwd
-rw-r--r-- 1 root root 1857 2013-06-08 16:45 /etc/passwd
root@bala-VirtualBox:/home/bala# ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 41284 2011-06-24 15:06 /usr/bin/passwd
NOTE: The setuid and setgid bit are applicable only for binary executables. They are normally ignored for shell scripts.