original in en Guido Socher
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
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 (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 |
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.
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.