Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
[Photo of the Author]
by Guido Socher

About the author:
Guido loves Linux because it is a free system and it is also a lot of fun to work with people from the Linux community all over the world. He spends his spare time with his girl-friend, listens to BBC World Service radio, rides his bike through the countryside and enjoys playing with Linux.

Content:

File Access Permissions

[Illustration]

Abstract:

This article is divided into two parts:



 

Basic file access permissions

Linux is a multiuser system where users can assign different access permission to their files. Every user has a user-Id, a unique number that identifies her/him. Users belong also to one or more groups. Groups can be used to restrict access to a number of people. A good feature to make team work with a number of people easier. To check your user-Id and see the group(s) to which you belong to just type the command id:

>id
uid=550(alice)  gid=100(users)  groups=100(users),6(disk)

Access permissions can be set per file for owner, group and others on the basis of read (r), write (w) and execute permissions (x). Your can use the command ls -l to see these permissions.

>ls -l   /usr/bin/id
-rwxr-xr-x    1 root   root    8632 May 9 1998 /usr/bin/id

The file /usr/bin/id is owned by user root and belongs to a group called root. The

 -rwxr-xr-x 

shows the file access permissions. This file is readable(r),writable(w) and executable(x) for the owner. For the group and all others it is readable(r) and executable(x).

You can imagine the the permissions as a bit vector with 3 bits each allocated to owner, group and others. Thus r-x corresponds to 101 as a bit pattern or 4+1=5 in decimal. The r-bit corresponds to decimal 4 the w-bit to decimal 2 and the x-bit to decimal 1.

sst
421
(discussed
later)
rwx
421
user
(owner)
rwx
421
group
 
rwx
421
others
 

The command chmod can be use to change these permission. For security reasons only root or the file owner may change the permissions. chmod takes either the decimal representation of the permissions or a symbolic representation. The symbolic representation is [ugoa][+-][rwx]. This is one of the letters u (user=file owner), g (group), o(others), a(all=u and g and o) followed by + or - to add or remove permissions and then the symbolic representation of the permissions in the form of r(read) w(write) x(execute). To make the file "file.txt" writable for all you type:

>chmod a+w   file.txt
or
>chmod 666   file.txt
>ls -l   file.txt
-rw-rw-rw-   1 alice   users   79 Jan 1 16:14 file.txt

chmod 644 file.txt would set the permissions back to "normal" permissions with owner writable+readable and only readable for everyone else.

Changing into a directory (with the command cd) is equivalent to executing the directory. "Normal" permissions for a directory are therefore 755 and not 644:

>chmod 755   mydir
>ls -ld   mydir
drwxr-xr-x    2 alice    users    1024 Dec 31 22:32 mydir

The umask defines your default permissions. The default permissions are applied when new files (and directories, etc ...) are created. As argument it takes those bits in decimal representation that you do NOT want to have set.

umask 022 is e.g a good choice. With 022 everybody can read, your files and "cd" into directories but only you can modify things. To print the current umask settings just type umask without arguments.

Here is an example of how umask and chmod are used:

The umask is set to a good standard value
>umask
22

Take your editor and create a file called myscript:
>nedit   myscript   (or vi myscript ...)
Put the following code into it:

#!/bin/sh
#myscript
echo -n "hello "
whoami
echo "This file ( $0 ) has the following permissions:"
ls -l $0 | cut -f1 -d" "

Save the script.
Now it has 644 permissions:
>ls -l  myscript
-rw-r--r--   1 alice  users  108 Jan 1 myscript

To run it you must make it executable:
>chmod 755 myscript
or
>chmod a+x myscript

Now run it:
>./myscript

Note that a script must be readable and executable in order to run where as a normal compiled binary needs only to be executable. This is because the script must be read be the interpreter (the shell). Running the script should produce:

 
hello alice
This file ( ./myscript ) has the following permissions:
-rwxr-xr-x
 

T-bit, SUID and SGID

After you have worked for a while with Linux you discover probably that there is much more to file permissions than just the "rwx" bits. When you look around in your file system you will see "s" and "t":

>ls -ld /usr/bin/crontab  /usr/bin/passwd  /usr/sbin/sendmail  /tmp

drwxrwxrwt   5 root   root   1024 Jan 1 17:21 /tmp
-rwsr-xr-x   1 root   root   0328 May 6 1998 /usr/bin/crontab
-r-sr-xr-x   1 root   bin     5613 Apr 27 1998 /usr/bin/passwd
-rwsr-sr-x   1 root   mail   89524 Dec 3 22:18 /usr/sbin/sendmail

What is this "s" and "t" bit? The vector of permission bits is really 4 * 3 bits long. chmod 755 is only a shortcut for chmod 0755.

 

The t-bit

The t-bit (sometimes referred to as "sticky bit") is only useful in combination with directories. It is used with the /tmp directory as you can see above.

Normally (without the t-bit set on the directory) files can be deleted if the directory holding the files is writable for the person deleting files. Thus if you have a directory where anybody can deposit files then also anybody can delete the files of everybody else.

The t-bit changes this rule. With the t-bit set only the owner of the file or the owner of the directory can delete the files. The t-bit can be set with chmod a+tw or chmod 1777. Here is an example:

Alice creates a directory with t-bit set:
>mkdir mytmp
chmod 1777 mytmp


now Bob puts a file into it:
>ls -al
drwxrwxrwt   3 alice    users  1024 Jan  1 20:30 ./
-rw-r--r--  1 bob   users     0 Jan  1 20:31 f.txt

This file can now be deleted by Alice (directory owner) and Bob (file owner) but it can not be deleted by Tux:

>whoami
tux
rm -f f.txt
rm: f.txt: Operation not permitted

 

S-bit set on the user

With Linux processes run under a user-ID. This gives them access to all resources (files etc...) that this user would have access to. There are 2 user IDs. The real user-ID and the effective user-ID. The effective user-ID is the one that determines the access to files. Save the following script under the name idinfo and make it executable (chmod 755 idinfo).


#!/bin/sh
#idinfo: Print user information
echo " effective user-ID:"
id -un
echo " real user-ID:"
id -unr
echo " group ID:"
id -gn

When you run the script you will see that the process that runs it gets your user-ID and your group-ID:

 effective user-ID:
alice
 real user-ID:
alice
 group ID:
users

When Tux runs your idinfo program then he gets a similar output that shows the process now running under the ID of tux. The output of the program depends only on the user that runs it and not the one who owns the file.

For security reasons the s-bit works only when used on binaries (compiled code) and not on scripts (an exception are perl scripts). Therefore we create a C-program that will call our idinfo program:

/*suidtest.c*/
#include <stdio.h>
#include <unistd.h>
int main(){
/*secure SUID programs MUST
*not trust any user input or environment variable!! */

char *env[]={"PATH=/bin:/usr/bin",NULL};
char prog[]="/home/alice/idinfo";
if (access(prog,X_OK)){
    fprintf(stderr,"ERROR: %s not executable\n",prog);
    exit(1);
}
printf("running now %s ...\n",prog);
setreuid(geteuid(),geteuid());
execle(prog,(const char*)NULL,env);
perror("suidtest");

return(1);
}

Compile the program with "gcc -o suidtest -Wall suidtest.c" and set the s-bit on the owner:

>chmod 4755   suidtest
or
>chmod u+s   suidtest

Run it! What happens? Nothing ? Run it from a different user!

The file suidtest is owned by alice and has the s-bit set where normally the x is for the owner of the file. This causes the file to be executed under the user-ID of the user that owns the file rather than the user that executes the file. If Tux runs the program then this looks as follows:

>ls -l suidtest
-rwsr-xr-x   1 alice   users   4741 Jan 1 21:53 suidtest
>whoami
tux

running now /home/alice/idinfo ...
effective user-ID:
alice
real user-ID:
alice
group ID:
users

As you can see this is a very powerful feature especially if root owns the file with s-bit set. Any user can then do things that normally only root can do. A few words on security. When you write a SUID program then you must make sure that it can only be used for the purpose that you intended it to be used. Always set the path to a hard-coded value. Never rely on environment variables or functions that use environment variables. Never trust user input (config files, command line arguments....). Check user input byte for byte and compare it with values that you consider valid.

When a SUID program is owned by root then both the effective and the real user-ID can be set (with setreuid() function).

Set-UID programs are often used by "root" to give ordinary users access to things that normally only "root" can do. As root you can e.g modify the suidtest.c to allow any user to run the ppp-on/ppp-off scripts on your machine.

Note: It is possible to switch off Suid when mounting a file system. If the above does not work then check your /etc/fstab. It should look like this:
/dev/hda5 / ext2 defaults 1 1
If you find the option "nosuid" there then this Suid feature is switched off. For details have a look at the man-page of mount.

 

S-bit set on the group

Executable files the that have the s-bit set on the group run under the group-ID of the file owner. This is very similar to s-bit on user in the paragraph above.

When the s-bit is set on the group for a directory then the group is also set for every file that is created in that directory. Alice belong to 2 groups:

>id
uid=550(alice)  gid=100(users)  groups=100(users),6(disk)

Normally files are created for her with the group set to users. But if a directory is created with group set to disk and the s-bit set on the group then all files that alice creates have also the group ID disk:

>chmod 2775 .
>ls -ld .
drwxrwsr-x  3 tux   disk     1024 Jan 1 23:02 .

If alice creates now a new file in this directory then the group of that file will be set to disk

>touch newfile
>ls -l newfile
-rw-r--r--   1 alice    disk      0 Jan 1 23:02 newfile

This is a good feature when you want to work with several people in a team and ensure that the group IDs of the files are set to the right group for the working directory of that team especially in an environment where users normally have a 027 umask that makes files un-accessible for people outside the group.


Webpages maintained by the LinuxFocus Editor team
© FDL, Guido Socher
LinuxFocus.org

Click here to report a fault or send a comment to Linuxfocus

2000-10-31, generated by lfparser version 1.9