Monday, June 28, 2010

what is SUID?



  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.

13 comments:

  1. In RHEL, suid is restricted to binary files and cannot be implemented on script files.

    sunil datta
    www.opensourcenuts.com

    ReplyDelete
  2. Thanks for the article.

    Rick

    ReplyDelete
  3. Yes sunil, you are right..thanks for sharing the information.

    ReplyDelete
  4. Guru : you didnt explain how does passwd command works ? I came to this article from here - http://www.unix.com/red-hat/139992-how-passwd-cmd-working.html

    ReplyDelete
    Replies
    1. passwd command works in exactly the same way how the example given above works.

      Delete
  5. Thanks! it was very helpful for me to understand about how "passwd" works on linux. But I have a question. After I remove the 'writing' authority of 'root' on file /etc/passwd, I can still be able to change root password by using 'passwd' cmd. Do you have any idea why the "passwd" command is still working?..

    ReplyDelete
  6. root being the superuser gets to break the rules. Being a root, try to edit a file which has no write permission, you will be able to save it using :w!. The same is the case with the passwd command as well.

    ReplyDelete
  7. what about sgid? how does tht work...

    ReplyDelete
  8. Imagine if the root does not have writing authority on the passwd file and if a script with SUID is ran by a normal user. Will this still work?

    ReplyDelete
    Replies
    1. It still works. Root is superuser who can break all rules. You try to write to a file on which root does not have permission using an editor. It works. Similarly, when the exe with SUID is run by the normal user, it still works because root has all permissions on any file in the system.

      Delete
  9. Hey this is great very neat explanation....

    ReplyDelete