SUID, Set User-ID, is one of the most beautiful concepts in UNIX. The common definition given for SUID is, it is an advanced file permission which allows an user to execute a script as if the owner of the script is executing it, and the famous example used for SUID is the passwd command.
Let us do a case study right away to understand what exactly is SUID bit and how to use it.
A user 'blogger1' writes a simple script:
#cat test.sh
#!/usr/bin/ksh
dt=`date`
echo $USER $dt >> ~blogger1/log
echo "Updated the log file sucessfully."
The above example shows a simple shell script which writes the username and date-time to a log file and echoes a confirmation statement . On running the script, everything happens as expected for the user 'blogger1' as shown below.
#chmod 755 test.sh
#ls -l test.sh log
-rwxr-xr-x 1 blogger1 blogger1 60 Jun 24 21:44 test.sh
-rw-r--r-- 1 blogger1 blogger1 0 Jun 24 21:44 log
#./test.sh
Updated the log file sucessfully.
#cat log
blogger1 Fri Jun 25 08:01:16 IST 2010
Now, the user 'blogger2' has been told to run this script everyday. Since the script 'test.sh' has executable permission for others, 'blogger2' can execute the script.
The user 'blogger2' logs into his account and does:
#PATH=$PATH:~blogger1
#which test.sh
/home/blogger1/test.sh
#test.sh
test.sh: line 3: /home/blogger1/log: Permission denied
#
The 'blogger2' updated his path to where the script test.sh is present. On trying to run the script, 'blogger2' got an error stating "Permission denied" on the log file. The error occurred because the 'log' file has write permission only for the owner which is 'blogger1'. When 'blogger2' runs the script, effectively it means 'blogger2' is trying to write on the file 'log' on which he has no permission, and hence the error.
At the outset, a solution can be thought of to give the 'write' permission to the user 'blogger2' on the file 'log'. Let's try and see.
The user 'blogger1' gives the write permission on the log file:
#chmod o+w log
#ls -l log
-rw-r--rw- 1 blogger1 blogger1 20 Jun 24 21:44 log
Now, the user 'blogger2' tries to run the script:
#test.sh
Updated the log file sucessfully.
#cat ~blogger1/log
blogger1 Fri Jun 25 08:01:16 IST 2010
blogger2 Fri Jun 25 08:41:16 IST 2010
The script ran successfully. However, the problem is not solved, instead it got bigger. Though the 'write' permission was given on the 'log' file to enable 'blogger2' run the script, effectively it will now enable the 'blogger2' to simply open the 'log' file and start editing as per his wish. This is because 'blogger2' has the 'write' permission and everything is his now.
So, we want a solution wherein 'blogger2' does not get to edit the 'log' file directly, however still can run the script 'test.sh' which updates the 'log' file. This means we would like to have some kind of permission by which the effective user(blogger2) gets the permissions of the real user(blogger1) on running the test.sh script.
This is where SUID comes in. When the SUID(s) bit is set on an executable, whoever runs the executable gets the same permission as the owner of the file. The SUID can be set on a file by adding the 's' bit as shown below:
#chmod o-w log
#chmod u+s test.sh
#ls -l test.sh log
-rwsr-xr-x 1 blogger1 blogger1 60 Jun 24 21:44 test.sh
-rw-r--r-- 1 blogger1 blogger1 20 Jun 24 21:44 log
#
Once the SUID is applied, it means any user who runs the executable will get the permissions of the owner of the file while running it. So, when 'blogger2' tries to run the test.sh, UNIX treats 'blogger2' with the same permission as the owner 'blogger1' has on the 'log' file, and hence 'blogger2' can update the 'log' file successfully through the script.
The 'blogger2' now tries to run the script:
#test.sh
Updated the log file sucessfully.
#cat ~blogger1/log
blogger1 Fri Jun 25 08:01:16 IST 2010
blogger2 Fri Jun 25 08:41:11 IST 2010
blogger2 Fri Jun 25 08:58:14 IST 2010
#
This is how the SUID bit works. The same concept is being used in the passwd command as well. The passwd command can be used by any user to set/change his password. When the passwd command is run, it internally updates the system file /etc/passwd on which only the root user has the 'write' permission. By making the passwd executable SUID enabled, any user can change his password effectively updating /etc/passwd file.
Enjoy with SUID!!!
P.S. SUID is one of the most DANGEROUS features in UNIX. I will explain why so in one of my future articles.